From 030044ba76c7f35e45655aec6debfef0c569d3dc Mon Sep 17 00:00:00 2001 From: serb Date: Tue, 10 Mar 2020 07:07:09 +0100 Subject: [PATCH] 8238925: Enhance WAV file playback Reviewed-by: prr, amenkov, rhalade, mschoene, mbalao, andrew --- .../sun/media/sound/DirectAudioDevice.java | 28 +++++++++++++------ .../classes/com/sun/media/sound/Toolkit.java | 15 ++++++---- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/share/classes/com/sun/media/sound/DirectAudioDevice.java b/src/share/classes/com/sun/media/sound/DirectAudioDevice.java index ba862f116..6688afa36 100644 --- a/src/share/classes/com/sun/media/sound/DirectAudioDevice.java +++ b/src/share/classes/com/sun/media/sound/DirectAudioDevice.java @@ -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 @@ -1121,7 +1121,7 @@ final class DirectAudioDevice extends AbstractMixer { 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)"); @@ -1135,11 +1135,18 @@ final class DirectAudioDevice extends AbstractMixer { 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) { @@ -1157,9 +1164,14 @@ final class DirectAudioDevice extends AbstractMixer { // 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); @@ -1173,7 +1185,7 @@ final class DirectAudioDevice extends AbstractMixer { } // while streamData = dbaos.getInternalBuffer(); } - lengthInFrames = bytesRead / stream.getFormat().getFrameSize(); + lengthInFrames = bytesRead / frameSize; if (Printer.debug) Printer.debug("Read to end of stream. lengthInFrames: " + lengthInFrames); diff --git a/src/share/classes/com/sun/media/sound/Toolkit.java b/src/share/classes/com/sun/media/sound/Toolkit.java index 5d52b8fe7..96733cfa9 100644 --- a/src/share/classes/com/sun/media/sound/Toolkit.java +++ b/src/share/classes/com/sun/media/sound/Toolkit.java @@ -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 @@ public final class Toolkit { } 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 @@ public final class Toolkit { +((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)? -- GitLab