diff --git a/src/main/java/vavi/sound/sampled/nsf/Nsf2PcmAudioInputStream.java b/src/main/java/vavi/sound/sampled/nsf/Nsf2PcmAudioInputStream.java index a9f5cfe..e0ce670 100644 --- a/src/main/java/vavi/sound/sampled/nsf/Nsf2PcmAudioInputStream.java +++ b/src/main/java/vavi/sound/sampled/nsf/Nsf2PcmAudioInputStream.java @@ -110,6 +110,8 @@ public NSFOutputEngine(InputStream in, Map props) throws IOExcep /** the thread which executes buffer#take() */ private Thread blockingDequeThread; + private volatile boolean finished = false; + /** */ public void initialize(OutputStream out) throws IOException { if (this.out != null) { @@ -160,12 +162,7 @@ public void write(byte b) { public void finish() { blockingDequeThread.interrupt(); Debug.println(Level.FINE, "sink finish"); - try { - out.close(); // TODO wait write finished - } catch (IOException e) { - finish(); - throw new UncheckedIOException(e); - } + finished = true; } }); } catch (IOException e) { @@ -173,28 +170,21 @@ public void finish() { } }); - try { - // rendering is too slow, wait buffering - Thread.sleep(1000); - } catch (InterruptedException e) { - Debug.printStackTrace(e); - } - blockingDequeThread = Thread.currentThread(); } static final int BUFFER_SIZE = 16; - byte[] buf = new byte[BUFFER_SIZE]; - /** */ public void execute() throws IOException { try { int c = 0; - while (buffer.peek() != null || c++ < BUFFER_SIZE) { + while (buffer.peek() != null && c++ < BUFFER_SIZE) { out.write(buffer.take()); } - Thread.yield(); + if (finished) { + out.close(); + } //Debug.println(Level.FINER, "write: " + i + ", " + buffer.size()); } catch (InterruptedException e) { Debug.println(Level.FINE, "BlockingDeque#take() interrupted"); diff --git a/src/test/java/TestCase.java b/src/test/java/TestCase.java index e622852..846b74d 100644 --- a/src/test/java/TestCase.java +++ b/src/test/java/TestCase.java @@ -35,6 +35,8 @@ /** * TestCase. * + * clip takes a bit time for loading all, so not tested + * * @author Naohide Sano (umjammer) * @version 0.00 2012/06/11 umjammer initial version
*/ @@ -65,7 +67,7 @@ void setup() throws Exception { static int time = System.getProperty("vavi.test", "").equals("ide") ? 1000 : 10; @Test - @DisplayName("directly, clip takes a bit time for loading all") + @DisplayName("directly") void test0() throws Exception { Map props = new HashMap<>(); props.put("track", 5); @@ -84,22 +86,27 @@ void test0() throws Exception { AudioInputStream ais = new Nsf2PcmAudioInputStream(Files.newInputStream(Paths.get(inFile)), targetAudioFormat, -1); Debug.println(targetAudioFormat); - DataLine.Info info = new DataLine.Info(Clip.class, targetAudioFormat, AudioSystem.NOT_SPECIFIED); - CountDownLatch cdl = new CountDownLatch(1); - Clip clip = (Clip) AudioSystem.getLine(info); -Debug.println(clip.getClass().getName()); - clip.addLineListener(event -> { -Debug.println(event.getType()); - if (event.getType().equals(LineEvent.Type.STOP)) { - cdl.countDown(); - } - }); - clip.open(ais); - volume(clip, volume); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, targetAudioFormat, AudioSystem.NOT_SPECIFIED); + SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); + Debug.println(line.getClass().getName()); + line.addLineListener(event -> Debug.println(event.getType())); + Debug.println("buffer size: " + line.getBufferSize()); - clip.start(); - cdl.await(); - clip.close(); + line.open(targetAudioFormat); + volume(line, volume); + line.start(); + int r; + byte[] buf = new byte[line.getBufferSize()]; + while (true) { + r = ais.read(buf, 0, buf.length); + if (r < 0) { + break; + } +//Debug.println("line: " + line.available()); + line.write(buf, 0, r); + } + line.drain(); + line.close(); ais.close(); }