Beispiel #1
0
 SourceDataLine getSourceDataLine(AudioFormat format, int bufferSize) {
   SourceDataLine line = null;
   DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
   if (AudioSystem.isLineSupported(info)) {
     try {
       if (outputMixer == null) {
         line = (SourceDataLine) AudioSystem.getLine(info);
       } else {
         line = (SourceDataLine) outputMixer.getLine(info);
       }
       // remember that time you spent, like, an entire afternoon fussing
       // with this buffer size to try to get the latency decent on Linux?
       // Yah, don't fuss with this anymore, ok?
       line.open(format, bufferSize * format.getFrameSize() * 4);
       if (line.isOpen()) {
         debug(
             "SourceDataLine is "
                 + line.getClass().toString()
                 + "\n"
                 + "Buffer size is "
                 + line.getBufferSize()
                 + " bytes.\n"
                 + "Format is "
                 + line.getFormat().toString()
                 + ".");
         return line;
       }
     } catch (LineUnavailableException e) {
       error("Couldn't open the line: " + e.getMessage());
     }
   }
   error("Unable to return a SourceDataLine: unsupported format - " + format.toString());
   return line;
 }
  private void startSpeaker(AudioFormat format) throws LineUnavailableException {

    speaker.open(format, bufferSize);

    int actualBufferSize = speaker.getBufferSize();

    if (bufferSize != actualBufferSize) {
      Logger.println(
          "Speaker set buffer to " + bufferSize + " but actual size is " + actualBufferSize);

      bufferSize = actualBufferSize;
    }

    if (Logger.logLevel >= Logger.LOG_MOREINFO) {
      Logger.println(
          "Speaker using "
              + getBufferSizeMillis(actualBufferSize)
              + " millisecond buffer "
              + actualBufferSize
              + " bytes");
    }

    speaker.start();
    flush();

    // println("speaker started");
  }
Beispiel #3
0
 public int getFramePosition() {
   long timeSinceLastPositionSet = System.currentTimeMillis() - timelastPositionSet;
   int size = dataLine.getBufferSize() * (format.getChannels() / 2) / bufferUpdateFactor;
   int framesSinceLast =
       (int) ((timeSinceLastPositionSet / 1000f) * dataLine.getFormat().getFrameRate());
   int framesRemainingTillTime = size - framesSinceLast;
   return framePosition - framesRemainingTillTime;
 }
Beispiel #4
0
  public SourceDataLine getOutputLine(AudioFormat format) throws LineUnavailableException {
    SourceDataLine out;

    DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
    out = (SourceDataLine) mixer.getLine(info);
    out.open(format, out.getBufferSize());
    return out;
  }
 /** @see com.groovemanager.thread.ProgressThread#init() */
 protected void init() throws InitException {
   analysisLine = unit.getAnalysisLine();
   try {
     analysisLine.open();
   } catch (LineUnavailableException e) {
     e.printStackTrace();
     cancelOperation();
   }
   if (!in.getFormat().equals(analysisLine.getFormat())) {
     if (AudioSystem.isConversionSupported(analysisLine.getFormat(), in.getFormat()))
       in = AudioSystem.getAudioInputStream(analysisLine.getFormat(), in);
     else
       throw new InitException(
           "Unable to process audio data:\nConversion from "
               + in.getFormat()
               + " to "
               + analysisLine.getFormat()
               + " not supported.");
   }
   buffer = new byte[analysisLine.getBufferSize()];
 }
 /** Opens the line. */
 protected void openLine() throws LineUnavailableException {
   if (m_line != null) {
     AudioFormat audioFormat = m_audioInputStream.getFormat();
     int buffersize = lineBufferSize;
     if (buffersize <= 0) {
       buffersize = m_line.getBufferSize();
     }
     m_lineCurrentBufferSize = buffersize;
     m_line.open(audioFormat, buffersize);
     log.info("Open Line : BufferSize=" + buffersize);
     /*-- Display supported controls --*/
     Control[] c = m_line.getControls();
     for (int p = 0; p < c.length; p++) {
       log.info("Controls : " + c[p].toString());
     }
     /*-- Is Gain Control supported ? --*/
     if (m_line.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
       m_gainControl = (FloatControl) m_line.getControl(FloatControl.Type.MASTER_GAIN);
       log.info(
           "Master Gain Control : ["
               + m_gainControl.getMinimum()
               + ","
               + m_gainControl.getMaximum()
               + "] "
               + m_gainControl.getPrecision());
     }
     /*-- Is Pan control supported ? --*/
     if (m_line.isControlSupported(FloatControl.Type.PAN)) {
       m_panControl = (FloatControl) m_line.getControl(FloatControl.Type.PAN);
       log.info(
           "Pan Control : ["
               + m_panControl.getMinimum()
               + ","
               + m_panControl.getMaximum()
               + "] "
               + m_panControl.getPrecision());
     }
   }
 }
Beispiel #7
0
 public int getBufferSize() {
   return dataLine.getBufferSize();
 }
 /**
  * Main loop.
  *
  * <p>Player Status == STOPPED || SEEKING => End of Thread + Freeing Audio Ressources.<br>
  * Player Status == PLAYING => Audio stream data sent to Audio line.<br>
  * Player Status == PAUSED => Waiting for another status.
  */
 public void run() {
   log.info("Thread Running");
   int nBytesRead = 1;
   byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
   int readIndex = 0; // 所有读进缓冲区的数量
   int writeIndex = 0; // 所有写出数量
   // Lock stream while playing.
   synchronized (m_audioInputStream) {
     boolean buffering = false;
     // Main play/pause loop.
     while ((nBytesRead != -1)
         && (m_status != STOPPED)
         && (m_status != SEEKING)
         && (m_status != UNKNOWN)) {
       if (m_status == PLAYING) {
         // Play.
         try {
           nBytesRead = m_audioInputStream.read(abData, 0, abData.length);
           if (nBytesRead >= 0) {
             byte[] pcm = new byte[nBytesRead];
             System.arraycopy(abData, 0, pcm, 0, nBytesRead);
             if (m_line.available() >= m_line.getBufferSize()) {
               //                                buffering = true;
               log.fine("缓冲区空虚 : " + m_line.available() + "/" + m_line.getBufferSize());
             }
             //                            if(m_line.available()==0){
             //                                buffering=false;
             //                            }
             if (buffering == false) {
               int nBytesWritten = m_line.write(abData, 0, nBytesRead);
               // Compute position in bytes in encoded stream.
               int nEncodedBytes = getEncodedStreamPosition();
               // Notify listeners
               Iterator<BasicPlayerListener> it = laucher.getBasicPlayerListeners().iterator();
               while (it.hasNext()) {
                 BasicPlayerListener bpl = it.next();
                 if (m_audioInputStream instanceof PropertiesContainer) {
                   // Pass audio parameters such as instant bitrate, ...
                   Map properties = ((PropertiesContainer) m_audioInputStream).properties();
                   bpl.progress(nEncodedBytes, m_line.getMicrosecondPosition(), pcm, properties);
                 } else {
                   bpl.progress(nEncodedBytes, m_line.getMicrosecondPosition(), pcm, empty_map);
                 }
               }
             }
           }
         } catch (IOException e) {
           log.log(Level.SEVERE, "Thread cannot run()", e);
           m_status = STOPPED;
           notifyEvent(BasicPlayerEvent.STOPPED, getEncodedStreamPosition(), -1, null);
         }
         // Nice CPU usage.
         if (threadSleep > 0) {
           try {
             Thread.sleep(threadSleep);
           } catch (InterruptedException e) {
             log.log(Level.SEVERE, "Thread cannot sleep(" + threadSleep + ")", e);
           }
         }
       } else {
         synchronized (m_audioInputStream) {
           try {
             log.log(Level.INFO, "状态是不正在播放,要无限期的等待了.....");
             m_audioInputStream.wait();
             log.log(Level.INFO, "状态改过来了,等待被唤醒了.......");
           } catch (InterruptedException ex) {
             Logger.getLogger(BasicPlayer.class.getName()).log(Level.SEVERE, null, ex);
           }
         }
         // Pause
         //                    try {
         //                        Thread.sleep(500);
         //                    } catch (InterruptedException e) {
         //                        log.log(Level.SEVERE, "Thread cannot sleep(500)", e);
         //                    }
       }
     }
     // Free audio resources.
     if (m_line != null) {
       m_line.drain();
       m_line.stop();
       m_line.close();
       m_line = null;
     }
     // Notification of "End Of Media"
     if (nBytesRead == -1) {
       notifyEvent(BasicPlayerEvent.EOM, getEncodedStreamPosition(), -1, null);
     }
     // Close stream.
     closeStream();
   }
   m_status = STOPPED;
   notifyEvent(BasicPlayerEvent.STOPPED, getEncodedStreamPosition(), -1, null);
   log.info("Thread completed");
 }
Beispiel #9
0
  /**
   * Single audio channel playback with automatic starting and stopping of the underlying
   * sourcedataline specified by the mixer and mixer channel arguments.
   *
   * <p>Maintains an internal non-blocking audio packet queue and processes this queue 25 times a
   * second (every 40 ms).
   *
   * @param threadPoolManager for assigning buffer processing schedule task
   * @param mixer to obtain source data line
   * @param mixerChannel either mono or left/right stereo
   * @param audioFormat to use during playback
   * @param lineInfo to use when obtaining the source data line
   * @param requestedBufferSize of approximately 1 second of audio
   */
  public AudioOutput(
      ThreadPoolManager threadPoolManager,
      Mixer mixer,
      MixerChannel mixerChannel,
      AudioFormat audioFormat,
      Line.Info lineInfo,
      int requestedBufferSize) {
    mThreadPoolManager = threadPoolManager;
    mMixer = mixer;
    mMixerChannel = mixerChannel;

    try {
      mOutput = (SourceDataLine) mMixer.getLine(lineInfo);

      if (mOutput != null) {
        mOutput.open(audioFormat, requestedBufferSize);

        // Start threshold: buffer is full with 10% or less of capacity remaining
        mBufferStartThreshold = (int) (mOutput.getBufferSize() * 0.10);

        // Stop threshold: buffer is empty with 90% or more capacity available
        mBufferStopThreshold = (int) (mOutput.getBufferSize() * 0.90);

        mOutput.addLineListener(this);

        if (mOutput != null) {
          try {
            Control gain = mOutput.getControl(FloatControl.Type.MASTER_GAIN);
            mGainControl = (FloatControl) gain;
          } catch (IllegalArgumentException iae) {
            mLog.warn(
                "Couldn't obtain MASTER GAIN control for stereo line ["
                    + mixer.getMixerInfo().getName()
                    + " | "
                    + getChannelName()
                    + "]");
          }

          try {
            Control mute = mOutput.getControl(BooleanControl.Type.MUTE);
            mMuteControl = (BooleanControl) mute;
          } catch (IllegalArgumentException iae) {
            mLog.warn(
                "Couldn't obtain MUTE control for stereo line ["
                    + mixer.getMixerInfo().getName()
                    + " | "
                    + getChannelName()
                    + "]");
          }

          /* Run the queue processor task every 40 milliseconds or 25 times a second */
          mProcessorTask =
              mThreadPoolManager.scheduleFixedRate(
                  ThreadType.AUDIO_PROCESSING, new BufferProcessor(), 40, TimeUnit.MILLISECONDS);
        }

        mAudioStartEvent = new AudioEvent(AudioEvent.Type.AUDIO_STARTED, getChannelName());
        mAudioStopEvent = new AudioEvent(AudioEvent.Type.AUDIO_STOPPED, getChannelName());

        mCanProcessAudio = true;
      }
    } catch (LineUnavailableException e) {
      mLog.error(
          "Couldn't obtain audio source data line for "
              + "audio output - mixer ["
              + mMixer.getMixerInfo().getName()
              + "]");
    }
  }