Android Open Source - rfcx-guardian-android F L A C Stream Controller






From Project

Back to project page rfcx-guardian-android.

License

The source code is released under:

Apache License

If you think the Android project rfcx-guardian-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2010  Preston Lacey http://javaflacencoder.sourceforge.net/
 * All Rights Reserved.//from  www.  java2s  .  c  o m
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

package net.sourceforge.javaFlacEncoder;
import java.util.concurrent.locks.ReentrantLock;
import java.io.IOException;
/**
 *
 * @author preston
 */
public class FLACStreamController {
  public static int DEBUG_LEV = 0;
  /** we set this to true while a flac stream has been opened and not
   * officially closed. Must use a streamLock to set and get this. Some actions
   * must not be taken while a stream is opened */
  volatile boolean flacStreamIsOpen = false;

  private final ReentrantLock streamLock = new ReentrantLock();
  
  /* Object to write results to. Must be set before opening stream */
  private FLACOutputStream out = null;

  /* contains FLAC_id used in the flac stream header to signify FLAC format */
  EncodedElement FLAC_id = FLACStreamIdentifier.getIdentifier();

  /* total number of samples encoded to output. Used in stream header */
  volatile long samplesInStream;

  /* next frame number to use */
  volatile long nextFrameNumber = 0;

  /* position of header in output stream location(needed so we can update
   * the header info(md5, minBlockSize, etc), once encoding is done
   */
  long streamHeaderPos = 0;

    /* minimum frame size seen so far. Used in the stream header */
  volatile int minFrameSize = 0x7FFFFFFF;

  /* maximum frame size seen so far. Used in stream header */
  volatile int maxFrameSize = 0;

  /* minimum block size used so far. Used in stream header */
  volatile int minBlockSize = 0x7FFFFFFF;

  /* maximum block size used so far. Used in stream header */
  volatile int maxBlockSize = 0;

  StreamConfiguration streamConfig = null;
  public FLACStreamController(FLACOutputStream fos, StreamConfiguration sc) {
    out = fos;
    streamConfig = new StreamConfiguration(sc);
    minFrameSize = 0x7FFFFFFF;
    maxFrameSize = 0;
    minBlockSize = 0x7FFFFFFF;
    maxBlockSize = 0;
    samplesInStream = 0;
    streamHeaderPos = 0;
    nextFrameNumber = 0;
  }
  public void setFLACOutputStream(FLACOutputStream fos) {
    streamLock.lock();
    try {
      if(flacStreamIsOpen)
        throw new IllegalStateException("Cannot set new output stream while flac stream is open");
      out = fos;
    }finally {
      streamLock.unlock();
    }
  }
  public FLACOutputStream getFLACOutputStream() { return out; }


  /**
   * Close the current FLAC stream. Updates the stream header information.
   * If called on a closed stream, operation is undefined. Do not do this.
   */
  public void closeFLACStream(byte[] md5Hash, StreamConfiguration streamConfig)
      throws IOException {
    //reset position in output stream to beginning.
    //re-write the updated stream info.
    streamLock.lock();
    try {
      if(!flacStreamIsOpen)
        throw new IllegalStateException("Error. Cannot close a non-opened stream");
      StreamConfiguration tempSC = new StreamConfiguration(streamConfig);
      tempSC.setMaxBlockSize(maxBlockSize);
      tempSC.setMinBlockSize(minBlockSize);
      EncodedElement streamInfo =  MetadataBlockStreamInfo.getStreamInfo(
          tempSC, minFrameSize, maxFrameSize, samplesInStream, md5Hash);
      if(out.canSeek()) {
        out.seek(streamHeaderPos);
        this.writeDataToOutput(streamInfo);
      }
      flacStreamIsOpen = false;
    } finally {
       streamLock.unlock();
    }
  }


/**
   * Write the data stored in an EncodedElement to the output stream.
   * All data will be written along byte boundaries, but the elements in the
   * given list need not end on byte boundaries. If the data of an element
   * does not end on a byte boundary, then the space remaining in that last
   * byte will be used as an offset, and merged(using an "OR"), with the first
   * byte of the following element.
   *
   * @param data
   * @return
   * @throws IOException
   */
  private int writeDataToOutput(EncodedElement data) throws IOException {
    
    int writtenBytes = 0;
    int offset = 0;
    EncodedElement current = data;
    int currentByte = 0;
    byte unfullByte = 0;
    byte[] eleData = null;
    int usableBits = 0;
    int lastByte = 0;
    while(current != null) {
      eleData = current.getData();
      usableBits = current.getUsableBits();
      currentByte = 0;
      //if offset is not zero, merge first byte with existing byte
      if(offset != 0) {
        unfullByte = (byte)(unfullByte | eleData[currentByte++]);
        out.write(unfullByte);
      }
      //write all full bytes of element.
      lastByte = usableBits/8;
      if(lastByte > 0)
        out.write(eleData, currentByte, lastByte-currentByte);
      //save non-full byte(if present), and set "offset" for next element.
      offset = usableBits %8;
      if(offset != 0) {
        unfullByte = eleData[lastByte];
      }
      //update current.
      current = current.getNext();
    }
    //if non-full byte remains. write.
    if(offset != 0) {
      out.write(eleData, lastByte, 1);
    }
    return writtenBytes;
  }

  public long incrementFrameNumber() {
    return nextFrameNumber++;
  }

/**
   * Begin a new FLAC stream. Prior to calling this, you must have already
   * set the StreamConfiguration and the output stream, both of which must not
   * change until encoding is finished and the stream is closed. If this
   * FLACEncoder object has already been used to encode a stream, unencoded
   * samples may still be stored. Use clear() to dump them prior to calling
   * this method(if clear() not called, and samples are instead retained, the
   * StreamConfiguration must NOT have changed from the prior stream.
   *
   * @throws IOException if there is an error writing the headers to output.
   */
  public void openFLACStream() throws IOException {
    streamLock.lock();
    try {
      //reset all data.
      reset();
      flacStreamIsOpen = true;
      //write FLAC stream identifier
      out.write(FLAC_id.getData(), 0, FLAC_id.getUsableBits()/8);
      //write stream headers. These must be updated at close of stream
      byte[] md5Hash = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//blank hash. Don't know it yet.
      EncodedElement streamInfo =  MetadataBlockStreamInfo.getStreamInfo(
          streamConfig, minFrameSize, maxFrameSize, samplesInStream, md5Hash);
      //mark stream info location(so we can return to it and re-write headers,
      //  assuming stream is seekable. Then write header.
      int size = streamInfo.getUsableBits()/8;
      EncodedElement metadataBlockHeader =
          MetadataBlockHeader.getMetadataBlockHeader(false,
          MetadataBlockHeader.MetadataBlockType.STREAMINFO, size);
      this.writeDataToOutput(metadataBlockHeader);
      streamHeaderPos = out.getPos();
      out.write(streamInfo.getData(), 0, size);
      writePaddingToFoolJFlac();
    }finally {
       streamLock.unlock();
    }
  }
  private void reset() {
    minFrameSize = 0x7FFFFFFF;
    maxFrameSize = 0;
    minBlockSize = 0x7FFFFFFF;
    maxBlockSize = 0;
    samplesInStream = 0;
    streamHeaderPos = 0;
    nextFrameNumber = 0;
  }
  private void writePaddingToFoolJFlac() throws IOException {
    int size = 40;
    byte[] padding = new byte[size];
    EncodedElement metadataBlockHeader =
        MetadataBlockHeader.getMetadataBlockHeader(true,
        MetadataBlockHeader.MetadataBlockType.PADDING, 40);
    this.writeDataToOutput(metadataBlockHeader);
    out.write(padding, 0,size);
  }

  public void writeBlock(BlockEncodeRequest ber) throws IOException {
    if(!flacStreamIsOpen)
      throw new IllegalStateException("Cannot write on a non-opened stream");
    writeDataToOutput(ber.result.getNext());
    //update encodedCount and count, and blocks, MD5
    if(ber.count != ber.encodedSamples) {
      System.err.println("Error encoding frame number: "+
          ber.frameNumber+", FLAC stream potentially invalid");
    }
    samplesInStream += ber.encodedSamples;
    if(ber.encodedSamples > maxBlockSize)
      maxBlockSize = ber.encodedSamples;
    if(ber.encodedSamples < minBlockSize)
      minBlockSize = ber.encodedSamples;
    int frameSize = ber.result.getTotalBits()/8;
    if(frameSize > maxFrameSize) maxFrameSize = frameSize;
    if(frameSize < minFrameSize) minFrameSize = frameSize;
  }

}




Java Source Code List

net.sourceforge.javaFlacEncoder.ArrayRecycler.java
net.sourceforge.javaFlacEncoder.BlockEncodeRequest.java
net.sourceforge.javaFlacEncoder.BlockThreadManager.java
net.sourceforge.javaFlacEncoder.CRC16.java
net.sourceforge.javaFlacEncoder.CRC8.java
net.sourceforge.javaFlacEncoder.ChannelData.java
net.sourceforge.javaFlacEncoder.EncodedElement_32.java
net.sourceforge.javaFlacEncoder.EncodedElement.java
net.sourceforge.javaFlacEncoder.EncodingConfiguration.java
net.sourceforge.javaFlacEncoder.FLACEncoder.java
net.sourceforge.javaFlacEncoder.FLACFileOutputStream.java
net.sourceforge.javaFlacEncoder.FLACOutputStream.java
net.sourceforge.javaFlacEncoder.FLACStreamController.java
net.sourceforge.javaFlacEncoder.FLACStreamIdentifier.java
net.sourceforge.javaFlacEncoder.FLACStreamOutputStream.java
net.sourceforge.javaFlacEncoder.FLAC_ConsoleFileEncoder.java
net.sourceforge.javaFlacEncoder.FLAC_FileEncoder.java
net.sourceforge.javaFlacEncoder.FLAC_MD5.java
net.sourceforge.javaFlacEncoder.FrameHeader.java
net.sourceforge.javaFlacEncoder.FrameThread.java
net.sourceforge.javaFlacEncoder.Frame.java
net.sourceforge.javaFlacEncoder.LPC.java
net.sourceforge.javaFlacEncoder.MetadataBlockHeader.java
net.sourceforge.javaFlacEncoder.MetadataBlockStreamInfo.java
net.sourceforge.javaFlacEncoder.RiceEncoder.java
net.sourceforge.javaFlacEncoder.StreamConfiguration.java
net.sourceforge.javaFlacEncoder.Subframe_Constant.java
net.sourceforge.javaFlacEncoder.Subframe_Fixed.java
net.sourceforge.javaFlacEncoder.Subframe_LPC.java
net.sourceforge.javaFlacEncoder.Subframe_Verbatim.java
net.sourceforge.javaFlacEncoder.Subframe.java
net.sourceforge.javaFlacEncoder.UTF8Modified.java
org.rfcx.guardian.RfcxGuardianPrefs.java
org.rfcx.guardian.RfcxGuardian.java
org.rfcx.guardian.activity.MainActivity.java
org.rfcx.guardian.activity.PrefsActivity.java
org.rfcx.guardian.api.ApiCore.java
org.rfcx.guardian.audio.AudioCore.java
org.rfcx.guardian.database.AlertDb.java
org.rfcx.guardian.database.AudioDb.java
org.rfcx.guardian.database.DeviceStateDb.java
org.rfcx.guardian.database.SmsDb.java
org.rfcx.guardian.device.AirplaneMode.java
org.rfcx.guardian.device.CpuUsage.java
org.rfcx.guardian.device.DeviceState.java
org.rfcx.guardian.intentservice.ApiCheckInTriggerIntentService.java
org.rfcx.guardian.intentservice.AudioEncodeIntentService.java
org.rfcx.guardian.intentservice.ServiceMonitorIntentService.java
org.rfcx.guardian.receiver.AirplaneModeReceiver.java
org.rfcx.guardian.receiver.BootReceiver.java
org.rfcx.guardian.receiver.ConnectivityReceiver.java
org.rfcx.guardian.receiver.SmsReceiver.java
org.rfcx.guardian.service.ApiCheckInService.java
org.rfcx.guardian.service.AudioCaptureService.java
org.rfcx.guardian.service.CarrierCodeService.java
org.rfcx.guardian.service.DeviceStateService.java
org.rfcx.guardian.telecom.CarrierInteraction.java
org.rfcx.guardian.utility.DateTimeUtils.java
org.rfcx.guardian.utility.DeviceGuid.java
org.rfcx.guardian.utility.ExtAudioRecorderModified.java
org.rfcx.guardian.utility.FileUtils.java
org.rfcx.guardian.utility.HttpGet.java
org.rfcx.guardian.utility.HttpPostMultipart.java
org.rfcx.guardian.utility.TimeOfDay.java