1 /*
   2  * Copyright (c) 2010, 2012, 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 
  32 import java.io.ByteArrayInputStream;
  33 import java.io.ByteArrayOutputStream;
  34 import java.io.InputStream;
  35 import java.util.Arrays;
  36 import javax.sound.sampled.AudioFormat;
  37 import javax.sound.sampled.AudioInputStream;
  38 import javax.sound.sampled.AudioSystem;
  39 
  40 public 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 }