1

I am feeding audio from an electric cello into the mic port on my computer, and I would like my program to understand when no audio is being inputted and if audio is being inputted, what note/frequency is being played.

I am able to get the cello to play through the targetdataline and out to the sourcedataline in java. I also implemented a live frequency detection portion using fft according to Java: How to get current frequency of audio input?, but it doesn't work that well with the cello. It does perform somewhat well when I whistle, however.

I would appreciate any guidance into understanding how to use the information gained by the targetdataline and the cello output to see what is being played. Alternative approaches such as using different applications are welcome.

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;
}

Using this fft on the cello input has not given good results. I think I can detect when no input is being played by checking the magnitude of the biggest frequency and see if it passes a threshold, but that is future work.

  • Is there a significant volume difference between when the cello is and isn't playing? If so, you can use an root-mean-square type of algorithm to check the volume level and react. But if you are getting a lot of background noise (playing live with a band?) then IDK. But very cool getting the basic path working, and getting an FFT working in real time. I hope to try this too, at some point. Also, you might try asking at https://dsp.stackexchange.com/ since the coding part is less a problem here than figuring out a good DSP strategy. – Phil Freihofner May 15 '19 at 20:47
  • Yes there's a significant difference in volume, so checking when the cello is being played from the targetdataline won't be too hard. There shouldn't be much background noise since the cello has a guitar output that plugs into the computer. I will try to display the frequencies live similar to this video: https://youtu.be/q9cRZuosrOs. I'll ask in the dsp section as well. Thanks for the help! – Jebin Joseph May 15 '19 at 22:12
  • Just curious, are you also the cellist? Also, I recommend/request that you post a link to your reposting this question in the dsp area. – Phil Freihofner May 16 '19 at 03:11
  • Yes :). I got it to display the frequencies. If you would like the code let me know. The pitch detection works well when plucking the strings, but when using the bow, multiple frequency peaks occur, so accuracy is very low. Consequently, I won't be posting this to the DSP section.The goal was to play different instruments by getting the note from the cello, but I may just end up getting a roli seaboard. – Jebin Joseph May 18 '19 at 22:44

0 Answers0