1/*
2 * Copyright (c) 2003, 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.sampled.AudioFormat;
25import javax.sound.sampled.AudioSystem;
26import javax.sound.sampled.Clip;
27import javax.sound.sampled.DataLine;
28import javax.sound.sampled.Mixer;
29import javax.sound.sampled.SourceDataLine;
30
31/**
32 * @test
33 * @bug 4515126
34 * @summary Verify that the buffer passed to SourceDataLine.write() and
35 *          Clip.open() will not be changed
36 */
37public class ChangingBuffer {
38
39    final static int samplerate = 44100;
40    final static byte[] buffer = new byte[16384];
41    static int successfulTests = 0;
42
43    private static void makeBuffer() {
44        for (int i=0; i<buffer.length; i++) {
45            buffer[i] = (byte) (i % 128);
46        }
47    }
48
49    private static void checkBufferSDL() throws Exception {
50        successfulTests++;
51        for (int i=0; i<buffer.length; i++) {
52            if (buffer[i] != ((byte) (i % 128))) {
53                throw new Exception("Buffer was changed by SourceDataLine.write()!. Test FAILED");
54            }
55        }
56        System.out.println("  -> passed for this line");
57        System.out.println("");
58    }
59
60    private static void checkBufferClip() throws Exception {
61        for (int i=0; i<buffer.length; i++) {
62            if (buffer[i] != (i % 128)) {
63                throw new Exception("Buffer was changed by Clip.open()!. Test FAILED");
64            }
65        }
66        System.out.println("  -> passed for this clip");
67        System.out.println("");
68    }
69
70    private static boolean doMixerClip(Mixer mixer, AudioFormat format) {
71        if (mixer==null) return false;
72        try {
73            System.out.println("Trying mixer "+mixer+":");
74                DataLine.Info info = new DataLine.Info(
75                                          Clip.class,
76                                          format,
77                                          (int) samplerate);
78
79                Clip clip = (Clip) mixer.getLine(info);
80            System.out.println("  - got clip: "+clip);
81            System.out.println("  - open with format "+format);
82            clip.open(format, buffer, 0, buffer.length);
83            System.out.println("  - playing...");
84            clip.start();
85            System.out.println("  - waiting while it's active...");
86            while (clip.isActive())
87                    Thread.sleep(100);
88            System.out.println("  - waiting 100millis");
89            Thread.sleep(100);
90            System.out.println("  - drain1");
91            clip.drain();
92            System.out.println("  - drain2");
93            clip.drain();
94            System.out.println("  - stop");
95            clip.stop();
96            System.out.println("  - close");
97            clip.close();
98            System.out.println("  - closed");
99        } catch (Throwable t) {
100            System.out.println("  - Caught exception. Not failed.");
101            System.out.println("  - "+t.toString());
102            return false;
103        }
104        return true;
105    }
106
107    private static boolean doMixerSDL(Mixer mixer, AudioFormat format) {
108        if (mixer==null) return false;
109        try {
110            System.out.println("Trying mixer "+mixer+":");
111                DataLine.Info info = new DataLine.Info(
112                                          SourceDataLine.class,
113                                          format,
114                                          (int) samplerate);
115
116                SourceDataLine sdl = (SourceDataLine) mixer.getLine(info);
117            System.out.println("  - got sdl: "+sdl);
118            System.out.println("  - open with format "+format);
119            sdl.open(format);
120            System.out.println("  - start...");
121            sdl.start();
122            System.out.println("  - write...");
123            sdl.write(buffer, 0, buffer.length);
124            Thread.sleep(200);
125            System.out.println("  - drain...");
126            sdl.drain();
127            System.out.println("  - stop...");
128            sdl.stop();
129            System.out.println("  - close...");
130            sdl.close();
131            System.out.println("  - closed");
132        } catch (Throwable t) {
133            System.out.println("  - Caught exception. Not failed.");
134            System.out.println("  - "+t.toString());
135            return false;
136        }
137        return true;
138    }
139
140    private static void doAll(boolean bigEndian) throws Exception {
141        AudioFormat pcm = new AudioFormat(
142                            AudioFormat.Encoding.PCM_SIGNED,
143                            samplerate, 16, 1, 2, samplerate, bigEndian);
144            Mixer.Info[] mixers = AudioSystem.getMixerInfo();
145            for (int i=0; i<mixers.length; i++) {
146                Mixer mixer = AudioSystem.getMixer(mixers[i]);
147                makeBuffer(); if (doMixerClip(mixer, pcm)) checkBufferClip();
148                makeBuffer(); if (doMixerSDL(mixer, pcm)) checkBufferSDL();
149            }
150            if (mixers.length==0) {
151                System.out.println("No mixers available!");
152            }
153
154    }
155
156    public static void main(String args[]) throws Exception{
157        doAll(true);
158        doAll(false);
159        if (successfulTests==0) {
160            System.out.println("Could not execute any of the tests. Test NOT failed.");
161        } else {
162            System.out.println("Test PASSED.");
163        }
164    }
165}
166