PortMixerProvider.java revision 15409:eb0e7e2360f2
155714Skris/*
255714Skris * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
355714Skris * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
455714Skris *
555714Skris * This code is free software; you can redistribute it and/or modify it
655714Skris * under the terms of the GNU General Public License version 2 only, as
755714Skris * published by the Free Software Foundation.  Oracle designates this
855714Skris * particular file as subject to the "Classpath" exception as provided
955714Skris * by Oracle in the LICENSE file that accompanied this code.
1055714Skris *
1155714Skris * This code is distributed in the hope that it will be useful, but WITHOUT
1255714Skris * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1355714Skris * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1455714Skris * version 2 for more details (a copy is included in the LICENSE file that
1555714Skris * accompanied this code).
1655714Skris *
1755714Skris * You should have received a copy of the GNU General Public License version
1855714Skris * 2 along with this work; if not, write to the Free Software Foundation,
1955714Skris * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2055714Skris *
2155714Skris * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2255714Skris * or visit www.oracle.com if you need additional information or have any
2355714Skris * questions.
2455714Skris */
2555714Skris
2655714Skrispackage com.sun.media.sound;
2755714Skris
2855714Skrisimport javax.sound.sampled.Mixer;
2955714Skrisimport javax.sound.sampled.spi.MixerProvider;
3055714Skris
3155714Skris/**
3255714Skris * Port provider.
3355714Skris *
3455714Skris * @author Florian Bomers
3555714Skris */
3655714Skrispublic final class PortMixerProvider extends MixerProvider {
3755714Skris
3855714Skris    /**
3955714Skris     * Set of info objects for all port input devices on the system.
4055714Skris     */
4155714Skris    private static PortMixerInfo[] infos;
4255714Skris
4355714Skris    /**
4455714Skris     * Set of all port input devices on the system.
4555714Skris     */
4655714Skris    private static PortMixer[] devices;
4755714Skris
4855714Skris    static {
4955714Skris        // initialize
5055714Skris        Platform.initialize();
5155714Skris    }
5255714Skris
5355714Skris    /**
5455714Skris     * Required public no-arg constructor.
5555714Skris     */
5655714Skris    public PortMixerProvider() {
5755714Skris        synchronized (PortMixerProvider.class) {
5855714Skris            if (Platform.isPortsEnabled()) {
5955714Skris                init();
6055714Skris            } else {
6155714Skris                infos = new PortMixerInfo[0];
62109998Smarkm                devices = new PortMixer[0];
6355714Skris            }
6455714Skris        }
6555714Skris    }
6655714Skris
6755714Skris    private static void init() {
6855714Skris        // get the number of input devices
6955714Skris        int numDevices = nGetNumDevices();
7055714Skris
7155714Skris        if (infos == null || infos.length != numDevices) {
7255714Skris            if (Printer.trace) Printer.trace("PortMixerProvider: init()");
7355714Skris            // initialize the arrays
7455714Skris            infos = new PortMixerInfo[numDevices];
7555714Skris            devices = new PortMixer[numDevices];
7655714Skris
7755714Skris            // fill in the info objects now.
7855714Skris            // we'll fill in the device objects as they're requested.
7955714Skris            for (int i = 0; i < infos.length; i++) {
8055714Skris                infos[i] = nNewPortMixerInfo(i);
8155714Skris            }
8255714Skris            if (Printer.trace) Printer.trace("PortMixerProvider: init(): found numDevices: " + numDevices);
8355714Skris        }
8455714Skris    }
85109998Smarkm
8655714Skris    @Override
8755714Skris    public Mixer.Info[] getMixerInfo() {
8855714Skris        synchronized (PortMixerProvider.class) {
8955714Skris            Mixer.Info[] localArray = new Mixer.Info[infos.length];
9055714Skris            System.arraycopy(infos, 0, localArray, 0, infos.length);
9155714Skris            return localArray;
9255714Skris        }
9355714Skris    }
9455714Skris
9555714Skris    @Override
9655714Skris    public Mixer getMixer(Mixer.Info info) {
9755714Skris        synchronized (PortMixerProvider.class) {
9855714Skris            for (int i = 0; i < infos.length; i++) {
9955714Skris                if (infos[i].equals(info)) {
10055714Skris                    return getDevice(infos[i]);
10155714Skris                }
10255714Skris            }
10355714Skris        }
10455714Skris        throw new IllegalArgumentException(
10555714Skris                String.format("Mixer %s not supported by this provider", info));
10655714Skris    }
10755714Skris
10855714Skris    private static Mixer getDevice(PortMixerInfo info) {
10955714Skris        int index = info.getIndex();
11055714Skris        if (devices[index] == null) {
11155714Skris            devices[index] = new PortMixer(info);
11255714Skris        }
11355714Skris        return devices[index];
11455714Skris    }
11555714Skris
11655714Skris    /**
11755714Skris     * Info class for PortMixers.  Adds an index value for
11855714Skris     * making native references to a particular device.
11955714Skris     * This constructor is called from native.
12055714Skris     */
12155714Skris    static final class PortMixerInfo extends Mixer.Info {
12255714Skris        private final int index;
12355714Skris
12455714Skris        private PortMixerInfo(int index, String name, String vendor, String description, String version) {
12555714Skris            super("Port " + name, vendor, description, version);
12655714Skris            this.index = index;
12755714Skris        }
12855714Skris
12955714Skris        int getIndex() {
13055714Skris            return index;
13155714Skris        }
13255714Skris
13355714Skris    } // class PortMixerInfo
13455714Skris
13555714Skris    private static native int nGetNumDevices();
13655714Skris    private static native PortMixerInfo nNewPortMixerInfo(int mixerIndex);
13755714Skris}
13855714Skris