1/*
2 * Copyright (c) 2010, 2013, 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
24/**
25 * @test
26 * @bug 6938426
27 * @bug 7058852
28 * @summary Tests that Alaw encoder works properly in multithreaded environment
29 * @author Alex Menkov
30 */
31
32import java.io.ByteArrayInputStream;
33import java.io.ByteArrayOutputStream;
34import java.io.InputStream;
35import java.util.Arrays;
36import javax.sound.sampled.AudioFormat;
37import javax.sound.sampled.AudioInputStream;
38import javax.sound.sampled.AudioSystem;
39
40public class AlawEncoderSync {
41
42    static final int THREAD_COUNT   = 20;
43
44    static final AudioFormat pcmFormat = new AudioFormat(8000f, 16, 2, true, false);
45    static final int STREAM_LENGTH = 10;    // in seconds
46    static byte[] pcmBuffer;
47    static final AudioFormat alawFormat
48            = new AudioFormat(AudioFormat.Encoding.ALAW, 8000f, 8, 2, 2, 8000f, false);
49
50    static final ConversionThread[] threads = new ConversionThread[THREAD_COUNT];
51
52    public static void main(String[] args) {
53        preparePCMBuffer();
54        log("pcmStream size: " + pcmBuffer.length);
55
56        for (int i=0; i<THREAD_COUNT; i++) {
57            threads[i] = new ConversionThread(i);
58            threads[i].start();
59        }
60
61        for (int i=0; i<THREAD_COUNT; i++) {
62            try {
63                threads[i].join();
64            } catch (InterruptedException ex) {
65                log("Main thread was interrupted, exiting.");
66                return;
67            }
68        }
69
70        int failed = 0;
71        log("comparing result arrays...");
72        for (int i=1; i<THREAD_COUNT; i++) {
73            if (!Arrays.equals(threads[0].resultArray, threads[i].resultArray)) {
74                failed++;
75                log("NOT equals: 0 and " + i);
76            }
77        }
78        if (failed > 0) {
79            throw new RuntimeException("test FAILED");
80        }
81        log("test PASSED.");
82    }
83
84
85    static void preparePCMBuffer() {
86        pcmBuffer = new byte[STREAM_LENGTH * (int)pcmFormat.getSampleRate()
87                * (pcmFormat.getSampleSizeInBits() / 8) * pcmFormat.getChannels()];
88        for (int i=0; i<pcmBuffer.length; i++) {
89            pcmBuffer[i] = (byte)(Math.random() * 256.0 - 128.0);
90        }
91    }
92
93    static AudioInputStream createPCMStream() {
94        InputStream byteStream = new ByteArrayInputStream(pcmBuffer);
95        return new AudioInputStream(byteStream, pcmFormat, AudioSystem.NOT_SPECIFIED);
96    }
97
98    static class ConversionThread extends Thread {
99        public final int num;
100        public byte[] resultArray = null;
101        public ConversionThread(int num) {
102            this.num = num;
103        }
104        @Override
105        public void run() {
106            log("ConversionThread[" + num + "] started.");
107            try {
108                InputStream inStream = new ByteArrayInputStream(pcmBuffer);
109
110                AudioInputStream pcmStream = new AudioInputStream(
111                        inStream, pcmFormat, AudioSystem.NOT_SPECIFIED);
112                AudioInputStream alawStream = AudioSystem.getAudioInputStream(alawFormat, pcmStream);
113
114                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
115                int read = 0;
116                byte[] data = new byte[4096];
117                while((read = alawStream.read(data)) != -1) {
118                    outStream.write(data, 0, read);
119               }
120               alawStream.close();
121               resultArray = outStream.toByteArray();
122            } catch (Exception ex) {
123                log("ConversionThread[" + num + "] exception:");
124                log(ex);
125            }
126            log("ConversionThread[" + num + "] completed.");
127        }
128    }
129
130    static void log(String s) {
131        System.out.println(s);
132    }
133
134    static void log(Exception ex) {
135        ex.printStackTrace(System.out);
136    }
137}
138