jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java
author serb
Fri, 14 Oct 2016 21:43:00 +0300
changeset 41790 88b6889f7c39
parent 40444 afabcfc2f3ef
child 43319 66a889959081
permissions -rw-r--r--
8167435: IllegalArgumentException is not thrown by Clip.open(AudioFormat,byte[], int, int) Reviewed-by: amenkov
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
41790
88b6889f7c39 8167435: IllegalArgumentException is not thrown by Clip.open(AudioFormat,byte[], int, int)
serb
parents: 40444
diff changeset
     2
 * Copyright (c) 2002, 2016, 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: 1846
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: 1846
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: 1846
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1846
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1846
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
package com.sun.media.sound;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.ByteArrayOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.Vector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    32
import javax.sound.sampled.AudioFormat;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    33
import javax.sound.sampled.AudioInputStream;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    34
import javax.sound.sampled.AudioSystem;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    35
import javax.sound.sampled.BooleanControl;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    36
import javax.sound.sampled.Clip;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    37
import javax.sound.sampled.Control;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    38
import javax.sound.sampled.DataLine;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    39
import javax.sound.sampled.FloatControl;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    40
import javax.sound.sampled.Line;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    41
import javax.sound.sampled.LineUnavailableException;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    42
import javax.sound.sampled.SourceDataLine;
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    43
import javax.sound.sampled.TargetDataLine;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
// IDEA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
// Use java.util.concurrent.Semaphore,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
// java.util.concurrent.locks.ReentrantLock and other new classes/methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
// to improve this class's thread safety.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
/**
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
    51
 * A Mixer which provides direct access to audio devices.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * @author Florian Bomers
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 */
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
    55
final class DirectAudioDevice extends AbstractMixer {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private static final int CLIP_BUFFER_TIME = 1000; // in milliseconds
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    private static final int DEFAULT_LINE_BUFFER_TIME = 500; // in milliseconds
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    DirectAudioDevice(DirectAudioDeviceProvider.DirectAudioDeviceInfo portMixerInfo) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        // pass in Line.Info, mixer, controls
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
        super(portMixerInfo,              // Mixer.Info
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
              null,                       // Control[]
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
              null,                       // Line.Info[] sourceLineInfo
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
              null);                      // Line.Info[] targetLineInfo
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        if (Printer.trace) Printer.trace(">> DirectAudioDevice: constructor");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        // source lines
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        DirectDLI srcLineInfo = createDataLineInfo(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        if (srcLineInfo != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            sourceLineInfo = new Line.Info[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            // SourcedataLine
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            sourceLineInfo[0] = srcLineInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
            // Clip
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
            sourceLineInfo[1] = new DirectDLI(Clip.class, srcLineInfo.getFormats(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
                                              srcLineInfo.getHardwareFormats(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
                                              32, // arbitrary minimum buffer size
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
                                              AudioSystem.NOT_SPECIFIED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
            sourceLineInfo = new Line.Info[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        // TargetDataLine
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        DataLine.Info dstLineInfo = createDataLineInfo(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        if (dstLineInfo != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
            targetLineInfo = new Line.Info[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
            targetLineInfo[0] = dstLineInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
            targetLineInfo = new Line.Info[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        if (Printer.trace) Printer.trace("<< DirectAudioDevice: constructor completed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    private DirectDLI createDataLineInfo(boolean isSource) {
24548
9c007a986347 8042256: Fix raw and unchecked lint warnings in com.sun.media.sound
darcy
parents: 22584
diff changeset
    97
        Vector<AudioFormat> formats = new Vector<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        AudioFormat[] hardwareFormatArray = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        AudioFormat[] formatArray = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        synchronized(formats) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
            nGetFormats(getMixerIndex(), getDeviceID(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                        isSource /* true:SourceDataLine/Clip, false:TargetDataLine */,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                        formats);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
            if (formats.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                int size = formats.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                int formatArraySize = size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                hardwareFormatArray = new AudioFormat[size];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                for (int i = 0; i < size; i++) {
24548
9c007a986347 8042256: Fix raw and unchecked lint warnings in com.sun.media.sound
darcy
parents: 22584
diff changeset
   110
                    AudioFormat format = formats.elementAt(i);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                    hardwareFormatArray[i] = format;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                    int bits = format.getSampleSizeInBits();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                    boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                    boolean isUnsigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                    if ((isSigned || isUnsigned)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                        // will insert a magically converted format here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                        formatArraySize++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                formatArray = new AudioFormat[formatArraySize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
                int formatArrayIndex = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                for (int i = 0; i < size; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
                    AudioFormat format = hardwareFormatArray[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                    formatArray[formatArrayIndex++] = format;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                    int bits = format.getSampleSizeInBits();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                    boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                    boolean isUnsigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                    // add convenience formats (automatic conversion)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                    if (bits == 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                        // add the other signed'ness for 8-bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                        if (isSigned) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                            formatArray[formatArrayIndex++] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                                new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                                    format.getSampleRate(), bits, format.getChannels(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                                    format.getFrameSize(), format.getSampleRate(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                                    format.isBigEndian());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                        else if (isUnsigned) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                            formatArray[formatArrayIndex++] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                                new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                                    format.getSampleRate(), bits, format.getChannels(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                                    format.getFrameSize(), format.getSampleRate(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                                    format.isBigEndian());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
                    } else if (bits > 8 && (isSigned || isUnsigned)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                        // add the other endian'ness for more than 8-bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                        formatArray[formatArrayIndex++] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                            new AudioFormat(format.getEncoding(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                                              format.getSampleRate(), bits,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                                              format.getChannels(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                                              format.getFrameSize(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                                              format.getSampleRate(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                                              !format.isBigEndian());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                    //System.out.println("Adding "+v.get(v.size()-1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        // todo: find out more about the buffer size ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        if (formatArray != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            return new DirectDLI(isSource?SourceDataLine.class:TargetDataLine.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                                 formatArray, hardwareFormatArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                                 32, // arbitrary minimum buffer size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                                 AudioSystem.NOT_SPECIFIED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    // ABSTRACT MIXER: ABSTRACT METHOD IMPLEMENTATIONS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   171
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    public Line getLine(Line.Info info) throws LineUnavailableException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        Line.Info fullInfo = getLineInfo(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        if (fullInfo == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            throw new IllegalArgumentException("Line unsupported: " + info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        if (fullInfo instanceof DataLine.Info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            DataLine.Info dataLineInfo = (DataLine.Info)fullInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            AudioFormat lineFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            int lineBufferSize = AudioSystem.NOT_SPECIFIED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            // if a format is specified by the info class passed in, use it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            // otherwise use a format from fullInfo.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            AudioFormat[] supportedFormats = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            if (info instanceof DataLine.Info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                supportedFormats = ((DataLine.Info)info).getFormats();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                lineBufferSize = ((DataLine.Info)info).getMaxBufferSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            if ((supportedFormats == null) || (supportedFormats.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                // use the default format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                lineFormat = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                // use the last format specified in the line.info object passed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                // in by the app
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                lineFormat = supportedFormats[supportedFormats.length-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                // if something is not specified, use default format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                if (!Toolkit.isFullySpecifiedPCMFormat(lineFormat)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                    lineFormat = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            if (dataLineInfo.getLineClass().isAssignableFrom(DirectSDL.class)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                return new DirectSDL(dataLineInfo, lineFormat, lineBufferSize, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            if (dataLineInfo.getLineClass().isAssignableFrom(DirectClip.class)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                return new DirectClip(dataLineInfo, lineFormat, lineBufferSize, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            if (dataLineInfo.getLineClass().isAssignableFrom(DirectTDL.class)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                return new DirectTDL(dataLineInfo, lineFormat, lineBufferSize, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        throw new IllegalArgumentException("Line unsupported: " + info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   220
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    public int getMaxLines(Line.Info info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        Line.Info fullInfo = getLineInfo(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        // if it's not supported at all, return 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        if (fullInfo == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        if (fullInfo instanceof DataLine.Info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            // DirectAudioDevices should mix !
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            return getMaxSimulLines();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   237
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    protected void implOpen() throws LineUnavailableException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        if (Printer.trace) Printer.trace("DirectAudioDevice: implOpen - void method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   242
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    protected void implClose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        if (Printer.trace) Printer.trace("DirectAudioDevice: implClose - void method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   247
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    protected void implStart() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        if (Printer.trace) Printer.trace("DirectAudioDevice: implStart - void method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   252
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    protected void implStop() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        if (Printer.trace) Printer.trace("DirectAudioDevice: implStop - void method");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    int getMixerIndex() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        return ((DirectAudioDeviceProvider.DirectAudioDeviceInfo) getMixerInfo()).getIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    int getDeviceID() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        return ((DirectAudioDeviceProvider.DirectAudioDeviceInfo) getMixerInfo()).getDeviceID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    int getMaxSimulLines() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        return ((DirectAudioDeviceProvider.DirectAudioDeviceInfo) getMixerInfo()).getMaxSimulLines();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
24548
9c007a986347 8042256: Fix raw and unchecked lint warnings in com.sun.media.sound
darcy
parents: 22584
diff changeset
   269
    private static void addFormat(Vector<AudioFormat> v, int bits, int frameSizeInBytes, int channels, float sampleRate,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                                  int encoding, boolean signed, boolean bigEndian) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        AudioFormat.Encoding enc = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        switch (encoding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        case PCM:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            enc = signed?AudioFormat.Encoding.PCM_SIGNED:AudioFormat.Encoding.PCM_UNSIGNED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        case ULAW:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            enc = AudioFormat.Encoding.ULAW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            if (bits != 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                if (Printer.err) Printer.err("DirectAudioDevice.addFormat called with ULAW, but bitsPerSample="+bits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                bits = 8; frameSizeInBytes = channels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        case ALAW:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            enc = AudioFormat.Encoding.ALAW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            if (bits != 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                if (Printer.err) Printer.err("DirectAudioDevice.addFormat called with ALAW, but bitsPerSample="+bits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                bits = 8; frameSizeInBytes = channels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        if (enc==null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            if (Printer.err) Printer.err("DirectAudioDevice.addFormat called with unknown encoding: "+encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        if (frameSizeInBytes <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            if (channels > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                frameSizeInBytes = ((bits + 7) / 8) * channels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                frameSizeInBytes = AudioSystem.NOT_SPECIFIED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        v.add(new AudioFormat(enc, sampleRate, bits, channels, frameSizeInBytes, sampleRate, bigEndian));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    protected static AudioFormat getSignOrEndianChangedFormat(AudioFormat format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        boolean isSigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        boolean isUnsigned = format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        if (format.getSampleSizeInBits() > 8 && isSigned) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            // if this is PCM_SIGNED and 16-bit or higher, then try with endian-ness magic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            return new AudioFormat(format.getEncoding(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                                   format.getSampleRate(), format.getSampleSizeInBits(), format.getChannels(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                                   format.getFrameSize(), format.getFrameRate(), !format.isBigEndian());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        else if (format.getSampleSizeInBits() == 8 && (isSigned || isUnsigned)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            // if this is PCM and 8-bit, then try with signed-ness magic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            return new AudioFormat(isSigned?AudioFormat.Encoding.PCM_UNSIGNED:AudioFormat.Encoding.PCM_SIGNED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                                   format.getSampleRate(), format.getSampleSizeInBits(), format.getChannels(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                                   format.getFrameSize(), format.getFrameRate(), format.isBigEndian());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * Private inner class for the DataLine.Info objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * adds a little magic for the isFormatSupported so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * that the automagic conversion of endianness and sign
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * does not show up in the formats array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * I.e. the formats array contains only the formats
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * that are really supported by the hardware,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * but isFormatSupported() also returns true
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * for formats with wrong endianness.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     */
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   333
    private static final class DirectDLI extends DataLine.Info {
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   334
        final AudioFormat[] hardwareFormats;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
24548
9c007a986347 8042256: Fix raw and unchecked lint warnings in com.sun.media.sound
darcy
parents: 22584
diff changeset
   336
        private DirectDLI(Class<?> clazz, AudioFormat[] formatArray,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                          AudioFormat[] hardwareFormatArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                          int minBuffer, int maxBuffer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            super(clazz, formatArray, minBuffer, maxBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            this.hardwareFormats = hardwareFormatArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        public boolean isFormatSupportedInHardware(AudioFormat format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            if (format == null) return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            for (int i = 0; i < hardwareFormats.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                if (format.matches(hardwareFormats[i])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                    return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        /*public boolean isFormatSupported(AudioFormat format) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
         *   return isFormatSupportedInHardware(format)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
         *      || isFormatSupportedInHardware(getSignOrEndianChangedFormat(format));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
         *}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
         private AudioFormat[] getHardwareFormats() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
             return hardwareFormats;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    /**
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   365
     * Private inner class as base class for direct lines.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    private static class DirectDL extends AbstractDataLine implements EventDispatcher.LineMonitor {
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   368
        protected final int mixerIndex;
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   369
        protected final int deviceID;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        protected long id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        protected int waitTime;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        protected volatile boolean flushing = false;
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   373
        protected final boolean isSource;         // true for SourceDataLine, false for TargetDataLine
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        protected volatile long bytePosition;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        protected volatile boolean doIO = false;     // true in between start() and stop() calls
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 18215
diff changeset
   376
        protected volatile boolean stoppedWritten = false; // true if a write occurred in stopped state
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        protected volatile boolean drained = false; // set to true when drain function returns, set to false in write()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        protected boolean monitoring = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        // if native needs to manually swap samples/convert sign, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        // is set to the framesize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        protected int softwareConversionSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        protected AudioFormat hardwareFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   385
        private final Gain gainControl = new Gain();
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   386
        private final Mute muteControl = new Mute();
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   387
        private final Balance balanceControl = new Balance();
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   388
        private final Pan panControl = new Pan();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        private float leftGain, rightGain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        protected volatile boolean noService = false; // do not run the nService method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
1846
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   392
        // Guards all native calls.
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   393
        protected final Object lockNative = new Object();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        protected DirectDL(DataLine.Info info,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                           DirectAudioDevice mixer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                           AudioFormat format,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                           int bufferSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                           int mixerIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                           int deviceID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                           boolean isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            super(info, mixer, null, format, bufferSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            if (Printer.trace) Printer.trace("DirectDL CONSTRUCTOR: info: " + info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            this.mixerIndex = mixerIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            this.deviceID = deviceID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            this.waitTime = 10; // 10 milliseconds default wait time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            this.isSource = isSource;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   411
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        void implOpen(AudioFormat format, int bufferSize) throws LineUnavailableException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            if (Printer.trace) Printer.trace(">> DirectDL: implOpen("+format+", "+bufferSize+" bytes)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            // $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            Toolkit.isFullySpecifiedAudioFormat(format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            // check for record permission
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            if (!isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                JSSecurityManager.checkRecordPermission();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            int encoding = PCM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            if (format.getEncoding().equals(AudioFormat.Encoding.ULAW)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                encoding = ULAW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            else if (format.getEncoding().equals(AudioFormat.Encoding.ALAW)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                encoding = ALAW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            if (bufferSize <= AudioSystem.NOT_SPECIFIED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                bufferSize = (int) Toolkit.millis2bytes(format, DEFAULT_LINE_BUFFER_TIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            DirectDLI ddli = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            if (info instanceof DirectDLI) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                ddli = (DirectDLI) info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            /* set up controls */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                if (!format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                    && !format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                    // no controls for non-PCM formats */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                    controls = new Control[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                else if (format.getChannels() > 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                         || format.getSampleSizeInBits() > 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                    // no support for more than 2 channels or more than 16 bits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                    controls = new Control[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                    if (format.getChannels() == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                        controls = new Control[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                        controls = new Control[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                        controls[2] = balanceControl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                        /* to keep compatibility with apps that rely on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                         * MixerSourceLine's PanControl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                        controls[3] = panControl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                    controls[0] = gainControl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                    controls[1] = muteControl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            if (Printer.debug) Printer.debug("DirectAudioDevice: got "+controls.length+" controls.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
            hardwareFormat = format;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            /* some magic to account for not-supported endianness or signed-ness */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            softwareConversionSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            if (ddli != null && !ddli.isFormatSupportedInHardware(format)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                AudioFormat newFormat = getSignOrEndianChangedFormat(format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                if (ddli.isFormatSupportedInHardware(newFormat)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                    // apparently, the new format can be used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                    hardwareFormat = newFormat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                    // So do endian/sign conversion in software
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                    softwareConversionSize = format.getFrameSize() / format.getChannels();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                    if (Printer.debug) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                        Printer.debug("DirectAudioDevice: softwareConversionSize "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                                      +softwareConversionSize+":");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                        Printer.debug("  from "+format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                        Printer.debug("  to   "+newFormat);
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
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            // align buffer to full frames
22584
eed64ee05369 8032733: Fix cast lint warnings in client libraries
darcy
parents: 21278
diff changeset
   488
            bufferSize = ( bufferSize / format.getFrameSize()) * format.getFrameSize();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   490
            id = nOpen(mixerIndex, deviceID, isSource,
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   491
                    encoding,
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   492
                    hardwareFormat.getSampleRate(),
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   493
                    hardwareFormat.getSampleSizeInBits(),
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   494
                    hardwareFormat.getFrameSize(),
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   495
                    hardwareFormat.getChannels(),
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   496
                    hardwareFormat.getEncoding().equals(
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   497
                        AudioFormat.Encoding.PCM_SIGNED),
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   498
                    hardwareFormat.isBigEndian(),
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   499
                    bufferSize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   501
            if (id == 0) {
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   502
                // TODO: nicer error messages...
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   503
                throw new LineUnavailableException(
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   504
                        "line with format "+format+" not supported.");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            }
1846
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   506
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            this.bufferSize = nGetBufferSize(id, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            if (this.bufferSize < 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                // this is an error!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                this.bufferSize = bufferSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            this.format = format;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            // wait time = 1/4 of buffer time
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            waitTime = (int) Toolkit.bytes2millis(format, this.bufferSize) / 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            if (waitTime < 10) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                waitTime = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            else if (waitTime > 1000) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                // we have seen large buffer sizes!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                // never wait for more than a second
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                waitTime = 1000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            bytePosition = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            stoppedWritten = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            doIO = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            calcVolume();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            if (Printer.trace) Printer.trace("<< DirectDL: implOpen() succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   531
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        void implStart() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            if (Printer.trace) Printer.trace(" >> DirectDL: implStart()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            // check for record permission
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            if (!isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                JSSecurityManager.checkRecordPermission();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            synchronized (lockNative)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                nStart(id, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            // check for monitoring/servicing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            monitoring = requiresServicing();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            if (monitoring) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                getEventDispatcher().addLineMonitor(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            doIO = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            // need to set Active and Started
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            // note: the current API always requires that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            //       Started and Active are set at the same time...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            if (isSource && stoppedWritten) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                setStarted(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                setActive(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            if (Printer.trace) Printer.trace("<< DirectDL: implStart() succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   563
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        void implStop() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            if (Printer.trace) Printer.trace(">> DirectDL: implStop()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            // check for record permission
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
            if (!isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                JSSecurityManager.checkRecordPermission();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            if (monitoring) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                getEventDispatcher().removeLineMonitor(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                monitoring = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            synchronized (lockNative) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                nStop(id, isSource);
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   578
            }
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   579
            // wake up any waiting threads
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   580
            synchronized(lock) {
1846
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   581
                // need to set doIO to false before notifying the
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   582
                // read/write thread, that's why isStartedRunning()
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   583
                // cannot be used
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   584
                doIO = false;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                lock.notifyAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            setActive(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            setStarted(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            stoppedWritten = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            if (Printer.trace) Printer.trace(" << DirectDL: implStop() succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   594
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        void implClose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
            if (Printer.trace) Printer.trace(">> DirectDL: implClose()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            // check for record permission
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            if (!isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                JSSecurityManager.checkRecordPermission();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
            // be sure to remove this monitor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            if (monitoring) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                getEventDispatcher().removeLineMonitor(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                monitoring = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
            doIO = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            long oldID = id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            id = 0;
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   612
            synchronized (lockNative) {
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   613
                nClose(oldID, isSource);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            bytePosition = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            softwareConversionSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
            if (Printer.trace) Printer.trace("<< DirectDL: implClose() succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   620
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        public int available() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
            if (id == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            }
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   625
            int a;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            synchronized (lockNative) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   627
                a = nAvailable(id, isSource);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
            return a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   632
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        public void drain() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
            noService = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            // additional safeguard against draining forever
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 18215
diff changeset
   636
            // this occurred on Solaris 8 x86, probably due to a bug
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            // in the audio driver
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
            int counter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            long startPos = getLongFramePosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            boolean posChanged = false;
1846
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   641
            while (!drained) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                synchronized (lockNative) {
1846
4a53d636e2f4 6702956: OpenJDK: replace encumbered code (software synthesizer)
amenkov
parents: 2
diff changeset
   643
                    if ((id == 0) || (!doIO) || !nIsStillDraining(id, isSource))
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                // check every now and then for a new position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                if ((counter % 5) == 4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                    long thisFramePos = getLongFramePosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                    posChanged = posChanged | (thisFramePos != startPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                    if ((counter % 50) > 45) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                        // when some time elapsed, check that the frame position
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                        // really changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                        if (!posChanged) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                            if (Printer.err) Printer.err("Native reports isDraining, but frame position does not increase!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
                        posChanged = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                        startPos = thisFramePos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                counter++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                synchronized(lock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                        lock.wait(10);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                    } catch (InterruptedException ie) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            if (doIO && id != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                drained = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            noService = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   675
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        public void flush() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            if (id != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                // first stop ongoing read/write method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                flushing = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
                synchronized(lock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                    lock.notifyAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                synchronized (lockNative) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   684
                    if (id != 0) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
                        // then flush native buffers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                        nFlush(id, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                drained = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        // replacement for getFramePosition (see AbstractDataLine)
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   694
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
        public long getLongFramePosition() {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   696
            long pos;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            synchronized (lockNative) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   698
                pos = nGetBytePosition(id, isSource, bytePosition);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            // hack because ALSA sometimes reports wrong framepos
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            if (pos < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                if (Printer.debug) Printer.debug("DirectLine.getLongFramePosition: Native reported pos="
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                                                 +pos+"! is changed to 0. byteposition="+bytePosition);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
                pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            return (pos / getFormat().getFrameSize());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
         * write() belongs into SourceDataLine and Clip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
         * so define it here and make it accessible by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
         * declaring the respective interfaces with DirectSDL and DirectClip
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        public int write(byte[] b, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
            flushing = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            if (len == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            if (len < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                throw new IllegalArgumentException("illegal len: "+len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            if (len % getFormat().getFrameSize() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                throw new IllegalArgumentException("illegal request to write "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                                                   +"non-integral number of frames ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                                                   +len+" bytes, "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                                                   +"frameSize = "+getFormat().getFrameSize()+" bytes)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
            if (off < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
                throw new ArrayIndexOutOfBoundsException(off);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            }
11893
6a3b541908ae 7088367: JavaSound security issue (12865443)
amenkov
parents: 9035
diff changeset
   731
            if ((long)off + (long)len > (long)b.length) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
                throw new ArrayIndexOutOfBoundsException(b.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            if (!isActive() && doIO) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                // this is not exactly correct... would be nicer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                // if the native sub system sent a callback when IO really starts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                setActive(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                setStarted(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            int written = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            while (!flushing) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   743
                int thisWritten;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                synchronized (lockNative) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   745
                    thisWritten = nWrite(id, b, off, len,
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   746
                            softwareConversionSize,
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   747
                            leftGain, rightGain);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                    if (thisWritten < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                        // error in native layer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
                    bytePosition += thisWritten;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                    if (thisWritten > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                        drained = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                len -= thisWritten;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                written += thisWritten;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                if (doIO && len > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                    off += thisWritten;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    synchronized (lock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                            lock.wait(waitTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                        } catch (InterruptedException ie) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
            if (written > 0 && !doIO) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                stoppedWritten = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            return written;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        protected boolean requiresServicing() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            return nRequiresServicing(id, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        // called from event dispatcher for lines that need servicing
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   781
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        public void checkLine() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            synchronized (lockNative) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                if (monitoring
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                        && doIO
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                        && id != 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                        && !flushing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                        && !noService) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                    nService(id, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        private void calcVolume() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
            if (getFormat() == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
            if (muteControl.getValue()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                leftGain = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                rightGain = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
            float gain = gainControl.getLinearGain();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
            if (getFormat().getChannels() == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                // trivial case: only use gain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                leftGain = gain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                rightGain = gain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                // need to combine gain and balance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                float bal = balanceControl.getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                if (bal < 0.0f) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                    // left
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                    leftGain = gain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                    rightGain = gain * (bal + 1.0f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                    leftGain = gain * (1.0f - bal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                    rightGain = gain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        /////////////////// CONTROLS /////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   824
        protected final class Gain extends FloatControl {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
            private float linearGain = 1.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
            private Gain() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
                super(FloatControl.Type.MASTER_GAIN,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
                      Toolkit.linearToDB(0.0f),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                      Toolkit.linearToDB(2.0f),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                      Math.abs(Toolkit.linearToDB(1.0f)-Toolkit.linearToDB(0.0f))/128.0f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                      -1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                      0.0f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                      "dB", "Minimum", "", "Maximum");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   839
            @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
            public void setValue(float newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                // adjust value within range ?? spec says IllegalArgumentException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                //newValue = Math.min(newValue, getMaximum());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                //newValue = Math.max(newValue, getMinimum());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                float newLinearGain = Toolkit.dBToLinear(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                super.setValue(Toolkit.linearToDB(newLinearGain));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                // if no exception, commit to our new gain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                linearGain = newLinearGain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                calcVolume();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            float getLinearGain() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                return linearGain;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        } // class Gain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   857
        private final class Mute extends BooleanControl {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
            private Mute() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                super(BooleanControl.Type.MUTE, false, "True", "False");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   863
            @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
            public void setValue(boolean newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                super.setValue(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                calcVolume();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
        }  // class Mute
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   870
        private final class Balance extends FloatControl {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
            private Balance() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                super(FloatControl.Type.BALANCE, -1.0f, 1.0f, (1.0f / 128.0f), -1, 0.0f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                      "", "Left", "Center", "Right");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   877
            @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
            public void setValue(float newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                setValueImpl(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                panControl.setValueImpl(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                calcVolume();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
            void setValueImpl(float newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                super.setValue(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
        } // class Balance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   890
        private final class Pan extends FloatControl {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            private Pan() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                super(FloatControl.Type.PAN, -1.0f, 1.0f, (1.0f / 128.0f), -1, 0.0f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
                      "", "Left", "Center", "Right");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   897
            @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
            public void setValue(float newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
                setValueImpl(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
                balanceControl.setValueImpl(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
                calcVolume();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            void setValueImpl(float newValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
                super.setValue(newValue);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        } // class Pan
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    } // class DirectDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
    /**
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   910
     * Private inner class representing a SourceDataLine.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
     */
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   912
    private static final class DirectSDL extends DirectDL
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   913
            implements SourceDataLine {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
        private DirectSDL(DataLine.Info info,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                          AudioFormat format,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                          int bufferSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
                          DirectAudioDevice mixer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
            super(info, mixer, format, bufferSize, mixer.getMixerIndex(), mixer.getDeviceID(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
            if (Printer.trace) Printer.trace("DirectSDL CONSTRUCTOR: completed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    /**
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   926
     * Private inner class representing a TargetDataLine.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
     */
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   928
    private static final class DirectTDL extends DirectDL
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
   929
            implements TargetDataLine {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
        private DirectTDL(DataLine.Info info,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
                          AudioFormat format,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
                          int bufferSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
                          DirectAudioDevice mixer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
            super(info, mixer, format, bufferSize, mixer.getMixerIndex(), mixer.getDeviceID(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
            if (Printer.trace) Printer.trace("DirectTDL CONSTRUCTOR: completed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
   939
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        public int read(byte[] b, int off, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            flushing = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            if (len == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            if (len < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
                throw new IllegalArgumentException("illegal len: "+len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
            if (len % getFormat().getFrameSize() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
                throw new IllegalArgumentException("illegal request to read "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
                                                   +"non-integral number of frames ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
                                                   +len+" bytes, "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
                                                   +"frameSize = "+getFormat().getFrameSize()+" bytes)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            if (off < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
                throw new ArrayIndexOutOfBoundsException(off);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            }
11893
6a3b541908ae 7088367: JavaSound security issue (12865443)
amenkov
parents: 9035
diff changeset
   957
            if ((long)off + (long)len > (long)b.length) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
                throw new ArrayIndexOutOfBoundsException(b.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            if (!isActive() && doIO) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
                // this is not exactly correct... would be nicer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
                // if the native sub system sent a callback when IO really starts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
                setActive(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
                setStarted(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
            int read = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
            while (doIO && !flushing) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   968
                int thisRead;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
                synchronized (lockNative) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
   970
                    thisRead = nRead(id, b, off, len, softwareConversionSize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
                    if (thisRead < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
                        // error in native layer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
                    bytePosition += thisRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
                    if (thisRead > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
                        drained = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
                len -= thisRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
                read += thisRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
                if (len > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                    off += thisRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
                    synchronized(lock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
                            lock.wait(waitTime);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
                        } catch (InterruptedException ie) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
            if (flushing) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                read = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            return read;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
     * Private inner class representing a Clip
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
     * This clip is realized in software only
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
     */
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
  1005
    private static final class DirectClip extends DirectDL
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
  1006
            implements Clip, Runnable, AutoClosingClip {
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
  1007
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        private Thread thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
        private byte[] audioData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
        private int frameSize;         // size of one frame in bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
        private int m_lengthInFrames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
        private int loopCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
        private int clipBytePosition;   // index in the audioData array at current playback
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
        private int newFramePosition;   // set in setFramePosition()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
        private int loopStartFrame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
        private int loopEndFrame;      // the last sample included in the loop
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        // auto closing clip support
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
        private boolean autoclosing = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
        private DirectClip(DataLine.Info info,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                           AudioFormat format,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
                           int bufferSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                           DirectAudioDevice mixer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
            super(info, mixer, format, bufferSize, mixer.getMixerIndex(), mixer.getDeviceID(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
            if (Printer.trace) Printer.trace("DirectClip CONSTRUCTOR: completed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        // CLIP METHODS
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1031
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        public void open(AudioFormat format, byte[] data, int offset, int bufferSize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            throws LineUnavailableException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            // $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
            Toolkit.isFullySpecifiedAudioFormat(format);
41790
88b6889f7c39 8167435: IllegalArgumentException is not thrown by Clip.open(AudioFormat,byte[], int, int)
serb
parents: 40444
diff changeset
  1037
            Toolkit.validateBuffer(format.getFrameSize(), bufferSize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            byte[] newData = new byte[bufferSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
            System.arraycopy(data, offset, newData, 0, bufferSize);
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
  1041
            open(format, newData, bufferSize / format.getFrameSize());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
        // this method does not copy the data array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        private void open(AudioFormat format, byte[] data, int frameLength)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            throws LineUnavailableException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
            // $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            Toolkit.isFullySpecifiedAudioFormat(format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
            synchronized (mixer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                if (Printer.trace) Printer.trace("> DirectClip.open(format, data, frameLength)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
                if (Printer.debug) Printer.debug("   data="+((data==null)?"null":""+data.length+" bytes"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
                if (Printer.debug) Printer.debug("   frameLength="+frameLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                if (isOpen()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                    throw new IllegalStateException("Clip is already open with format " + getFormat() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                                                    " and frame lengh of " + getFrameLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
                    // if the line is not currently open, try to open it with this format and buffer size
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
                    this.audioData = data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
                    this.frameSize = format.getFrameSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
                    this.m_lengthInFrames = frameLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                    // initialize loop selection with full range
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
                    bytePosition = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                    clipBytePosition = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                    newFramePosition = -1; // means: do not set to a new readFramePos
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                    loopStartFrame = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                    loopEndFrame = frameLength - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                    loopCount = 0; // means: play the clip irrespective of loop points from beginning to end
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                        // use DirectDL's open method to open it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                        open(format, (int) Toolkit.millis2bytes(format, CLIP_BUFFER_TIME)); // one second buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
                    } catch (LineUnavailableException lue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
                        audioData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
                        throw lue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
                    } catch (IllegalArgumentException iae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
                        audioData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
                        throw iae;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                    // if we got this far, we can instanciate the thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                    int priority = Thread.NORM_PRIORITY
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                        + (Thread.MAX_PRIORITY - Thread.NORM_PRIORITY) / 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                    thread = JSSecurityManager.createThread(this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
                                                            "Direct Clip", // name
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
                                                            true,     // daemon
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
                                                            priority, // priority
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                                                            false);  // doStart
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
                    // cannot start in createThread, because the thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
                    // uses the "thread" variable as indicator if it should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
                    // continue to run
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
                    thread.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
            if (isAutoClosing()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
                getEventDispatcher().autoClosingClipOpened(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            if (Printer.trace) Printer.trace("< DirectClip.open completed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1103
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
        public void open(AudioInputStream stream) throws LineUnavailableException, IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
            // $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
            Toolkit.isFullySpecifiedAudioFormat(format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
            synchronized (mixer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
                if (Printer.trace) Printer.trace("> DirectClip.open(stream)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
                byte[] streamData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
                if (isOpen()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
                    throw new IllegalStateException("Clip is already open with format " + getFormat() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
                                                    " and frame lengh of " + getFrameLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
                int lengthInFrames = (int)stream.getFrameLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
                if (Printer.debug) Printer.debug("DirectClip: open(AIS): lengthInFrames: " + lengthInFrames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
                int bytesRead = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
                if (lengthInFrames != AudioSystem.NOT_SPECIFIED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
                    // read the data from the stream into an array in one fell swoop.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
                    int arraysize = lengthInFrames * stream.getFormat().getFrameSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
                    streamData = new byte[arraysize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
                    int bytesRemaining = arraysize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
                    int thisRead = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
                    while (bytesRemaining > 0 && thisRead >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
                        thisRead = stream.read(streamData, bytesRead, bytesRemaining);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
                        if (thisRead > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                            bytesRead += thisRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
                            bytesRemaining -= thisRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
                        else if (thisRead == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
                            Thread.yield();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
                    // read data from the stream until we reach the end of the stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
                    // we use a slightly modified version of ByteArrayOutputStream
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
                    // to get direct access to the byte array (we don't want a new array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
                    // to be allocated)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
                    int MAX_READ_LIMIT = 16384;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
                    DirectBAOS dbaos  = new DirectBAOS();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
                    byte tmp[] = new byte[MAX_READ_LIMIT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
                    int thisRead = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                    while (thisRead >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                        thisRead = stream.read(tmp, 0, tmp.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
                        if (thisRead > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
                            dbaos.write(tmp, 0, thisRead);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
                            bytesRead += thisRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                        else if (thisRead == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
                            Thread.yield();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
                    } // while
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
                    streamData = dbaos.getInternalBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
                lengthInFrames = bytesRead / stream.getFormat().getFrameSize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
                if (Printer.debug) Printer.debug("Read to end of stream. lengthInFrames: " + lengthInFrames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
                // now try to open the device
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
                open(stream.getFormat(), streamData, lengthInFrames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                if (Printer.trace) Printer.trace("< DirectClip.open(stream) succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
            } // synchronized
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1170
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
        public int getFrameLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
            return m_lengthInFrames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1175
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
        public long getMicrosecondLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
            return Toolkit.frames2micros(getFormat(), getFrameLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1180
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        public void setFramePosition(int frames) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
            if (Printer.trace) Printer.trace("> DirectClip: setFramePosition: " + frames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
            if (frames < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                frames = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
            else if (frames >= getFrameLength()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                frames = getFrameLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
            if (doIO) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                newFramePosition = frames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                clipBytePosition = frames * frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                newFramePosition = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            // fix for failing test050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
            // $$fb although getFramePosition should return the number of rendered
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
            // frames, it is intuitive that setFramePosition will modify that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
            // value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
            bytePosition = frames * frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
            // cease currently playing buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
            flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
            // set new native position (if necessary)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
            // this must come after the flush!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
            synchronized (lockNative) {
8527
4b82a41f91bc 6801206: SoundTestSuite: test050 fails
amenkov
parents: 7805
diff changeset
  1208
                nSetBytePosition(id, isSource, frames * frameSize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
            if (Printer.debug) Printer.debug("  DirectClip.setFramePosition: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
                                             +" doIO="+doIO
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                                             +" newFramePosition="+newFramePosition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                                             +" clipBytePosition="+clipBytePosition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
                                             +" bytePosition="+bytePosition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
                                             +" getLongFramePosition()="+getLongFramePosition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
            if (Printer.trace) Printer.trace("< DirectClip: setFramePosition");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
        // replacement for getFramePosition (see AbstractDataLine)
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1221
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
        public long getLongFramePosition() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
            /* $$fb
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
             * this would be intuitive, but the definition of getFramePosition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
             * is the number of frames rendered since opening the device...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
             * That also means that setFramePosition() means something very
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
             * different from getFramePosition() for Clip.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
            // take into account the case that a new position was set...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
            //if (!doIO && newFramePosition >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
            //return newFramePosition;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
            //}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
            return super.getLongFramePosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1236
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
        public synchronized void setMicrosecondPosition(long microseconds) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
            if (Printer.trace) Printer.trace("> DirectClip: setMicrosecondPosition: " + microseconds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            long frames = Toolkit.micros2frames(getFormat(), microseconds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
            setFramePosition((int) frames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
            if (Printer.trace) Printer.trace("< DirectClip: setMicrosecondPosition succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1246
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
        public void setLoopPoints(int start, int end) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
            if (Printer.trace) Printer.trace("> DirectClip: setLoopPoints: start: " + start + " end: " + end);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
            if (start < 0 || start >= getFrameLength()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
                throw new IllegalArgumentException("illegal value for start: "+start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
            if (end >= getFrameLength()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
                throw new IllegalArgumentException("illegal value for end: "+end);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
            if (end == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                end = getFrameLength() - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
                if (end < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
                    end = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
            // if the end position is less than the start position, throw IllegalArgumentException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
            if (end < start) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
                throw new IllegalArgumentException("End position " + end + "  preceeds start position " + start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
            // slight race condition with the run() method, but not a big problem
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
            loopStartFrame = start;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
            loopEndFrame = end;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
            if (Printer.trace) Printer.trace("  loopStart: " + loopStartFrame + " loopEnd: " + loopEndFrame);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
            if (Printer.trace) Printer.trace("< DirectClip: setLoopPoints completed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1277
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
        public void loop(int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
            // note: when count reaches 0, it means that the entire clip
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
            // will be played, i.e. it will play past the loop end point
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
            loopCount = count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
            start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1285
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
        void implOpen(AudioFormat format, int bufferSize) throws LineUnavailableException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
            // only if audioData wasn't set in a calling open(format, byte[], frameSize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
            // this call is allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
            if (audioData == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
                throw new IllegalArgumentException("illegal call to open() in interface Clip");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
            super.implOpen(format, bufferSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1295
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
        void implClose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
            if (Printer.trace) Printer.trace(">> DirectClip: implClose()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
            // dispose of thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
            Thread oldThread = thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
            thread = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
            doIO = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
            if (oldThread != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
                // wake up the thread if it's in wait()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
                synchronized(lock) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
                    lock.notifyAll();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
                // wait for the thread to terminate itself,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
                // but max. 2 seconds. Must not be synchronized!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
                    oldThread.join(2000);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                } catch (InterruptedException ie) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
            super.implClose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
            // remove audioData reference and hand it over to gc
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
            audioData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
            newFramePosition = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
            // remove this instance from the list of auto closing clips
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
            getEventDispatcher().autoClosingClipClosed(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
            if (Printer.trace) Printer.trace("<< DirectClip: implClose() succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1325
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
        void implStart() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
            if (Printer.trace) Printer.trace("> DirectClip: implStart()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
            super.implStart();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
            if (Printer.trace) Printer.trace("< DirectClip: implStart() succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1332
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
        void implStop() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
            if (Printer.trace) Printer.trace(">> DirectClip: implStop()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
            super.implStop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
            // reset loopCount field so that playback will be normal with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
            // next call to start()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
            loopCount = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
            if (Printer.trace) Printer.trace("<< DirectClip: implStop() succeeded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
        // main playback loop
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1345
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
            if (Printer.trace) Printer.trace(">>> DirectClip: run() threadID="+Thread.currentThread().getId());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
            while (thread != null) {
7805
ca2d2a7e657a 6968933: Clip loop() deadlock in DirectAudioDevice$DirectClip.run
kevinw
parents: 5506
diff changeset
  1349
                // doIO is volatile, but we could check it, then get
ca2d2a7e657a 6968933: Clip loop() deadlock in DirectAudioDevice$DirectClip.run
kevinw
parents: 5506
diff changeset
  1350
                // pre-empted while another thread changes doIO and notifies,
ca2d2a7e657a 6968933: Clip loop() deadlock in DirectAudioDevice$DirectClip.run
kevinw
parents: 5506
diff changeset
  1351
                // before we wait (so we sleep in wait forever).
ca2d2a7e657a 6968933: Clip loop() deadlock in DirectAudioDevice$DirectClip.run
kevinw
parents: 5506
diff changeset
  1352
                synchronized(lock) {
ca2d2a7e657a 6968933: Clip loop() deadlock in DirectAudioDevice$DirectClip.run
kevinw
parents: 5506
diff changeset
  1353
                    if (!doIO) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
                            lock.wait();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
                        } catch(InterruptedException ie) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
                while (doIO) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
                    if (newFramePosition >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
                        clipBytePosition = newFramePosition * frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
                        newFramePosition = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
                    int endFrame = getFrameLength() - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
                    if (loopCount > 0 || loopCount == LOOP_CONTINUOUSLY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
                        endFrame = loopEndFrame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
                    long framePos = (clipBytePosition / frameSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
                    int toWriteFrames = (int) (endFrame - framePos + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
                    int toWriteBytes = toWriteFrames * frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
                    if (toWriteBytes > getBufferSize()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
                        toWriteBytes = Toolkit.align(getBufferSize(), frameSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
                    }
22584
eed64ee05369 8032733: Fix cast lint warnings in client libraries
darcy
parents: 21278
diff changeset
  1374
                    int written = write(audioData, clipBytePosition, toWriteBytes); // increases bytePosition
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
                    clipBytePosition += written;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
                    // make sure nobody called setFramePosition, or stop() during the write() call
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
                    if (doIO && newFramePosition < 0 && written >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
                        framePos = clipBytePosition / frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
                        // since endFrame is the last frame to be played,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
                        // framePos is after endFrame when all frames, including framePos,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
                        // are played.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
                        if (framePos > endFrame) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
                            // at end of playback. If looping is on, loop back to the beginning.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
                            if (loopCount > 0 || loopCount == LOOP_CONTINUOUSLY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
                                if (loopCount != LOOP_CONTINUOUSLY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
                                    loopCount--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
                                newFramePosition = loopStartFrame;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
                            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
                                // no looping, stop playback
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
                                if (Printer.debug) Printer.debug("stop clip in run() loop:");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
                                if (Printer.debug) Printer.debug("  doIO="+doIO+" written="+written+" clipBytePosition="+clipBytePosition);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
                                if (Printer.debug) Printer.debug("  framePos="+framePos+" endFrame="+endFrame);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
                                drain();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
                                stop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
            if (Printer.trace) Printer.trace("<<< DirectClip: run() threadID="+Thread.currentThread().getId());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
        // AUTO CLOSING CLIP SUPPORT
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
        /* $$mp 2003-10-01
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
           The following two methods are common between this class and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
           MixerClip. They should be moved to a base class, together
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
           with the instance variable 'autoclosing'. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1411
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
        public boolean isAutoClosing() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
            return autoclosing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1416
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
        public void setAutoClosing(boolean value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
            if (value != autoclosing) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
                if (isOpen()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
                    if (value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
                        getEventDispatcher().autoClosingClipOpened(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
                        getEventDispatcher().autoClosingClipClosed(this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                autoclosing = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
40444
afabcfc2f3ef 8163949: Cleanup of classes which are related to JavaSound
serb
parents: 25859
diff changeset
  1430
        @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
        protected boolean requiresServicing() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
            // no need for servicing for Clips
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
    } // DirectClip
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
     * private inner class representing a ByteArrayOutputStream
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
     * which allows retrieval of the internal array
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
    private static class DirectBAOS extends ByteArrayOutputStream {
18215
b2afd66ce6db 8006328: Improve robustness of sound classes
serb
parents: 11893
diff changeset
  1443
        DirectBAOS() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
            super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
        public byte[] getInternalBuffer() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
            return buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
    } // class DirectBAOS
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
24548
9c007a986347 8042256: Fix raw and unchecked lint warnings in com.sun.media.sound
darcy
parents: 22584
diff changeset
  1453
    @SuppressWarnings("rawtypes")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
    private static native void nGetFormats(int mixerIndex, int deviceID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                                           boolean isSource, Vector formats);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
    private static native long nOpen(int mixerIndex, int deviceID, boolean isSource,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
                                     int encoding,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
                                     float sampleRate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
                                     int sampleSizeInBits,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
                                     int frameSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
                                     int channels,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
                                     boolean signed,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
                                     boolean bigEndian,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
                                     int bufferSize) throws LineUnavailableException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
    private static native void nStart(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
    private static native void nStop(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
    private static native void nClose(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
    private static native int nWrite(long id, byte[] b, int off, int len, int conversionSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
                                     float volLeft, float volRight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
    private static native int nRead(long id, byte[] b, int off, int len, int conversionSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
    private static native int nGetBufferSize(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
    private static native boolean nIsStillDraining(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
    private static native void nFlush(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
    private static native int nAvailable(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
    // javaPos is number of bytes read/written in Java layer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
    private static native long nGetBytePosition(long id, boolean isSource, long javaPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
    private static native void nSetBytePosition(long id, boolean isSource, long pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
    // returns if the native implementation needs regular calls to nService()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
    private static native boolean nRequiresServicing(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
    // called in irregular intervals
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
    private static native void nService(long id, boolean isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
}