From 4a3514712815ebf8a2496dc436cd49da57f384ab Mon Sep 17 00:00:00 2001 From: amenkov Date: Thu, 3 Mar 2011 15:41:44 +0300 Subject: [PATCH] 6938426: Concurrency bug in ALAW encoder causes random bursts of static/noise in output. Reviewed-by: stayer --- .../com/sun/media/sound/AlawCodec.java | 11 +- .../sampled/FileWriter/AlawEncoderSync.java | 113 ++++++++++++++++++ 2 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 test/javax/sound/sampled/FileWriter/AlawEncoderSync.java diff --git a/src/share/classes/com/sun/media/sound/AlawCodec.java b/src/share/classes/com/sun/media/sound/AlawCodec.java index 72c71e8da..bac6b9304 100644 --- a/src/share/classes/com/sun/media/sound/AlawCodec.java +++ b/src/share/classes/com/sun/media/sound/AlawCodec.java @@ -52,9 +52,6 @@ public class AlawCodec extends SunCodec { private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; - private static final int tempBufferSize = 64; - private byte tempBuffer [] = null; - /** * Initializes the decode tables */ @@ -199,12 +196,9 @@ public class AlawCodec extends SunCodec { AudioFormat inputFormat = stream.getFormat(); if( inputFormat.matches(outputFormat) ) { - cs = stream; } else { - cs = (AudioInputStream) (new AlawCodecStream(stream, outputFormat)); - tempBuffer = new byte[tempBufferSize]; } return cs; @@ -264,6 +258,10 @@ public class AlawCodec extends SunCodec { class AlawCodecStream extends AudioInputStream { + // tempBuffer required only for encoding (when encode is true) + private static final int tempBufferSize = 64; + private byte tempBuffer [] = null; + /** * True to encode to a-law, false to decode to linear */ @@ -303,6 +301,7 @@ public class AlawCodec extends SunCodec { encodeFormat = outputFormat; decodeFormat = inputFormat; PCMIsBigEndian = inputFormat.isBigEndian(); + tempBuffer = new byte[tempBufferSize]; } if (PCMIsBigEndian) { diff --git a/test/javax/sound/sampled/FileWriter/AlawEncoderSync.java b/test/javax/sound/sampled/FileWriter/AlawEncoderSync.java new file mode 100644 index 000000000..8d378a522 --- /dev/null +++ b/test/javax/sound/sampled/FileWriter/AlawEncoderSync.java @@ -0,0 +1,113 @@ +/** + * @test + * @bug 6938426 + * @summary Tests that Alaw encoder works properly in multithreaded environment + * @author Alex Menkov + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Arrays; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +public class AlawEncoderSync { + + static final int THREAD_COUNT = 20; + + static final AudioFormat pcmFormat = new AudioFormat(8000f, 16, 2, true, false); + static final int STREAM_LENGTH = 10; // in seconds + static byte[] pcmBuffer; + static final AudioFormat alawFormat + = new AudioFormat(AudioFormat.Encoding.ALAW, 8000f, 8, 2, 2, 8000f, false); + + static final ConversionThread[] threads = new ConversionThread[THREAD_COUNT]; + + public static void main(String[] args) { + preparePCMBuffer(); + log("pcmStream size: " + pcmBuffer.length); + + for (int i=0; i 0) { + throw new RuntimeException("test FAILED"); + } + log("test PASSED."); + } + + + static void preparePCMBuffer() { + pcmBuffer = new byte[STREAM_LENGTH * (int)pcmFormat.getSampleRate() + * (pcmFormat.getSampleSizeInBits() / 8) * pcmFormat.getChannels()]; + for (int i=0; i