1/*
2 * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24import javax.sound.midi.Instrument;
25import javax.sound.midi.MidiSystem;
26import javax.sound.midi.Soundbank;
27import javax.sound.midi.Synthesizer;
28import javax.sound.sampled.AudioSystem;
29import javax.sound.sampled.Mixer;
30
31/**
32 * @test
33 * @bug 4429762
34 * @summary Some instrument names in some soundbanks include bad extra characters
35 */
36public class ExtraCharInSoundbank {
37
38    private static void printName(String loadedName)
39    {
40        System.out.println("Loaded Name: " + loadedName);
41        byte[] theLoadedNameByteArray = loadedName.getBytes();
42
43        System.out.print("Name Bytes: ");
44        for(int i = 0; i < theLoadedNameByteArray.length; i++)
45            System.out.print((Integer.toHexString((int)theLoadedNameByteArray[i]).toUpperCase()) + " ");
46        System.out.println("");
47        System.out.println("");
48    }
49
50    private static boolean containsControlChar(String name) {
51        byte[] bytes = name.getBytes();
52        for (int i = 0; i < bytes.length; i++) {
53            if (bytes[i] < 32) {
54                return true;
55            }
56        }
57        return false;
58    }
59
60    public static boolean checkInstrumentNames(Synthesizer theSynthesizer)
61    {
62        boolean containsControlCharacters = false;
63
64        Instrument[] theLoadedInstruments = theSynthesizer.getLoadedInstruments();
65
66        System.out.println("Checking soundbank...");
67        for(int theInstrumentIndex = 0; theInstrumentIndex < theLoadedInstruments.length; theInstrumentIndex++) {
68            String name = theLoadedInstruments[theInstrumentIndex].getName();
69            if (containsControlChar(name)) {
70                containsControlCharacters = true;
71                System.out.print("Instrument[" + theInstrumentIndex + "] contains unexpected control characters: ");
72                printName(name);
73            }
74        }
75        return !containsControlCharacters;
76    }
77
78    public static void main(String[] args) throws Exception {
79        // the internal synthesizer needs a soundcard to work properly
80        if (!isSoundcardInstalled()) {
81            return;
82        }
83        Synthesizer theSynth = MidiSystem.getSynthesizer();
84        System.out.println("Got synth: "+theSynth);
85        theSynth.open();
86        try {
87            Soundbank theSoundbank = theSynth.getDefaultSoundbank();
88            System.out.println("Got soundbank: "+theSoundbank);
89            theSynth.loadAllInstruments(theSoundbank);
90            try {
91                    if (!checkInstrumentNames(theSynth)) {
92                            throw new Exception("Test failed");
93                    }
94            } finally {
95                    theSynth.unloadAllInstruments(theSoundbank);
96            }
97        } finally {
98            theSynth.close();
99        }
100        System.out.println("Test passed.");
101    }
102
103    /**
104     * Returns true if at least one soundcard is correctly installed
105     * on the system.
106     */
107    public static boolean isSoundcardInstalled() {
108        boolean result = false;
109        try {
110            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
111            if (mixers.length > 0) {
112                result = AudioSystem.getSourceDataLine(null) != null;
113            }
114        } catch (Exception e) {
115            System.err.println("Exception occured: "+e);
116        }
117        if (!result) {
118            System.err.println("Soundcard does not exist or sound drivers not installed!");
119            System.err.println("This test requires sound drivers for execution.");
120        }
121        return result;
122    }
123}
124