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 
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 
29 import javax.sound.sampled.AudioFormat;
30 import javax.sound.sampled.AudioInputStream;
31 import javax.sound.sampled.AudioSystem;
32 
33 /**
34  * @test
35  * @bug 4714846
36  * @summary JavaSound ULAW (8-bit) encoder erroneously depends on endian-ness
37  */
38 public class AlawUlaw {
39     static ByteArrayInputStream in;
40     static int byteLength = 1000;
41 
42     static boolean failed = false;
43 
main(String[] args)44     public static void main(String[] args) throws Exception {
45         // generate some random data
46         byte[] soundData = new byte[byteLength];
47         for (int i=0; i<soundData.length; i++) {
48             soundData[i] = (byte) ((i % 256) - 128);
49         }
50 
51         // create an AudioInputStream from it
52         in = new ByteArrayInputStream(soundData);
53         in.mark(1);
54 
55         test1(PCM_FORMAT_1, ULAW_FORMAT_1, ULAW_FORMAT_2);
56         test1(PCM_FORMAT_2, ULAW_FORMAT_1, ULAW_FORMAT_2);
57         test2(ULAW_FORMAT_1, ULAW_FORMAT_2, PCM_FORMAT_1);
58         test2(ULAW_FORMAT_1, ULAW_FORMAT_2, PCM_FORMAT_2);
59 
60         test1(PCM_FORMAT_1, ALAW_FORMAT_1, ALAW_FORMAT_2);
61         test1(PCM_FORMAT_2, ALAW_FORMAT_1, ALAW_FORMAT_2);
62         test2(ALAW_FORMAT_1, ALAW_FORMAT_2, PCM_FORMAT_1);
63         test2(ALAW_FORMAT_1, ALAW_FORMAT_2, PCM_FORMAT_2);
64 
65         if (failed) {
66                 throw new Exception("Test failed!");
67         }
68     }
69 
printFormat(AudioFormat format)70     public static String printFormat(AudioFormat format) {
71         return format.toString()+"  "+(format.isBigEndian()?"big":"little")+" endian";
72     }
73 
74 
test1(AudioFormat inFormat, AudioFormat outFormat1, AudioFormat outFormat2)75     public static void test1(AudioFormat inFormat, AudioFormat outFormat1, AudioFormat outFormat2) throws Exception {
76         AudioInputStream inStream = new AudioInputStream(in, inFormat, -1);
77         System.out.println("Input Format: " + printFormat(inStream.getFormat()));
78 
79         // get a converted stream
80         AudioInputStream stream1 = AudioSystem.getAudioInputStream(outFormat1, inStream);
81         System.out.println("Output Format 1: " + printFormat(stream1.getFormat()));
82 
83         // get a converted stream in big endian ulaw
84         AudioInputStream stream2 = AudioSystem.getAudioInputStream(outFormat2, inStream);
85         System.out.println("Output Format 2: " + printFormat(stream2.getFormat()));
86 
87         compareStreams(stream1, stream2);
88     }
89 
test2(AudioFormat inFormat1, AudioFormat inFormat2, AudioFormat outFormat)90     public static void test2(AudioFormat inFormat1, AudioFormat inFormat2, AudioFormat outFormat) throws Exception {
91         AudioInputStream inStream1 = new AudioInputStream(in, inFormat1, -1);
92         System.out.println("Input Format1: " + printFormat(inStream1.getFormat()));
93 
94         // get a converted stream
95         AudioInputStream stream1 = AudioSystem.getAudioInputStream(outFormat, inStream1);
96         System.out.println("Output Format 1: " + printFormat(stream1.getFormat()));
97 
98         AudioInputStream inStream2 = new AudioInputStream(in, inFormat2, -1);
99         System.out.println("Input Format1: " + printFormat(inStream2.getFormat()));
100 
101         // get a converted stream in big endian ulaw
102         AudioInputStream stream2 = AudioSystem.getAudioInputStream(outFormat, inStream2);
103         System.out.println("Output Format 2: " + printFormat(stream2.getFormat()));
104 
105         compareStreams(stream1, stream2);
106     }
107 
compareStreams(InputStream stream1, InputStream stream2)108     public static void compareStreams(InputStream stream1, InputStream stream2) throws Exception {
109         ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
110         ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
111 
112         in.reset();
113         writeDirectly(stream1, baos1);
114         in.reset();
115         writeDirectly(stream2, baos2);
116 
117         if (baos1.size() != baos2.size()) {
118             System.out.println("   stream1 has length = "+baos1.size()+", stream2 has length = "+baos2.size());
119         }
120         int len = baos1.size();
121         if (len > baos2.size()) {
122                 len = baos2.size();
123         }
124         byte[] data1=baos1.toByteArray();
125         byte[] data2=baos2.toByteArray();
126         for (int i=0; i<len; i++) {
127                 if (data1[i] != data2[i]) {
128                         System.out.println("  FAILED! Difference encountered at position "+i);
129                         failed = true;
130                         return;
131                 }
132         }
133         if (baos1.size() != baos2.size()) {
134                 System.out.println("  No difference, but different length!");
135                 failed = true;
136                 return;
137         }
138         System.out.println("   PASSED");
139     }
140 
writeDirectly(InputStream in, OutputStream out)141     public static void writeDirectly(InputStream in, OutputStream out) throws Exception {
142             // read data from the stream until we reach the end of the stream
143             byte tmp[] = new byte[16384];
144             while (true) {
145                 int bytesRead = in.read(tmp, 0, tmp.length);
146                 if (bytesRead == -1) {
147                         break;
148                 }
149                 out.write(tmp, 0, bytesRead);
150             } // while
151     }
152 
153     public static final AudioFormat PCM_FORMAT_1 =
154         new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
155                          8000f, //sample rate
156                          16, //bits per sample
157                          1, //channels
158                          2, //frame size
159                          8000f, // frame rate
160                          false); //isBigEndian
161     public static final AudioFormat PCM_FORMAT_2 =
162         new AudioFormat( AudioFormat.Encoding.PCM_SIGNED,
163                          8000f, //sample rate
164                          16, //bits per sample
165                          1, //channels
166                          2, //frame size
167                          8000f, // frame rate
168                          true); //isBigEndian
169 
170     public static final AudioFormat ULAW_FORMAT_1 =
171         new AudioFormat( AudioFormat.Encoding.ULAW,
172                          8000f, //sample rate
173                          8, //bits per sample
174                          1, //channels
175                          1, //frame size
176                          8000f, // frame rate
177                          false); //isBigEndian
178 
179     public static final AudioFormat ULAW_FORMAT_2 =
180         new AudioFormat( AudioFormat.Encoding.ULAW,
181                          8000f, //sample rate
182                          8, //bits per sample
183                          1, //channels
184                          1, //frame size
185                          8000f, // frame rate
186                          true); //isBigEndian
187 
188     public static final AudioFormat ALAW_FORMAT_1 =
189         new AudioFormat( AudioFormat.Encoding.ALAW,
190                          8000f, //sample rate
191                          8, //bits per sample
192                          1, //channels
193                          1, //frame size
194                          8000f, // frame rate
195                          false); //isBigEndian
196 
197     public static final AudioFormat ALAW_FORMAT_2 =
198         new AudioFormat( AudioFormat.Encoding.ALAW,
199                          8000f, //sample rate
200                          8, //bits per sample
201                          1, //channels
202                          1, //frame size
203                          8000f, // frame rate
204                          true); //isBigEndian
205 }
206