This content has been marked as final. Show 36 replies
(This thread was meant to continue
captfoss wrote:It is giving me grief. I seem to be having problems in addition to what I noted above. How do I use AudioSystem.write without write waiting for the end up the input stream? If it doesn't return, I don't see a way to pause or reset the recording.
JMF isn't included by default in the JRE and hasn't been supported in 8 years... JavaSound is included in the JRE and, as such, is currently supported.
So you have the option of old, unsupported code that you'll have to handle packaging / linking with your code, or, you can use something built-in that'll work with applications, applets, and web-start apps.
So the ease of use of the language should be, honestly, the least important design consideration for a programmer, in this instance at least.
And to actually answer your question, no...neither of them are "easy" to understand...but JavaSound is built around the stream concept, so if you're familiar with using any sort of InputStream and OutputStream architecture, you have some background into JavaSound.
So, as a basic introduction to JavaSound...
To record a file in JavaSound, you copy data from a TargetDataLine to a file... to pause the recording, you simply continue to read the data from the TDL but discontinue writing it to the file...to rewind the recording, you simply seek backwards in the file and overwrite existing data...
And there are "helper" classes that you need to use. AudioInputStream must be used to handle the reading from and writing to a file. AudioSystem.write should be used to write an AudioInputStream to file... and you have to do some "tricks" with the AIS to be able to write (AIS can be constructed with an InputStream, and I like to use a PipedOutputStream->PipedInputStream->AudioInputStream ordering to be able to "write" to an AudioInputStream as it is an InputStream and you can't write directly to it).
To better understand what "lines" are, you should read the article I gave you...
To see those classes "in action", you should look at the sample code...
And if you're wanting to learn how the whole system works together, RTFM
Several of your questions are addressed by the following excellent article about JavaSound:
But you already know that because I've asked you to read it twice before ;-)
As for the blocking nature of AudioSystem.write, don't use that until you're ready to finalize the file... write your audio data into a temporary file first, and then when you're ready to save... attach an input stream to the temporary file, wrap that in an AudioInputStream, and hand the AIS to AudioSystem.write...
Will Pittenger wrote:You'd have to post some code for me to have anything to say... and please post it using the comment tags as described in the forum's "Welcome to the new home" sticky...
Unfortunately, there is a problem, I am having problems getting sound directly out of the line with AudioInputStream.read. Even though I opened the line and started the stream, both isRunning and isActive return false.
Will Pittenger wrote:I don't think the close event would cascade through the streams like that. It's possible you could be closing the input stream as a "pause" event.
Would closing an attached PipeInputStream cause AudioInputStream to tell AudioSystem.write to end? Or would AudioSystem.write need some other signal to write out the end of the file?
You should probably close the AIS itself to signal to the AudioSystem to finish out the file.
Did you ever figure out why I was unable to start the line in that code I posted? Since then, I have written a class that will go in our real program. (It isn't intended for that simple program I was demoing with.) You might look at it (http://pastebin.com/XihBncE9) and tell me if you see any problems. I am hoping I won't run into that line start problem here.
I should add some notes on that new code.
*The selectLine function was based loosely on code from http://www.vsj.co.uk/java/display.asp?id=370. One thing that has troubled me is how that sample used source lines to get a microphone port. But if I have my terminology right, it should be target line.
*The FileWriter inner class is based on your suggestion with the pipe streams.
I'm not sure that you're understanding a few key concepts...
TargetDataLines don't attach to anything, they come pre-attached to mixers. The same way SourceDataLines come attached to mixers, just on the other side.
Mixers dump into TDLs and you read from TDLs. You write to SDLs and they dump into Mixers.
Input ports (microphone, line in, etc) are equviolent to SDLs. They dump into a Mixer.
Output ports (speakers, line out, etc) are equivolent to TDLs. Mixers dump into them.
The difference is, you can't read or write directly from a port, you have to read/write from output/input associated with the Mixer it's attached to.
So, to "read" from a microphone port, you fine the port, get it's mixer, and get one of the TargetDataLines from the Mixer. If you need the microphone to feed into another Mixer, then you have to manually read data from the TDL on Mixer1 to the SDL on Mixer2...