Программирование аудио входа - PullRequest
1 голос
/ 22 августа 2011

То, с чем я играю, выходит за рамки обычного программирования, которое я делаю, поэтому я решил спросить, прежде чем тратить больше времени.

Таким образом, в основном у меня есть кнопка (обычно находится на переключателе ВКЛ / ВЫКЛ компьютера), и, используя свои не столь обширные знания в области электроники, я подключил ее к стандартному аудиокабелю (который, конечно, подключен к аудиосистеме моего компьютера в Джек). Посредством Audacity я обнаружил, что когда я нажимаю кнопку, создается звуковая волновая форма.

Это все очень простые вещи, я оставил свой Arduino у родителей, поэтому в отчаянии решил использовать свою звуковую карту в качестве микроконтроллера.

Во всяком случае, я уверен, что вы все знаете, куда я иду с этим. Как я могу приступить к программированию небольшого приложения, которое запускается из командной строки (для тестирования) и в качестве фонового процесса, который будет отслеживать и обрабатывать информацию, поступающую от ввода, для выполнения определенной задачи (например, блокировка моего компьютера или открытие Firefox и т. Д.). .)

Я работаю с Java как часть моей степени по вычислительной технике (мы все еще изучаем очень простые вещи ... отсюда и вопрос), а также ежедневно работаю с PHP, поэтому я не против изучения нового языка если я должен.

Ответы [ 2 ]

1 голос
/ 22 августа 2011

В итоге я понял это для себя. В основном это так же просто, как прослушивание входной строки, а затем запуск метода, если амплитуда звука достигает определенной величины. В ходе тестирования я также обнаружил, что амплитуда измеряется в отрицательных числах при нажатии кнопки, и при отпускании кнопки регистрируется положительная амплитуда. Это означает, что вы можете написать код для этих отдельных событий, и если вы достаточно умны, вы также можете добавить событие для удержания кнопки с помощью интервального таймера.

В любом случае вот код (к сожалению, у меня не было времени его прокомментировать):

AudioInputButton.java

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.Mixer.Info;


public class AudioInputButton {
  private int line;
  private AudioFormat format;
  private Info[] lines;
  private TargetDataLine inputLine;
  private DataLine.Info inInfo;
  private int bufferSize;

  public AudioInputButton(int line){
    this.line = line;
    this.setup();
  }

  public AudioInputButton(){
    this.line = 2;
    this.setup();
  }

  private void setup(){
    format = new AudioFormat(8000, 8, 1, true, true); 
    lines = AudioSystem.getMixerInfo();    
    inInfo = new DataLine.Info(TargetDataLine.class, format);
    bufferSize = (int) format.getSampleRate() * format.getFrameSize();
  }

  public void printLineInfo(){
    for (int i = 0; i < lines.length; i++){
      System.out.println(i+": "+lines[i].getName()+"\n"+lines[i].getDescription());
    }
  }

  public void startListening(){
    try{
      inputLine = (TargetDataLine)AudioSystem.getMixer(lines[line]).getLine(inInfo);
      inputLine.open(format, bufferSize);
      inputLine.start(); 

      byte[] buffer = new byte[bufferSize];

      System.out.println("Listening on line " +line+", " + lines[line].getName() + "...");

      while(true){
        inputLine.read(buffer,0,buffer.length);
        int sample = listen(buffer);
        if(sample > 0){
          onClick();
        }
      }
    }catch (LineUnavailableException e){
      System.out.println("Line " + line + " is unavailable.");
      e.printStackTrace();
      System.exit(1);
    }
  }

  public int listen(byte[] eightBitByteArray)
  {
    int index = 0;
    int ret = 0;
    boolean down = false;
    boolean up = false;
    for (int audioByte = 0; audioByte < eightBitByteArray.length;)
    {
      int low = (int) eightBitByteArray[audioByte];
      audioByte++;
      int high = (int) eightBitByteArray[audioByte];
      audioByte++;
      int sample = (high << 8) + (low & 0x00ff);
      if(sample < -1100){
        if(!down){
          onDown();
          ret = sample;
          down = true;
        }
      }else if(sample > 1100){
        if(!up){

          onUp();
          ret = sample;
          down = false;
          up = true;
        }
      }
      index++;
    }
    return ret;
  }

  private void onClick(){
    System.out.println("Click!");
  }

  private void onDown(){
    System.out.println("Down!");
  }

  private void onUp(){
    System.out.println("Up");
  }
}

AudioInputButtonTester.java

public class AudioInputButtonTester {
  public static void main (String [] args){
    AudioInputButton myButton = new AudioInputButton(2);
    myButton.startListening();
  }
}

Я собирался превратить различные состояния кнопок в события, чтобы вы могли написать свой код для них в классе тестера, но в 2:30 ночи, и если вы действительно хотите отделить свою логику, создайте новый класс кнопок, который расширяет AudioInputButton с вашим собственным кодом.

0 голосов
/ 22 августа 2011

Я думаю, эту задачу можно стандартизировать или упростить с помощью COM-порта .

Посмотрите эти примеры http://www.java2s.com/Code/Java/Development-Class/COM-Port.htm http://java.sun.com/developer/Books/javaprogramming/cookbook/11.pdf

Если вы хотите выполнить свою задачу с помощью аудиовхода (входной порт микрофона), вам необходимо проверить уровень входного звукаамплитуда и выполнить свою задачу в соответствии с уровнем интенсивности.Для этого вы должны получить представление о многопоточности и записи звука в JAVA

...