changeset 9963:7746a8e93b68

8238925: Enhance WAV file playback Reviewed-by: prr, amenkov, rhalade, mschoene, mbalao, andrew
author serb
date Tue, 10 Mar 2020 07:07:09 +0100
parents e5707e56381b
children b7aa6cda7a03
files src/share/classes/com/sun/media/sound/DirectAudioDevice.java src/share/classes/com/sun/media/sound/Toolkit.java
diffstat 2 files changed, 29 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/media/sound/DirectAudioDevice.java	Wed Mar 18 16:05:15 2020 -0700
+++ b/src/share/classes/com/sun/media/sound/DirectAudioDevice.java	Tue Mar 10 07:07:09 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1115,7 +1115,7 @@
         public void open(AudioInputStream stream) throws LineUnavailableException, IOException {
 
             // $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions
-            Toolkit.isFullySpecifiedAudioFormat(format);
+            Toolkit.isFullySpecifiedAudioFormat(stream.getFormat());
 
             synchronized (mixer) {
                 if (Printer.trace) Printer.trace("> DirectClip.open(stream)");
@@ -1129,11 +1129,18 @@
                 if (Printer.debug) Printer.debug("DirectClip: open(AIS): lengthInFrames: " + lengthInFrames);
 
                 int bytesRead = 0;
+                int frameSize = stream.getFormat().getFrameSize();
                 if (lengthInFrames != AudioSystem.NOT_SPECIFIED) {
                     // read the data from the stream into an array in one fell swoop.
-                    int arraysize = lengthInFrames * stream.getFormat().getFrameSize();
-                    streamData = new byte[arraysize];
-
+                    int arraysize = lengthInFrames * frameSize;
+                    if (arraysize < 0) {
+                        throw new IllegalArgumentException("Audio data < 0");
+                    }
+                    try {
+                        streamData = new byte[arraysize];
+                    } catch (OutOfMemoryError e) {
+                        throw new IOException("Audio data is too big");
+                    }
                     int bytesRemaining = arraysize;
                     int thisRead = 0;
                     while (bytesRemaining > 0 && thisRead >= 0) {
@@ -1151,9 +1158,14 @@
                     // we use a slightly modified version of ByteArrayOutputStream
                     // to get direct access to the byte array (we don't want a new array
                     // to be allocated)
-                    int MAX_READ_LIMIT = 16384;
+                    int maxReadLimit = Math.max(16384, frameSize);
                     DirectBAOS dbaos  = new DirectBAOS();
-                    byte tmp[] = new byte[MAX_READ_LIMIT];
+                    byte[] tmp;
+                    try {
+                        tmp = new byte[maxReadLimit];
+                    } catch (OutOfMemoryError e) {
+                        throw new IOException("Audio data is too big");
+                    }
                     int thisRead = 0;
                     while (thisRead >= 0) {
                         thisRead = stream.read(tmp, 0, tmp.length);
@@ -1167,7 +1179,7 @@
                     } // while
                     streamData = dbaos.getInternalBuffer();
                 }
-                lengthInFrames = bytesRead / stream.getFormat().getFrameSize();
+                lengthInFrames = bytesRead / frameSize;
 
                 if (Printer.debug) Printer.debug("Read to end of stream. lengthInFrames: " + lengthInFrames);
 
--- a/src/share/classes/com/sun/media/sound/Toolkit.java	Wed Mar 18 16:05:15 2020 -0700
+++ b/src/share/classes/com/sun/media/sound/Toolkit.java	Tue Mar 10 07:07:09 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -154,6 +154,14 @@
     }
 
     static void isFullySpecifiedAudioFormat(AudioFormat format) {
+        // Our code requires a positive frame size, that's probably is not
+        // necessary for non-linear encodings, but for now
+        // IllegalArgumentException is better than ArithmeticException
+        if (format.getFrameSize() <= 0) {
+            throw new IllegalArgumentException("invalid frame size: "
+                                               +((format.getFrameSize() == -1) ?
+                    "NOT_SPECIFIED":String.valueOf(format.getFrameSize())));
+        }
         if (!format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
             && !format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED)
             && !format.getEncoding().equals(AudioFormat.Encoding.ULAW)
@@ -176,11 +184,6 @@
                                                +((format.getSampleSizeInBits()==-1)?
                                                  "NOT_SPECIFIED":String.valueOf(format.getSampleSizeInBits())));
         }
-        if (format.getFrameSize() <= 0) {
-            throw new IllegalArgumentException("invalid frame size: "
-                                               +((format.getFrameSize()==-1)?
-                                                 "NOT_SPECIFIED":String.valueOf(format.getFrameSize())));
-        }
         if (format.getChannels() <= 0) {
             throw new IllegalArgumentException("invalid number of channels: "
                                                +((format.getChannels()==-1)?