Whole document tree Chapter 5Capturing AudioCapturing refers to the process of obtaining a signal from outside the computer. A common application of audio capture is recording, such as recording the microphone input to a sound file. However, capturing isn't synonymous with recording, because recording implies that the application always saves the sound data that's coming in. An application that captures audio doesn't necessarily store the audio. Instead it might do something with the data as it's coming in-such as transcribe speech into text-but then discard each buffer of audio as soon as it's finished with that buffer. As discussed in Chapter 2, "Overview of the Sampled Package," a typical audio-input system in an implementation of the JavaTM Sound API consists of:
TargetDataLine consists of:
Setting Up a TargetDataLineThe process of obtaining a target data line was described in Chapter 3, "Accessing Audio System Resources," but we repeat it here for convenience: You could instead invoke Mixer's getLine method, rather than AudioSystem's .
As shown in this example, once you've obtained a target data line, you reserve it for your application's use by invoking the void open(AudioFormat format, int bufferSize)When choosing a buffer size, keep in mind the tradeoff between the delays incurred by long buffers, on the one hand, and the risk of discontinuities in the audio if the buffers are so short that you can't retrieve the data fast enough, on the other hand. When capturing audio, you risk data overflow if you don't pull data from the filled buffers fast enough. If overflow occurs, some of the captured data will be discarded, which will probably cause audible clicks and skips in the sound. This is the opposite situation from playback, where you risk data underflow, which can result in gaps in the sound. (See Chapter 4, "Playing Back Audio," for more on choosing buffer sizes.) Reading the Data from the TargetDataLine
Once the line is open, it is ready to start capturing data, but it isn't active yet. To actually commence the audio capture, use the
To start retrieving data from the buffer, invoke This method attempts to readint read(byte[] b, int offset, int length) length bytes of data into the array b , starting at the byte position offset in the array. The method returns the number of bytes actually read.
As with To avoid having your application hang during recording, you can invoke the read method within a loop, until you've retrieved all the audio input, as in this example: Notice that in this example, the size of the byte array into which the data is read is set to be one-fifth the size of the line's buffer. If you instead make it as big as the line's buffer and try to read the entire buffer, you need to be very exact in your timing, because data will be dumped if the mixer needs to deliver data to the line while you are reading from it. By using some fraction of the line's buffer size, as shown here, your application will be more successful in sharing access to the line's buffer with the mixer.// Assume that the TargetDataLine, line, has already // been obtained and opened. ByteArrayOutputStream out = new ByteArrayOutputStream(); int numBytesRead; byte[] data = new byte[line.getBufferSize() / 5]; // Begin audio capture. line.start(); // Here, stopped is a global boolean set by another thread. while (!stopped) { // Read the next chunk of data from the TargetDataLine. numBytesRead = line.read(data, 0, data.length); // Save this chunk of data. out.write(data, 0, numBytesRead); }
The
Typically, you read data from the line in a loop, as in this example. Within the
As with a source data line, it's possible to drain or flush a target data line. For example, if you're recording the input to a file, you'll probably want to invoke the There might be some cases where you instead want to flush the data. In any case, if you neither flush nor drain the data, it will be left in the mixer. This means that when capture recommences, there will be some leftover sound at the beginning of the new recording, which might be undesirable. It can be useful, then, to flush the target data line before restarting the capture. Monitoring the Line's Status
Because the Processing the Incoming AudioLike some source data lines, some mixers' target data lines have signal-processing controls, such as gain, pan, reverb, or sample-rate controls. The input ports might have similar controls, especially gain controls. For more information on how to determine whether a line has such controls, and how to use them if it does, see Chapter 6, "Processing Audio with Controls." [Top] [Prev] [Next] [Bottom] Copyright © 2000, Sun Microsystems Inc. All rights reserved. |