【问题标题】:Audio Input Programming音频输入编程
【发布时间】:2011-08-22 08:40:51
【问题描述】:

我玩的东西超出了我通常的编程范围,所以我想在浪费更多时间之前先问一下。

所以基本上我有一个按钮(通常在计算机的 ON/OFF 开关上找到)并使用我不太丰富的电子知识将它连接到标准音频电缆(当然连接到我的计算机音频杰克)。通过 Audacity,我发现当我点击按钮时,会生成并拾取音频波形。

这些都是非常基本的东西,我把我的 Arduino 留在了我父母的地方,所以我绝望地决定使用我的声卡作为微控制器。

不管怎样,我相信你们都知道我要去哪里。 我怎样才能编写一个在命令提示符(用于测试)上运行的小应用程序,并作为一个后台进程来监视和处理来自输入的信息以执行某些任务(比如锁定我的计算机或打开 Firefox 等。 .)?

我使用 Java 作为我的计算机学位的一部分(我们仍在学习非常基本的东西......因此问题)并且每天都使用 PHP 工作,所以我不介意学习一门新语言如果必须的话。

【问题讨论】:

    标签: java c++ audio input


    【解决方案1】:

    我最终自己解决了这个问题。基本上它就像听输入线一样简单,然后如果音频的幅度达到一定量,则运行一个方法。通过测试我还发现,当按钮被按下时,振幅以负数测量,而当按钮被释放时,振幅被记录为正数。这意味着您可以为这些单独的事件编写代码,如果您足够聪明,您还可以通过使用间隔计时器添加一个事件,用于当按钮被按下时。

    这里是代码(遗憾的是我没有时间评论它):

    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 与您自己的代码。

    【讨论】:

      【解决方案2】:

      我认为,这个任务可以通过使用COM port 来标准化或简化。

      查看这些示例 http://www.java2s.com/Code/Java/Development-Class/COM-Port.htm http://java.sun.com/developer/Books/javaprogramming/cookbook/11.pdf

      如果您想使用音频输入插孔(麦克风输入端口)来完成任务,您必须检查声音幅度的输入级别并根据强度级别执行任务。为此,您必须了解 JAVA 中的多线程和录制声音

      【讨论】:

      • 是的,由于我的不耐烦,我最终找到了一种通过良好的旧 Java 来实现它的方法。我只是为了好玩才尝试这个。
      猜你喜欢
      • 2010-10-07
      • 2012-11-19
      • 2014-05-06
      • 2018-09-17
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多