简体   繁体   中英

How do I make my Java program stop capturing audio as soon as a certain frequency has been read?

I'm creating a guitar tuner in Java on the netbeans IDE and I want my program to stop capturing live audio as soon as a certain frequency has been read. This code below starts the audio capture but stops instantly. I want it to stop as soon as it reaches the frequency of the Low E string for example. I've used this website for help so far: https://docs.oracle.com/javase/tutorial/sound/capturing.html

//libraries
import static java.awt.SystemColor.info;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import static java.lang.System.in;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;


public class AudioInputPractice {

/**
 * @param args the command line arguments
 * @throws javax.sound.sampled.LineUnavailableException
 */
public int read(byte[] b, int off, int len) throws IOException{
            return in.read(b, off, len);
        }

public static void main(String[] args){
    
    System.out.println("Starting sound test...");
    
   
    //audio 
    try
    {
        TargetDataLine line;
        AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 4100, false);
      
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
        if (!AudioSystem.isLineSupported(info)) {System.err.println("Line not Supported");}
        line = (TargetDataLine)AudioSystem.getLine(info);
        line.open();
        
        
  
    
    ByteArrayOutputStream out= new ByteArrayOutputStream();
    int numBytesRead;
    byte[] data = new byte[line.getBufferSize() / 5];
    
    System.out.println("Starting recording...");
    
    line.start();
    
    numBytesRead = line.read(data, 0 , data.length);
    out.write(data, 0, numBytesRead);
    }
    catch (LineUnavailableException ex) 
    {
        System.out.println("Error");
    }
    
    
    
    }
}

The code you have only reads one buffer's worth of data!

The usual thing is to put the read command into a conditional while loop. For your condition, it can be something as simple as a boolean called isRunning . As you read the data, you will presumably be shipping it on to your pitch analyzer.

The Java Tutorials has an example of such a while loop in Using Files and Format Converters. It's the first major code quote in this article. A snippet is shown below. Reading from a TargetDataLine is similar to reading from an AudioInputStream as is done in the example.

// Set an arbitrary buffer size of 1024 frames.
int numBytes = 1024 * bytesPerFrame; 
byte[] audioBytes = new byte[numBytes];
try {
    int numBytesRead = 0;
    int numFramesRead = 0;
    // Try to read numBytes bytes from the file.
    while ((numBytesRead = 
        audioInputStream.read(audioBytes)) != -1) {
        // Calculate the number of frames actually read.
        numFramesRead = numBytesRead / bytesPerFrame;
        totalFramesRead += numFramesRead;
        // Here, do something useful with the audio data that's 
        // now in the audioBytes array...
    }
} catch (Exception ex) { 
  // Handle the error...
}

The condition in the while is handled differently here. Often a boolean is used instead, as I first suggested, especially in cases where one wishes to use loose coupling as the mechanism to open or close the spigot, so to speak.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM