Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to use TargetDataLine.drain()?

829497Feb 9 2012 — edited Feb 12 2012
Hey there,

I have a question regarding a specific problem. I need to give some code to explain:
public class Recorder {
    private final TargetDataLine line;
    private final ByteArrayOutputStream data;
    

    public Recorder(AudioFormat format) throws LineUnavailableException {
        DataLine.Info lineInfo = new DataLine.Info( TargetDataLine.class,
                                                    format);
        line = (TargetDataLine)AudioSystem.getLine(lineInfo);
        data = new ByteArrayOutputStream();
    }
    

    public void start() throws LineUnavailableException {
        line.open();
        line.start();


        new Thread() {
            @Override
            public void run() {
                byte[] buffer = new byte[line.getFormat().getFrameSize()];
                while(line.isOpen()) {
                    if(0 != line.read(buffer, 0, buffer.length)) {
                        System.out.println("Writing data.");
                        try {
                            data.write(buffer);
                        }
                        catch(IOException ex) {
                        }
                    }
                    else {
                        System.out.println("NOT writing data.");
                    }
                }
            }
        }.start();
    }
    
    
    public void stop() {
        line.stop();
        System.out.println("Available after stop(): " + line.available());
        line.drain();
        System.out.println("Available after drain(): " + line.available());
        line.close();
        System.out.println("Available after close(): " + line.available());
        stopLineWatch();
    }
}
And here's the output that the code produces when start() and the stop() is invoked:
Writing data.
Writing data.
Writing data.
Available after stop(): 11024
Available after drain(): 11024
Available after close(): 0
NOT writing data.

Now here's the problem:
I don't want my Recorder class to end recording prematurely when Recorder.stop() is invoked. So the recording loop actually stops when the line gets closed so the line is supposed to be closed when no more data is available. Therefor I first stop the line to avoid that the lines internal buffer goes on being filled with more data. Then I invoke drain(), expecting that I will be able to go on reading from the line until there's no more data in its internal buffer. Unfortunately I am not able to go on reading from the line at all since read() always returns 0 after stop() has been invoked. I also expected drain() to block while there's more data to be read from the line. But drain() seems not to block at all as available returns a big number of leftover bytes and line.stop() is invoked immediately after line.drain().
So: How can I use drain() correctly to get all remaining data from the line?

Thanks in advance!
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 11 2012
Added on Feb 9 2012
2 comments
1,972 views