2012-03-26 2 views
5

컴퓨터에 적절한 마이크가 연결되어 있지 않은지 감지하고 사용자에게 경고하는 간단한 캡처/재생 스윙 앱이 있습니다. 이 같은 백그라운드 스레드에서 호출자바 사운드 새로 고침 마이크를 연결 한 후 줄 목록

 com.sun.media.sound.JDK13Services.setCachingPeriod(0); 

    private static boolean isMicrophoneAvailable() { 
     try { 
      if (!AudioSystem.isLineSupported(Port.Info.MICROPHONE)) { 
       log.debug("NO MICROPHONE FOUND"); 
       return false; 
      } else { 
       log.debug("MICROPHONE FOUND"); 
       return true; 
      } 
     } catch (IllegalArgumentException e) { 
      log.debug("INCONSISTENT"); 
     } 
     return false; 
    } 

:

new Thread() { 
     public void run() { 
      while(!thisFrame.isClosed()){ 
       if(isMicrophoneAvailable() == true){ 
        //OK 
       }else{ 
        //WARN 
       } 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }).start(); 

문제가 있다는 것입니다 손보는 주위의 많은 후 나는 나를 새로 연결하거나 제거 마이크를 감지 할 수있는 유일한 솔루션을 발견했다 설명 된 방법을 사용하여 장치가 올바르게 감지 되더라도 기본 행 목록은 새로 고쳐지지 않습니다.

java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian is supported. 

상쾌의 AudioSystem의 라인 목록을 얻을 수있는 방법이 있나요 : 사운드를 녹음 할 때 그 프로그램이 시작될 때, 장치가 나중에, 다음과 같은 예외가 발생 부착? 캐싱을 피하기 위해 초기에 JDK13Services 해결 방법과 비슷한 것을 사용할 수 있습니까?

UPDATE : 예외가 발생 코드 :

 AudioFormat format = formatControls.getDefaultFormat(); 
     DataLine.Info info = new DataLine.Info(TargetDataLine.class,format); 
     try { 
      line = (TargetDataLine) AudioSystem.getLine(info); 
      line.open(format, line.getBufferSize()); 
     } catch (LineUnavailableException ex) { 
      shutDown("No audio input device available. Please make sure that a microphone is attached to your computer"); 
      return; 
     } catch (Exception ex) { 
      log.error(ex.toString()); 
      shutDown(ex.toString()); 
      return; 
     } 

및 예외 자체 :

java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, big-endian is supported. 
+0

흥미로운 질문 +1. 확인하기 만하면, 당신은'com.sun' 패키지에서 클래스 사용의 취약 함을 깨닫게 될 것입니다, 그렇죠? 존재하는 JRE에서도 다음 버전에서 제거/이동/이름 변경이 가능합니다. –

+0

실제로, 이것이 적어도 나쁜 습관이라는 것을 알고 있지만, 실제로는 내 마지막 수단이었습니다. Java Sound 구현 결함으로 간주 될 수 있습니다. –

+0

많은 중 하나. JavaSound는 제한된 범위의 것들을 지원하는 데 유용하지만, Sun은 실제로 그것을 더 발전시키지 못했습니다. –

답변

0

예외가 도움이 될 수 있습니다 던져 코드를 게시. 마이크를 분리 할 때 당신은 여전히 ​​비슷한 예외를 얻을 수 있습니다

TargetDataLine dataLine = (TargetDataLine) AudioSystem.getLine(new DataLine.Info(TargetDataLine.class, audioFormat));      
dataLine.open(); 
dataLine.start();    
dataLine.read(b, offset, len); 

참고 :

난 당신만을 기록하는 다음 데이터 라인을 받고 마이크의 존재를 감지 할 Port.Info를 사용하고 있으리라 믿고있어 존재 여부를 확인하는 시간과 데이터 라인을 기록하려고 시도하는 사이에 마이크가 물리적으로 연결이 끊어지면 마이크로폰을 연결하면 문제가되지 않습니다.

+0

나는 똑같은 일을하고있는 것 같다. 어쨌든, 나는 코드와 예외로 질문을 업데이트했다. –

+0

라인이 해당 오디오 형식을 지원하는지 확인하십시오. 행에서 지원하는 모든 오디오 형식을 나열하려면 AudioFormat adfs [] = ((DataLine.Info) dataLine.getLineInfo()). getFormats(); for (AudioFormat adf : adfs) { System.out.println (adf.toString()); } – msam

+0

나는 당신의 아이디어를 얻지 못했다. line = (TargetDataLine) AudioSystem입니다.getLine (info); 예외가 던져지는 곳입니다. 그래서 처음부터 그 라인을 얻을 수 없습니다. 어쩌면 충분히 명확하지 않았을 것입니다. 프로그램 시작 전에 컴퓨터에 마이크가 연결되어 있으면 마이크가 정상적으로 작동합니다. 단절이 올바르게 감지되면 "기록"버튼이 비활성화됩니다. 다시 연결하면 다시 작동합니다. jvm 시작 전에 마이크가 연결되지 않은 경우 문제가 발생합니다. 이 경우 Port.Info.MICROPHONE이 발견 되더라도 해당 줄은 여전히 ​​작동하지 않습니다. –

0

원래 게시물을 영감으로 사용하여 마이크를 분실하거나 얻은 시간을 감지하는 수단으로 생각해 냈습니다. USB 마이크가 꽂혀 있거나 뽑혀있을 때 (내 시스템에서) 감지합니다. 백그라운드 스레드 루프에서 호출하고 있습니다. 노트북에 내장 마이크가 있기 때문에 원래의 방법으로는 나에게 도움이되지 않았으므로 두 번째 마이크를 추가해야했습니다.

... 
//call this once somewhere to turn the caching period down for faster detection 
    try 
    { 
     //try to set the caching period, defaults to something like 55 seconds 
     com.sun.media.sound.JDK13Services.setCachingPeriod(5); 
    } 
    catch(Exception e) 
    { 
     System.err.println("exception attempting to call com.sun.media.sound.JDK13Services.setCachingPeriod->" + e); 
    } 
... 

private int lastNumMics = -1; 
private synchronized void micCheck() 
{ 
    Line.Info[] lineInfoArray = AudioSystem.getSourceLineInfo(Port.Info.MICROPHONE); 
    int numMics = lineInfoArray == null ? 0 : lineInfoArray.length; 
    if(lastNumMics > -1) 
    { 
     if(numMics < lastNumMics) 
     { 
      //MICROPHONE_LOST 
     } 
     else if(numMics > lastNumMics) 
     { 
      //MICROPHONE_GAINED 
     } 
    } 
    lastNumMics = numMics; 
} 
관련 문제