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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /**
  27  * @test
  28  * @bug 6938426
  29  * @bug 7058852
  30  * @summary Tests that Alaw encoder works properly in multithreaded environment
  31  * @author Alex Menkov
  32  */
  33 
  34 import java.io.ByteArrayInputStream;
  35 import java.io.ByteArrayOutputStream;
  36 import java.io.InputStream;
  37 import java.util.Arrays;
  38 import javax.sound.sampled.AudioFormat;
  39 import javax.sound.sampled.AudioInputStream;
  40 import javax.sound.sampled.AudioSystem;
  41 
  42 public class AlawEncoderSync {
  43 
  44     static final int THREAD_COUNT   = 20;
  45 
  46     static final AudioFormat pcmFormat = new AudioFormat(8000f, 16, 2, true, false);
  47     static final int STREAM_LENGTH = 10;    // in seconds
  48     static byte[] pcmBuffer;
  49     static final AudioFormat alawFormat
  50             = new AudioFormat(AudioFormat.Encoding.ALAW, 8000f, 8, 2, 2, 8000f, false);
  51 
  52     static final ConversionThread[] threads = new ConversionThread[THREAD_COUNT];
  53 
  54     public static void main(String[] args) {
  55         preparePCMBuffer();
  56         log("pcmStream size: " + pcmBuffer.length);
  57 
  58         for (int i=0; i<THREAD_COUNT; i++) {
  59             threads[i] = new ConversionThread(i);
  60             threads[i].start();
  61         }
  62 
  63         for (int i=0; i<THREAD_COUNT; i++) {
  64             try {
  65                 threads[i].join();
  66             } catch (InterruptedException ex) {
  67                 log("Main thread was interrupted, exiting.");
  68                 return;
  69             }
  70         }
  71 
  72         int failed = 0;
  73         log("comparing result arrays...");
  74         for (int i=1; i<THREAD_COUNT; i++) {
  75             if (!Arrays.equals(threads[0].resultArray, threads[i].resultArray)) {
  76                 failed++;
  77                 log("NOT equals: 0 and " + i);
  78             }
  79         }
  80         if (failed > 0) {
  81             throw new RuntimeException("test FAILED");
  82         }
  83         log("test PASSED.");
  84     }
  85 
  86 
  87     static void preparePCMBuffer() {
  88         pcmBuffer = new byte[STREAM_LENGTH * (int)pcmFormat.getSampleRate()
  89                 * (pcmFormat.getSampleSizeInBits() / 8) * pcmFormat.getChannels()];
  90         for (int i=0; i<pcmBuffer.length; i++) {
  91             pcmBuffer[i] = (byte)(Math.random() * 256.0 - 128.0);
  92         }
  93     }
  94 
  95     static AudioInputStream createPCMStream() {
  96         InputStream byteStream = new ByteArrayInputStream(pcmBuffer);
  97         return new AudioInputStream(byteStream, pcmFormat, AudioSystem.NOT_SPECIFIED);
  98     }
  99 
 100     static class ConversionThread extends Thread {
 101         public final int num;
 102         public byte[] resultArray = null;
 103         public ConversionThread(int num) {
 104             this.num = num;
 105         }
 106         @Override
 107         public void run() {
 108             log("ConversionThread[" + num + "] started.");
 109             try {
 110                 InputStream inStream = new ByteArrayInputStream(pcmBuffer);
 111 
 112                 AudioInputStream pcmStream = new AudioInputStream(
 113                         inStream, pcmFormat, AudioSystem.NOT_SPECIFIED);
 114                 AudioInputStream alawStream = AudioSystem.getAudioInputStream(alawFormat, pcmStream);
 115 
 116                 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
 117                 int read = 0;
 118                 byte[] data = new byte[4096];
 119                 while((read = alawStream.read(data)) != -1) {
 120                     outStream.write(data, 0, read);
 121                }
 122                alawStream.close();
 123                resultArray = outStream.toByteArray();
 124             } catch (Exception ex) {
 125                 log("ConversionThread[" + num + "] exception:");
 126                 log(ex);
 127             }
 128             log("ConversionThread[" + num + "] completed.");
 129         }
 130     }
 131 
 132     static void log(String s) {
 133         System.out.println(s);
 134     }
 135 
 136     static void log(Exception ex) {
 137         ex.printStackTrace(System.out);
 138     }
 139 }