Как использовать байтовый массив, заданный targettdataline, для получения информации об аудио? - PullRequest
1 голос
/ 15 мая 2019

Я подаю звук с электрической виолончели в порт микрофона на моем компьютере, и я хотел бы, чтобы моя программа понимала, когда звук не вводится и если вводится звук, какая нота / частота воспроизводится.

Я могу заставить виолончель играть через 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 на входе для виолончели не дало хороших результатов. Я думаю, что могу определить, когда не воспроизводится никакой вход, проверяя величину самой большой частоты и посмотреть, не превышает ли это пороговое значение, но это будущая работа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...