I'm trying to capture audio that is coming from microphone and i wanted to check the frequency of sound. If I get a frequency greater then let's say : 1316.8 then I will start recording for 1 minute.
I am struggling with converting byte Data to Frequency.
I have used Javax.sound to capture audio that is coming from microphone and I have done the recording part as well.
AudioFormat format = new AudioFormat(44100, 16, 2, true, true);
DataLine.Info targetInfo = new DataLine.Info(TargetDataLine.class, format);
DataLine.Info sourceInfo = new DataLine.Info(SourceDataLine.class, format);
try {
TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(targetInfo);
targetLine.open(format);
targetLine.start();
SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(sourceInfo);
sourceLine.open(format);
sourceLine.start();
int numBytesRead;
byte[] targetData = new byte[targetLine.getBufferSize() / 5];
I expect the output to be like Frequency of every sound that is coming from microphone.
Related
I have a simple application that starts recording from the microphone and then immediately plays the sounds back to my headphones, however the problem here is: the sound quality is not good and there is a lasting echo after speaking something in the microphone which can last up to 5 seconds after speaking. I'm not sure whether the problem lies in the Java Sound API and I need to switch to another library.
I also want to mention that I use a headphone that is plugged into my computer. When I use low volume then the sound plays normal however when I turn it up to 90% of my maximum value the sound quality really becomes bad.
Here is my code:
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine mic = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
mic.open();
mic.start();
DataLine.Info dataLineInfo2 = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine speakers = (SourceDataLine) AudioSystem.getLine(dataLineInfo2);
speakers.open();
speakers.start();
byte[] buffer = new byte[1024];
while(true) {
mic.read(buffer, 0, buffer.length);
speakers.write(buffer, 0, buffer.length);
}
I'm trying to capture the sound of the PC. I have managed to capture the sound that enters the microphone through TargetDataLine, but I cannot find the way to capture the sound that comes out of the speakers.
I've been watching the mixer but I have not managed to capture the sound. I would like to know if someone has done it and if you can give me some clue as to where to start.
Although, your question is not really according to the "rules", here is a code snippet:
private byte[] record() throws LineUnavailableException {
AudioFormat format = AudioUtil.getAudioFormat(audioConf);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
// Checks if system supports the data line
if (!AudioSystem.isLineSupported(info)) {
LOGGER.error("Line not supported");
System.exit(0);
}
microphone = (TargetDataLine) AudioSystem.getLine(info);
microphone.open(format);
microphone.start();
LOGGER.info("Listening, tap enter to stop ...");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int numBytesRead;
byte[] data = new byte[microphone.getBufferSize() / 5];
// Begin audio capture.
microphone.start();
// Here, stopped is a global boolean set by another thread.
while (!stopped) {
// Read the next chunk of data from the TargetDataLine.
numBytesRead = microphone.read(data, 0, data.length);
// Save this chunk of data.
byteArrayOutputStream.write(data, 0, numBytesRead);
}
return byteArrayOutputStream.toByteArray();
}
Get more info from here:
https://www.programcreek.com/java-api-examples/?class=javax.sound.sampled.TargetDataLine&method=read
I'm capturing guitar audio notes (same format and conditions in both cases), with Java Sound API and the Adobe Audition Software, same parameters in both. As a result, they (the recording) should be also the same in both ones, but, I'm getting a difference in the spectrum form.
The audio format values are:
sample rate = 8000
sample size in bits = 16
channel = 1
This is basically the code I have used with the API: (replacing the corresponding AudioFormat values)
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
public class TestMic {
public static void main(String[] args) {
AudioFormat format = new AudioFormat(44100, 16, 2, true, true);
DataLine.Info targetInfo = new DataLine.Info(TargetDataLine.class, format);
DataLine.Info sourceInfo = new DataLine.Info(SourceDataLine.class, format);
try {
TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(targetInfo);
targetLine.open(format);
targetLine.start();
SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(sourceInfo);
sourceLine.open(format);
sourceLine.start();
int numBytesRead;
byte[] targetData = new byte[targetLine.getBufferSize() / 5];
while (true) {
numBytesRead = targetLine.read(targetData, 0, targetData.length);
if (numBytesRead == -1) break;
sourceLine.write(targetData, 0, numBytesRead);
}
}
catch (Exception e) {
System.err.println(e);
}
}
}
Then, when I applied the fourier transform, I'm obtaining next values, this is the array generated with the Adobe Software:
graphics are also different:
With the Adobe Audition:
graphic adobe audition
With the Java Sound API:
graphic java sound
Why is this happening?
i'm trying to capture/play audio with java in linux with pulseaudio server.
there's no problem with playing.
i can open capture device (microphone) but when calling micro.available returns 0 forever.
any tip ?
audioFormat = new AudioFormat(44100, 16, 2, true, false);
targetInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
sourceInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
targetDataLine = (TargetDataLine) AudioSystem.getTargetDataLine(audioFormat);
targetDataLine.open();
targetDataLine.start();
sourceDataLine = (SourceDataLine) AudioSystem.getLine(sourceInfo);
sourceDataLine.open(audioFormat);
The problem is in the sun jdk. With openjdk it works.
i am using tritonous package for audio encoding in ogg-vorbis. I face a problem when i am giving the audio format.
Unsupported conversion: VORBIS 44100.0Hz, unknown bits per sample, mono, unknown frame size, from PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian
This is my code where i am specifying the format
File outputFile = new File(userDir+"//San"+"_"+strFilename + ".spx");
// Using PCM 44.1 kHz, 16 bit signed,stereo.
if(osName.indexOf("win") >= 0){
System.out.println("windows");
audioFormat = getWindowsAudioFormat();
sampleRate = 44100.0F;
}else {
System.out.println("mac");
audioFormat = getMacAudioFormat();
sampleRate = 44100.0F;
}
AudioFormat vorbisFormat = new AudioFormat(VORBIS,
sampleRate,
AudioSystem.NOT_SPECIFIED,
1,
AudioSystem.NOT_SPECIFIED,
AudioSystem.NOT_SPECIFIED,
false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
TargetDataLine targetDataLine = null;
AudioFileFormat.Type fileType = null;
File audioFile = null;
fileType = VORBIS;
try
{
targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
targetDataLine.open(audioFormat);
}
catch (LineUnavailableException e)
{
System.out.println("unable to get a recording line");
e.printStackTrace();
System.exit(1);
}
AudioInputStream ais = new AudioInputStream(targetDataLine);
ais = AudioSystem.getAudioInputStream(vorbisFormat, ais);
final Recorder recorder = new Recorder(targetDataLine,ais,fileType,outputFile);
int number = 0;
System.out.println("Recording...");
recorder.start();
I wrote a utility class to encode OGG Vorbis audio files from Java, using the xiph Java ports of libogg and libvorbis.
https://github.com/xjmusic/java-vorbis-encoder/blob/master/VorbisEncoder.java