Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/media/sound/AbstractLine.java
38924 views
/*1* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.media.sound;2627import java.util.Map;28import java.util.Vector;29import java.util.WeakHashMap;3031import javax.sound.sampled.AudioSystem;32import javax.sound.sampled.Control;33import javax.sound.sampled.Line;34import javax.sound.sampled.LineEvent;35import javax.sound.sampled.LineListener;36import javax.sound.sampled.LineUnavailableException;373839/**40* AbstractLine41*42* @author Kara Kytle43*/44abstract class AbstractLine implements Line {4546protected final Line.Info info;47protected Control[] controls;48AbstractMixer mixer;49private volatile boolean open;50private final Vector listeners = new Vector();5152/**53* Contains event dispatcher per thread group.54*/55private static final Map<ThreadGroup, EventDispatcher> dispatchers =56new WeakHashMap<>();5758/**59* Constructs a new AbstractLine.60* @param mixer the mixer with which this line is associated61* @param controls set of supported controls62*/63protected AbstractLine(Line.Info info, AbstractMixer mixer, Control[] controls) {6465if (controls == null) {66controls = new Control[0];67}6869this.info = info;70this.mixer = mixer;71this.controls = controls;72}737475// LINE METHODS7677public final Line.Info getLineInfo() {78return info;79}808182public final boolean isOpen() {83return open;84}858687public final void addLineListener(LineListener listener) {88synchronized(listeners) {89if ( ! (listeners.contains(listener)) ) {90listeners.addElement(listener);91}92}93}949596/**97* Removes an audio listener.98* @param listener listener to remove99*/100public final void removeLineListener(LineListener listener) {101listeners.removeElement(listener);102}103104105/**106* Obtains the set of controls supported by the107* line. If no controls are supported, returns an108* array of length 0.109* @return control set110*/111public final Control[] getControls() {112Control[] returnedArray = new Control[controls.length];113114for (int i = 0; i < controls.length; i++) {115returnedArray[i] = controls[i];116}117118return returnedArray;119}120121122public final boolean isControlSupported(Control.Type controlType) {123// protect against a NullPointerException124if (controlType == null) {125return false;126}127128for (int i = 0; i < controls.length; i++) {129if (controlType == controls[i].getType()) {130return true;131}132}133134return false;135}136137138public final Control getControl(Control.Type controlType) {139// protect against a NullPointerException140if (controlType != null) {141142for (int i = 0; i < controls.length; i++) {143if (controlType == controls[i].getType()) {144return controls[i];145}146}147}148149throw new IllegalArgumentException("Unsupported control type: " + controlType);150}151152153// HELPER METHODS154155156/**157* This method sets the open state and generates158* events if it changes.159*/160final void setOpen(boolean open) {161162if (Printer.trace) Printer.trace("> "+getClass().getName()+" (AbstractLine): setOpen(" + open + ") this.open: " + this.open);163164boolean sendEvents = false;165long position = getLongFramePosition();166167synchronized (this) {168if (this.open != open) {169this.open = open;170sendEvents = true;171}172}173174if (sendEvents) {175if (open) {176sendEvents(new LineEvent(this, LineEvent.Type.OPEN, position));177} else {178sendEvents(new LineEvent(this, LineEvent.Type.CLOSE, position));179}180}181if (Printer.trace) Printer.trace("< "+getClass().getName()+" (AbstractLine): setOpen(" + open + ") this.open: " + this.open);182}183184185/**186* Send line events.187*/188final void sendEvents(LineEvent event) {189getEventDispatcher().sendAudioEvents(event, listeners);190}191192193/**194* This is an error in the API: getFramePosition195* should return a long value. At CD quality,196* the int value wraps around after 13 hours.197*/198public final int getFramePosition() {199return (int) getLongFramePosition();200}201202203/**204* Return the frame position in a long value205* This implementation returns AudioSystem.NOT_SPECIFIED.206*/207public long getLongFramePosition() {208return AudioSystem.NOT_SPECIFIED;209}210211212// $$kk: 06.03.99: returns the mixer used in construction.213// this is a hold-over from when there was a public method like214// this on line and should be fixed!!215final AbstractMixer getMixer() {216return mixer;217}218219final EventDispatcher getEventDispatcher() {220// create and start the global event thread221//TODO need a way to stop this thread when the engine is done222final ThreadGroup tg = Thread.currentThread().getThreadGroup();223synchronized (dispatchers) {224EventDispatcher eventDispatcher = dispatchers.get(tg);225if (eventDispatcher == null) {226eventDispatcher = new EventDispatcher();227dispatchers.put(tg, eventDispatcher);228eventDispatcher.start();229}230return eventDispatcher;231}232}233234// ABSTRACT METHODS235236public abstract void open() throws LineUnavailableException;237public abstract void close();238}239240241