All I need is a peice of java code that can detect DTMF from microphone print out the characters to System.out. I've been searching forever and I couldn't find it.
Oracle Docs on Capturing Audio in Java:
http://docs.oracle.com/javase/tutorial/sound/capturing.html
As discussed in Overview of the Sampled Package, a typical audio-input system in an implementation of the Java Sound API consists of:
An input port, such as a microphone port or a line-in port, which feeds its incoming audio data into:
A mixer, which places the input data in:
One or more target data lines, from which an application can retrieve the data.
(Emphasis Mine)
Also see:
Java (J2SE) DTMF tone detection
I think usually this is done in hardware, so you may end up writing code yourself to analyze the audio you've captured.
Also:
http://sourceforge.net/projects/java-dtmf/
Related
I am very much confused about Streams.
1) Does OS(i.e Windows) provide a Common Standard Input Stream and all the languages use it(i.e. Java refers to it as System.in and same Standard Input Stream is referred with stdin in c)?
Is it like keyboard has some port or physical address and OS has stored that
in some variable and when a program needs that it will give that same address to stdin or System.in depending on the language?
OR,
2) Is it like each language has its own API written for standard streams and when we run the program, a stream will get connected to the input device?
And what information that stream would have apart from data? i.e. Physical Port or address of device or what?
Also, Please tell about what is the meaning of System.in get "connected" to program when we run it. what does "connected" mean here?
Please share some link.
Definitions
A “stream” is a catch-all word, like “window”. All a stream means is that there is some thing (a “device”) that produces sequential data or accepts sequential data.
For example, I can make a string into an input stream (produces data), by simply keeping track of what the next character to produce is. When we run out of characters, we've reached the end of the stream. C++:
struct my_hello_stream
{
static const char* s = "Hello world!";
int n;
my_stream(): n(0) {}
int get()
{
if (s[n]) return s[n++];
return EOF;
}
};
Abstractions
Every system has its own way of abstracting a stream. The OS does it through files, pipes and character devices, which you can open for reading or writing. How exactly this is done depends entirely on the design of the OS. Consult your OS API documentation.
On top of that sits a programming language, like C or C++ or Java or FORTRAN — you name it. The programming language itself also defines a stream in a way convenient for the users of that language. In C you have a FILE*. In C++ you have std::iostreams. In Java you have I/O streams. Whatever the case, this works above the OS stream to read and write data from and to files, etc.
Moreover, these language features often allow you to do more powerful things with these stream interfaces, such as convert the character sequence 1234567 into a native integer value, and to perform these operations over strings.
Beyond that, there are also external libraries that allow us to treat things like internet connections and port connections with the printer like a stream. Some of this stuff the OS handles for us. Some of it it doesn't.
tl;dr
It all depends. What matters is the abstraction you have access to — which is typically your programming language. Hence, read about how your programming language expects you to open a file and read and write data, then act as if that is right. Whatever else actually happens underneath is magic.
What is a stream?
Stream is an abstraction which is either an input source or an output destination. In UNIX for example everything is a file so your keyboard will be represented by a read only file (why?). Whenever you want to read something from keyboard you just use the read system call using the keyboard file as parameter.
Does OS(i.e Windows) provide a Common Standard Input Stream and all
the languages use it(i.e. Java refers to it as System.in and same
Standard Input Stream is referred with stdin in c)?
OS only provides the very basic functionality such as read and write system calls (OS dependent) which can be used to read and write raw bytes. All the programming languages use this basic functionality to create abstractions (such as translating raw bytes to certain character set or buffering the data before writing).
When the program starts executing operating systems opens three standard text stream (channel) automatically and provides constant file pointer for them.
The stream you can think as like a channel, rather than a standard stream we have to open a stream by some library functions like fopen in c, which creates a stream bw your program and the file specified.
I'm trying to record from the microphone to a wav file as per this example. At the same time, I need to be able to test for input level/volume and send an alert if it's too low. I've tried what's described in this link and seems to work ok.
The issue comes when trying to record and read bytes at the same time using one TargetDataLine (bytes read for monitoring are being skipped for recording and vice-versa.
Another thing is that these are long processes (hours probably) so memory usage should be considered.
How should I proceed here? Any way to clone TargetDataLine? Can I buffer a number of bytes while writing them with AudioSystem.write()? Is there any other way to write to a .wav file without filling the system memory?
Thanks!
If you are using a TargetDataLine for capturing audio similar to the example given in the Java Tutorials, then you have access to a byte array called "data". You can loop through this array to test the volume level before outputting it.
To do the volume testing, you will have to convert the bytes to some sort of sensible PCM data. For example, if the format is 16-bit stereo little-endian, you might take two bytes and assemble to either a signed short or a signed, normalized float, and then test.
I apologize for not looking more closely at your examples before posting my "solution".
I'm going to suggest that you extend InputStream, making a customized version that also performs the volume test. Override the 'read' method so that it obtains the byte that it returns from the code you have that tests the volume. You'll have to modify the volume-testing code to work on a per-byte basis and to pass through the required byte.
You should then be able to use this extended InputStream as an argument when you create the AudioInputStream for the output-to-wav stage.
I've used this approach to save audio successfully via two data sources: once from an array that is populated beforehand, once from a streaming audio mix passing through a "mixer" I wrote to combine audio data sources. The latter would be more like what you need to do. I haven't done it from a microphone source, though. But the same approach should work, as far as I can tell.
I've a stream with contains a audio/video stream. The video encoding is H.264 AVC and the audio encoding is G.711 µ-law (PCMU). (I have no control over the output format.)
When I try to display the video into a VideoView frame, the device says that it cannot play the video. I guess that's because Android doesn't support the aforementioned audio encoding.
Is there a way to somehow display the selected stream in the VideoView?
Can I just use a Java code snippet to 'compute' the codec? I've seen the class android.net.rtp.AudioCodec, which contains a field PCMU, and I can imagine that class would be useful.
Or do I have to insert a library or some native code (FFmpeg) into my application and use that? If yes, how?
How to fix it?
If you want to manipulate a stream before you display it, you are unfortunately getting into tricky territory on an Android device - if you do have any possibility of doing the conversion on the serve side it will likely by much easier (and you should also usually have more 'horsepower' on the server side).
Assuming that you do need to convert on the server side, then a technique you can use is to stream the video from the server to your app, convert it as needed and then 'stream' from a localhost server in your app to a VideoView in your app. Roughly the steps are:
Stream the encrypted file from the server as usual, 'chunk by chunk'
On your Android device, read from the stream and convert each chunk as it is received
Using a localhost http server on your Android device, now 'serve' the converted chunks to the MediaPlayer (the media player should be set up to use a URL pointing at your localhost http server)
An example of this approach, I believe, is LibMedia: sure: http://libeasy.alwaysdata.net (note, this is not a free library, AFAIK).
For the actual conversion you can use ffmpeg as you suggest - there are a number of ffmpeg wrapper for Android projects that you can either use or look at to design your own. Some examples:
http://hiteshsondhi88.github.io/ffmpeg-android-java/
https://github.com/jhotovy/android-ffmpeg
Take a look at the note about libffmpeginvoke in the second link in particular if you are planning to write your won wrapper.
One thing to be aware of is that compressions techniques, in particular video compression, often use an approach where one packet or frame is compressed relative to the frames before it (and sometimes even the frames after it). For example the first frame might be a 'key frame', the next five frames might just contain data to explain how they differ from the key frame, and the the seventh frame might be another key frame and so on. This means you generally want a 'chunk' which has all the required key frames if you are converting the chunk from one format to another.
I don't think you will have this problem converting from PCM to AAC audio, but it useful to be aware of the concept anyway.
So, I went over the Java's sound tutorial and I did not find it all so helpful.
Anyways, what I understood from the tutorial for recording sound from a mic is this:
Although they do show how to get a target data line and so on, they do not tell how you can actually record sound [or maybe I didn't get it all well].
My understanding so far has been this:
Mixer can be your sound card or sound software drivers that can be used to process the sound, whether input or output
TargetDataLine is used when you want to output your sound into the computer. Like save it to the disk
Port is where your external devices like mic, etc are connected
Problems that remain
How do I select the proper mixer? Java's tut says that you get all the available mixers and query each one to see if it has what you want. That's quite vague for a beginner
How do I get the port on which my integrated mic is? Specifically, how do I get input from it into the mixer?
How do I output this to the disk?
Using the AudioSystem.getTargetDataLine(AudioFormat format) method you will get
... a target data line that can be used for recording audio data in the format specified by the AudioFormat object. The returned line will be provided by the default system mixer, or, if not possible, by any other mixer installed in the system that supports a matching TargetDataLine object.
See the accepted answer for Java Sound API - capturing microphone for an example of this.
If you want more control of which data line to use you can enumerate all the mixers and the data lines they support and pick the one you want. Here is some more information regarding how you would go about doing that: Java - recording from mixer
Once you've obtained the TargetDataLine you should open() it, and then call read() repeatedly to obtain data from that data line. The byte[] that you fill up with data with each call to read() can be written to disk e.g. through a FileOutputStream.
I've written a program that transmits a PCM stream from my pc to another pc or my android(using an AudioTrack). It uses java sound and takes the target and source lines from the Stereo Mix mixer. Everything technically works (sockets, mixers, lines, streams, buffers, etc.) but the output on the remote speakers is very static-y sounding. Even when there isn't sound coming through, there is a constant crackling sound. I've tested the programs on my phone and computer with the same result.
What can I do?
Thanks,
Bill
ps The code is pretty big, and kinda messy, but I can post it somewhere if you ask.
Typically the static means you're feeding incorrect data to the audio subsystem: given what you describe there's probably an error in the audio path, and I'd suspect you are either:
Experiencing some byte alignment issue when reading/transmitting/receiving the audio data from the source.
Inadvertently mixing your network stream with local loopback audio on the receiving end.
Feeding in invalid silence data (for sound subsystems that need to be constantly fed with audio data).
Not feeding in silence data when you should be.