Я подаю звук с электрической виолончели в порт микрофона на моем компьютере, и я хотел бы, чтобы моя программа понимала, когда звук не вводится и если вводится звук, какая нота / частота воспроизводится.
Я могу заставить виолончель играть через targettdataline и выйти на sourcedataline в java. Я также реализовал часть определения живой частоты, используя fft в соответствии с Java: Как получить текущую частоту аудиовхода? , но с виолончелью это не так хорошо работает. Тем не менее, когда я свистлю, он работает довольно хорошо.
Я был бы признателен за любые советы по пониманию того, как использовать информацию, полученную targettdataline, и выход виолончели, чтобы увидеть, что на ней играют. Альтернативные подходы, такие как использование различных приложений, приветствуются.
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
try {
//making SourceDataLine for writing
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
final SourceDataLine sourceLine = (SourceDataLine)AudioSystem.getLine(info);
sourceLine.open(format/*, #*/);
//#5800 is the smallest i got it to work so far
//making TargetDataLine for getting in
info = new DataLine.Info(TargetDataLine.class, format);
final TargetDataLine targetLine = (TargetDataLine)AudioSystem.getLine(info);
targetLine.open(format);
final byte[] buf = new byte[2048]; // <--- increase this for higher frequency resolution
final int numberOfSamples = buf.length / format.getFrameSize();
final JavaFFT fft = new JavaFFT(numberOfSamples);
Thread liveThread = new Thread() {
@Override public void run() {
int readBytes;
try {
while(true) {
readBytes = targetLine.read(buf, 0, buf.length);
sourceLine.write(buf, 0, readBytes);
final float[] samples = decode(buf, format);
final float[][] transformed = fft.transform(samples);
final float[] realPart = transformed[0];
final float[] imaginaryPart = transformed[1];
final double[] magnitudes = toMagnitudes(realPart, imaginaryPart);
System.out.println("length" + magnitudes.length);
System.out.println(ecello.findMaxMagnitude(magnitudes));
}
}
catch(Exception e) {
e.printStackTrace();
}
}
};
targetLine.start();
sourceLine.start();
liveThread.start();
System.out.println("Started recording...");
Thread.sleep(3000000);
targetLine.stop();
targetLine.close();
System.out.println("Ended recording");
System.exit(0);
}
catch(Exception e) {
e.printStackTrace();
}
}
private int findMaxMagnitude(double[] input){
//Calculates Maximum Magnitude of the array
double max = input[0];
double temp;
int index = 0;
for(int i = 1; i<input.length; i++){
temp = input[i];
if(temp>max){
max = temp;;
index = i;
}
}
return index;
}
Использование этого fft на входе для виолончели не дало хороших результатов. Я думаю, что могу определить, когда не воспроизводится никакой вход, проверяя величину самой большой частоты и посмотреть, не превышает ли это пороговое значение, но это будущая работа.