package audio;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
/**
* @author Basis: http://jvalentino2.tripod.com/dft/index.html
*
*/
public class AmplitudeAndFrequencyAnalyserMy {
private static final int EXTERNAL_BUFFER_SIZE = 1280000; // Space to store
// Sound
File soundFile = new File("sample.wav");
AudioFormat soundFormat = new AudioFormat(1200, 8, 2, true, false);
public static void main(String[] args) {
AmplitudeAndFrequencyAnalyserMy fa = new AmplitudeAndFrequencyAnalyserMy();
while (true) {
fa.record();
// fa.analyze();
}
}
public void record() {
byte[] voiceData = new byte[800];// Run time and accuracy appear to be
// dependent on this
// 250: completes 20 samples in 8.95 seconds
// 300: completes 20 samples in 9.40 seconds
try {
DataLine.Info info = new DataLine.Info(TargetDataLine.class,
soundFormat);
TargetDataLine targetDataLine = (TargetDataLine) AudioSystem
.getLine(info);
targetDataLine.open(soundFormat);
targetDataLine.start();
AudioInputStream linearStream = new AudioInputStream(targetDataLine);
linearStream.read(voiceData, 0, voiceData.length);
analyzeArray(voiceData);
targetDataLine.stop();
targetDataLine.close();
ByteArrayInputStream baiStream = new ByteArrayInputStream(voiceData);
AudioInputStream aiStream = new AudioInputStream(baiStream,
soundFormat, voiceData.length);
AudioSystem.write(aiStream, AudioFileFormat.Type.WAVE, soundFile);
aiStream.close();
baiStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void analyze() {
AudioInputStream audioInputStream = null;
try {
// Load the Audio Input Stream from the file:
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
SourceDataLine line = null; // Handle opening the line
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
soundFormat);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(soundFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
writeSoundToByteArray(audioInputStream, line, abData);
// Calculate the sample rate:
float sample_rate = soundFormat.getSampleRate();
// System.out.println("sample rate = "+sample_rate);
// Calculate the length in seconds of the sample:
float T = audioInputStream.getFrameLength()/soundFormat.getFrameRate();
// System.out.println("T = "+T+" (length of sampled sound in seconds)");
// Calculate the number of equidistant points in time:
int n = (int) (T * sample_rate) / 2;
// System.out.println("n = "+n+" (number of equidistant points)");
// Calculate the time interval at each equidistant point:
float h = (T / n);
// System.out.println("h = "+h+" (length of each time interval in seconds)");
// Determine the original Endian encoding format:
boolean isBigEndian = soundFormat.isBigEndian();
// this array is the value of the signal at time i*h:
int x[] = new int[n];
// convert each pair of byte values from the byte array to an Endian
// value:
for (int i = 0; i < n * 2; i += 2) {
int b1 = abData[i];
int b2 = abData[i + 1];
if (b1 < 0)
b1 += 0x100;
if (b2 < 0)
b2 += 0x100;
int value;
// Store the data based on the original Endian encoding format:
if (!isBigEndian)
value = (b1 << 8) + b2;
else
value = b1 + (b2 << 8);
x[i / 2] = value;
}
double highfrequency = 0; // Will store frequency at highest amplitude
double highamplitude = 0; // Will store highest amplitude
// do the DFT for each value of x sub j and store as f sub j:
double f[] = new double[n / 2];
for (int j = 0; j < n / 2; j++) {
double firstSummation = 0;
double secondSummation = 0;
for (int k = 0; k < n; k++) {
// Whole bunch of complicated math:
double twoPInjk = ((2 * Math.PI) / n) * (j * k);
firstSummation += x[k] * Math.cos(twoPInjk);
secondSummation += x[k] * Math.sin(twoPInjk);
}
// Quadratwurzel:
f[j] = Math.abs(Math.sqrt(Math.pow(firstSummation, 2)
+ Math.pow(secondSummation, 2)));
double amplitude = 2 * f[j] / n;
double frequency = j * h / T * sample_rate;
// Added so number of printed lines isn't insane:
if (frequency > 100) {
if (frequency < 1000) {
if (amplitude > highamplitude) {
// Stores frequency and amplitude if new amplitude is
//higher than the record
highfrequency = frequency;
highamplitude = amplitude;
}
} else
break; // If the frequency gets high, this breaks so it
// doesn't go on forever
}
}
lautstaerkeErmitteln(highfrequency, highamplitude);
}
public void analyzeArray(byte[] abData) {
AudioInputStream audioInputStream = null;
// try {
// // Load the Audio Input Stream from the file:
// audioInputStream = AudioSystem.getAudioInputStream(soundFile);
// } catch (Exception e) {
// e.printStackTrace();
// System.exit(1);
// }
//
// SourceDataLine line = null; // Handle opening the line
// DataLine.Info info = new DataLine.Info(SourceDataLine.class,
// soundFormat);
//
// try {
// line = (SourceDataLine) AudioSystem.getLine(info);
// line.open(soundFormat);
// } catch (LineUnavailableException e) {
// e.printStackTrace();
// System.exit(1);
// } catch (Exception e) {
// e.printStackTrace();
// System.exit(1);
// }
// line.start(); //Start playing the sound (doesn't need to play)
// byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
// writeSoundToByteArray(audioInputStream, line, abData);
// Calculate the sample rate:
float sample_rate = soundFormat.getSampleRate();
// System.out.println("sample rate = "+sample_rate);
// Calculate the length in seconds of the sample:
// float T = (abData.length/soundFormat.getSampleSizeInBits()) /soundFormat.getSampleRate();
float T = 0.6666667f;
System.out.println("T = "+T+" (length of sampled sound in seconds)");
// Calculate the number of equidistant points in time:
int n = (int) (T * sample_rate) / 2;
// System.out.println("n = "+n+" (number of equidistant points)");
// Calculate the time interval at each equidistant point:
float h = (T / n);
// System.out.println("h = "+h+" (length of each time interval in seconds)");
// Determine the original Endian encoding format:
boolean isBigEndian = soundFormat.isBigEndian();
// this array is the value of the signal at time i*h:
int x[] = new int[n];
// convert each pair of byte values from the byte array to an Endian
// value:
for (int i = 0; i < n * 2; i += 2) {
int b1 = abData[i];
int b2 = abData[i + 1];
if (b1 < 0)
b1 += 0x100;
if (b2 < 0)
b2 += 0x100;
int value;
// Store the data based on the original Endian encoding format:
if (!isBigEndian)
value = (b1 << 8) + b2;
else
value = b1 + (b2 << 8);
x[i / 2] = value;
}
double highfrequency = 0; // Will store frequency at highest amplitude
double highamplitude = 0; // Will store highest amplitude
// do the DFT for each value of x sub j and store as f sub j:
double f[] = new double[n / 2];
for (int j = 0; j < n / 2; j++) {
double firstSummation = 0;
double secondSummation = 0;
for (int k = 0; k < n; k++) {
// Whole bunch of complicated math:
double twoPInjk = ((2 * Math.PI) / n) * (j * k);
firstSummation += x[k] * Math.cos(twoPInjk);
secondSummation += x[k] * Math.sin(twoPInjk);
}
// Quadratwurzel:
f[j] = Math.abs(Math.sqrt(Math.pow(firstSummation, 2)
+ Math.pow(secondSummation, 2)));
double amplitude = 2 * f[j] / n;
double frequency = j * h / T * sample_rate;
// Added so number of printed lines isn't insane:
if (frequency > 100) {
if (frequency < 1000) {
if (amplitude > highamplitude) {
// Stores frequency and amplitude if new amplitude is
//higher than the record
highfrequency = frequency;
highamplitude = amplitude;
}
} else
break; // If the frequency gets high, this breaks so it
// doesn't go on forever
}
}
lautstaerkeErmitteln(highfrequency, highamplitude);
}
private void writeSoundToByteArray(AudioInputStream audioInputStream,
SourceDataLine line, byte[] abData) {
int nBytesRead = 0; // Write the sound to an array of bytes
while (nBytesRead != -1) {
try {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
} catch (IOException e) {
e.printStackTrace();
}
if (nBytesRead >= 0) {
line.write(abData, 0, nBytesRead);
}
}
line.drain(); // close the line
line.close();
}
private void lautstaerkeErmitteln(double highfrequency, double highamplitude) {
String lautstaerke = "";
if (highamplitude < 500) {
lautstaerke = "leise";
} else if (highamplitude < 5000) {
lautstaerke = "mittel laut";
} else {
lautstaerke= "sehr laut";
}
// System.out.println(" Highest Amplitude is " + (int) highamplitude + " at Frequency " + (int) highfrequency);
System.out.println(lautstaerke + " bei der Frequenz " + (int) highfrequency + " (Amplitude ist " + (int) highamplitude + ")");
}
}