2013-10-25 34 views
1

因此,我一直在研究一個學習類型項目,以從一行中獲取音頻數據並將其呈現給我的揚聲器。現在,我在最後一根稻草和最後幾行代碼上,我不知道會先發生什麼。一旦兩條數據線都設置好了,我嘗試將TargetDataLine讀入一個字節數組,並且編譯器會拋出一個nullPointerException。錯誤跟蹤到Stream.java:138這是public static void play()。我不確定我的Thread是否設置正確,但我們現在嘗試着眼於此話題。我基本上只是想讀Line In並寫到Speakers,任何建議都會很好。無法從TargetDataLine讀取

代碼:

package moshi; 

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Line; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.Mixer; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.TargetDataLine; 

/** 
* @author KN 
* @version 1.0 Build 1 October 25, 2013 
* 
*   This concurrent process sets up and controls the streaming of audio 
*   data via input and output buffers. 
* 
* @see {@link Thread}, {@link AudioSystem}, {@link TargetDataLine}, 
*  {@link SourceDataLine} 
*/ 

public class Stream extends Thread { 

    /** The {@link AudioFormat} used in encoding/decoding streaming audio data */ 
    public final static AudioFormat audioFormat = new AudioFormat(44100, 8, 1, true, true); 

    /** 
    * {@link String} describing the name of the audio device to be used. 
    * <p> 
    * Example: "Line In", "Microphone" 
    */ 
    private static String INPUT = "Line In"; 
    /** 
    * {@link String} describing the name of the audio device to be used. 
    * <p> 
    * Example: "Speakers", "Line Out" 
    */ 
    private static String OUTPUT = "Speakers"; 

    /** 
    * {@link #PROCESSING_BUFFER} is a buffer used for receiving audio data 
    * 
    * @see TargetDataLine 
    */ 
    private static TargetDataLine PROCESSING_BUFFER; 
    /** 
    * {@link #RENDERING_BUFFER} is a buffer used for writing audio data 
    * 
    * @see SourceDataLine 
    */ 
    private static SourceDataLine RENDERING_BUFFER; 
    /** {@link Integer} specifying the buffer sizes in bytes */ 
    private static int BUFFER_SIZE = 2048; 
    /** {@link Byte[]} for holding raw audio data */ 
    private static byte[] READ_BUFFER; 

    /** 
    * Initiates the audio hardware read/write buffers into 
    * {@link TargetDataLine}s and {@link SourceDataLine}s respectively. 
    * 
    * @see {@link TargetDataLine}, {@link SourceDataLine} 
    */ 
    public Stream() { 
     setProcessingBuffer(); 
     setRenderingBuffer(); 
    } 

    /** 
    * Queries input Lines and stores the {@link TargetDataLine} at 
    * {@link #PROCESSING_BUFFER} 
    * 
    * @see {@link AudioSystem}, {@link Line}, {@link TargetDataLine}, 
    *  {@link Mixer} 
    */ 
    private void setProcessingBuffer() { 
     final Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo(); 
     for (final Mixer.Info info : mixerInfos) { 
      final Mixer mixer = AudioSystem.getMixer(info); 
      final Line.Info[] targetLineInfos = mixer.getTargetLineInfo(); 
      for (final Line.Info targetLineInfo : targetLineInfos) { 
       if (targetLineInfo.getLineClass() == javax.sound.sampled.TargetDataLine.class 
         && info.getName().startsWith(Stream.INPUT)) { 
        try { 
         Stream.PROCESSING_BUFFER = (TargetDataLine) mixer.getLine(targetLineInfo); 
         System.out.println(targetLineInfo.getLineClass() + ": " + info.getName() + " [" 
           + Stream.PROCESSING_BUFFER + "]"); 
        } catch (LineUnavailableException e) { 
         e.printStackTrace(); 
        } 
       } else { 
       } 
      } 
     } 
    } 

    /** 
    * Queries output Lines and stores the {@link SourceDataLine} at 
    * {@link #RENDERING_BUFFER} 
    * 
    * @see {@link AudioSystem}, {@link Line}, {@link SourceDataLine}, 
    *  {@link Mixer} 
    */ 
    private void setRenderingBuffer() { 
     final Mixer.Info[] mixerInfos = AudioSystem.getMixerInfo(); 
     for (Mixer.Info info : mixerInfos) { 
      final Mixer mixer = AudioSystem.getMixer(info); 
      final Line.Info[] sourceLineInfos = mixer.getSourceLineInfo(); 
      for (final Line.Info sourceLineInfo : sourceLineInfos) { 
       if (sourceLineInfo.getLineClass() == javax.sound.sampled.SourceDataLine.class 
         && info.getName().startsWith(Stream.OUTPUT)) { 
        try { 
         Stream.RENDERING_BUFFER = (SourceDataLine) mixer.getLine(sourceLineInfo); 
         System.out.println(sourceLineInfo.getLineClass() + ": " + info.getName() + " [" 
           + Stream.RENDERING_BUFFER + "]"); 
        } catch (LineUnavailableException e) { 
         e.printStackTrace(); 
        } 
       } else { 
       } 
      } 
     } 
    } 

    /** 
    * Opens buffers {@link #PROCESSING_BUFFER} and {@link #RENDERING_BUFFER} 
    * for reading/writing 
    */ 
    public static void play() { 
     try { 
      if (!Stream.PROCESSING_BUFFER.isOpen()) { 
       Stream.PROCESSING_BUFFER.open(Stream.audioFormat); 
      } 
      if (!Stream.RENDERING_BUFFER.isOpen()) { 
       Stream.RENDERING_BUFFER.open(Stream.audioFormat); 
       Stream.RENDERING_BUFFER.start(); 
      } 
      while (Stream.RENDERING_BUFFER.isOpen()) { 
       Stream.PROCESSING_BUFFER.read(Stream.READ_BUFFER, 0, Stream.BUFFER_SIZE); 
       System.out.println(Stream.READ_BUFFER.length); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Stops buffers {@link #PROCESSING_BUFFER} and {@link #RENDERING_BUFFER} 
    * from reading/writing 
    */ 
    public static void pause() { 
     if (Stream.PROCESSING_BUFFER.isOpen()) { 
      Stream.PROCESSING_BUFFER.close(); 
     } 
     if (Stream.RENDERING_BUFFER.isOpen()) { 
      Stream.RENDERING_BUFFER.stop(); 
      Stream.RENDERING_BUFFER.close(); 
     } 
    } 

    /** {@inheritDoc} */ 
    @Override 
    public void run() { 
    } 
} 

從制度和錯誤堆棧跟蹤輸出的說:

interface javax.sound.sampled.TargetDataLine: Line In (Realtek High Definitio [[email protected]] 
interface javax.sound.sampled.SourceDataLine: Speakers (Realtek High Definition Audio) [[email protected]] 
java.lang.NullPointerException 
    at com.sun.media.sound.DirectAudioDevice$DirectTDL.read(Unknown Source) 
    at moshi.Stream.play(Stream.java:138) 
    at moshi.Controls$1.actionPerformed(Controls.java:38) 
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) 
    at java.awt.Component.processMouseEvent(Unknown Source) 
    at javax.swing.JComponent.processMouseEvent(Unknown Source) 
    at java.awt.Component.processEvent(Unknown Source) 
    at java.awt.Container.processEvent(Unknown Source) 
    at java.awt.Component.dispatchEventImpl(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Window.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$000(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 

回答

3

你永遠不會在你的代碼初始化的READ_BUFFER變量,你必須用適當的大小對其進行實例化:

READ_BUFFER = new byte[BUFFER_SIZE]; // I guess this was the intended size 
+0

哦,男孩,就是這樣。現在就像魅力一樣。非常感謝,有時我忘記了更簡單的事情。 xp – Kyle

+0

@凱爾太棒了!我很高興解決了這個問題:)請不要忘記接受答案;) –

+0

當然! ......在5分鐘內說。 – Kyle