Back to project page rfcx-guardian-android.
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.
/* * Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/ * All Rights Reserved.//w w w. j a va 2s . 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.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import android.util.Log; /** * FLAC_FileEncoder is a class to encode an input wav File to an output Flac * file. It allows the EncodingConfiguration to be set only once, prior to * encoding the entire File. * * @author Preston Lacey * @author Bo Tan (Temple) */ public class FLAC_FileEncoder { /** Maximum number of bytes to read from file at once */ private static final int MAX_READ = 16384; private FLACFileOutputStream fout = null; /** Status enum for encode result */ public enum Status { /** Unknown State. */ UNKNOWN, /** Everything went well */ FULL_ENCODE, /** Something unspecified went wrong...*/ GENERAL_ERROR, /** internal error is something that went haywire that was discovered * due to internal sanity checks. A problem in API. */ INTERNAL_ERROR, /** File given was not able to be read */ UNSUPPORTED_FILE, /** Generic file IO Error */ FILE_IO_ERROR, /** Sample size unsupported */ UNSUPPORTED_SAMPLE_SIZE, /** Error with output file */ OUTPUT_FILE_ERROR, /** No errors found. */ OK } FLACEncoder flac = null; StreamConfiguration sc = null; EncodingConfiguration ec = null; File outFile = null; int lastTotalSamples = 0; boolean useThreads; /** * Constructor creates a FLAC_FileEncoder object with default * StreamConfiguration configuration and default EncodingConfiguration. * Thread use defaults to true. */ public FLAC_FileEncoder() { flac = new FLACEncoder(); sc = new StreamConfiguration(); ec = new EncodingConfiguration(); useThreads = true; } /** * Specify whether to use multiple threads or not. * @param val true to use threads, false otherwise. */ public void useThreads(boolean val) { useThreads = val; } public void adjustAudioConfig(int sampleRate, int sampleSize, int channels) { sc.setSampleRate(sampleRate); sc.setBitsPerSample(sampleSize); sc.setChannelCount(channels); } /** * Set the stream configuration for this encoder to use. Note that the audio * characteristics(number of channels, sample rate, and sample size), will * be set to match the input file at encode time, so needn't be set in the * given StreamConfiguration object. * * @param config StreamConfiguration to use for encoding. */ public void setStreamConfig(StreamConfiguration config) {sc = config; } /** * Set the EncodingConfiguration to use for encoding. * @param config EncodingConfiguration to use. */ public void setEncodingConfig(EncodingConfiguration config){ec = config;} private Status openStream() { Status status = Status.OK; boolean result = flac.setStreamConfiguration(sc); result = result & flac.setEncodingConfiguration(ec); if( !result) status = Status.INTERNAL_ERROR; else { try { fout = new FLACFileOutputStream(outFile.getPath()); } catch(IOException e) { status = Status.OUTPUT_FILE_ERROR; e.printStackTrace(); } if( status == Status.OK) { flac.setOutputStream(fout); try { flac.openFLACStream(); }catch(IOException e) { status = Status.INTERNAL_ERROR; } } else status = Status.OUTPUT_FILE_ERROR; } return status; } /** * Encode the given input wav file to an output file. * * @param inputFile Input wav file to encode. * @param outputFile Output file to write FLAC stream to. If file exists, it * will be overwritten without prompting. * * @return Status flag for encode */ public Status encode(File inputFile, File outputFile) { Status status = Status.FULL_ENCODE; this.outFile = outputFile; //take file and initial configuration. //open file // AudioInputStream sin = null; // AudioFormat format = null; // //File inputFile = new File("encoderTest.wav"); // try { // sin = AudioSystem.getAudioInputStream(inputFile); // }catch(IOException e) { // status = Status.FILE_IO_ERROR; // }catch (UnsupportedAudioFileException e) { // status = Status.UNSUPPORTED_FILE; // }finally { // if(status != Status.FULL_ENCODE) // return status; // } FileInputStream sin=null; try { sin = new FileInputStream(inputFile); } catch (FileNotFoundException e1) { status = Status.FILE_IO_ERROR; e1.printStackTrace(); }finally { if (status != Status.FULL_ENCODE) return status; } try { //open stream openStream(); int frameSize = 2;//format.getFrameSize(); int sampleSize = 16;//format.getSampleSizeInBits(); int bytesPerSample = sampleSize/8; if(sampleSize %8 != 0) { //end processing now Exception newEx = new Exception(Status.UNSUPPORTED_SAMPLE_SIZE.name()); throw newEx; } int channels =1;// format.getChannels(); boolean bigEndian =false;// format.isBigEndian(); byte[] samplesIn = new byte[(int)MAX_READ]; int samplesRead; int framesRead; int[] sampleData = new int[MAX_READ*channels/frameSize]; int blockSize = sc.getMaxBlockSize(); int unencodedSamples = 0; int totalSamples = 0; while((samplesRead = sin.read(samplesIn, 0, MAX_READ)) != -1) { //System.err.println("Read: " + read); framesRead = samplesRead/(frameSize); if(bigEndian) { for(int i = 0; i < framesRead*channels; i++) { int lower8Mask = 255; int temp = 0; int totalTemp = 0; for(int x = bytesPerSample-1; x >= 0; x++) { int upShift = 8*x; if(x == 0)//don't mask...we want sign temp = ((samplesIn[bytesPerSample*i+x]) << upShift); else temp = ((samplesIn[bytesPerSample*i+x] & lower8Mask) << upShift); totalTemp = totalTemp | temp; } sampleData[i] = totalTemp; } } else { for(int i = 0; i < framesRead*channels; i++) { int lower8Mask = 255; int temp = 0; int totalTemp = 0; for(int x = 0; x < bytesPerSample; x++) { int upShift = 8*x; if(x == bytesPerSample-1)//don't mask...we want sign temp = ((samplesIn[bytesPerSample*i+x]) << upShift); else temp = ((samplesIn[bytesPerSample*i+x] & lower8Mask) << upShift); totalTemp = totalTemp | temp; } sampleData[i] = totalTemp; } } if(framesRead > 0) { flac.addSamples(sampleData, framesRead); unencodedSamples += framesRead; } //if(unencodedSamples > blockSize*100) { if(useThreads)//Thread.yield();// unencodedSamples -= flac.t_encodeSamples(unencodedSamples, false, 0); else unencodedSamples -= flac.encodeSamples(unencodedSamples, false); totalSamples += unencodedSamples; //unencodedSamples = 0; //} //System.err.println("read : "+ samplesRead); } totalSamples += unencodedSamples; if(useThreads) unencodedSamples -= flac.t_encodeSamples(unencodedSamples, true, 0); else unencodedSamples -= flac.encodeSamples(unencodedSamples, true); //unencodedSamples = 0; lastTotalSamples = totalSamples; } catch(IOException e) { status = Status.FILE_IO_ERROR; } catch(Exception e) { status = Status.GENERAL_ERROR; String message = e.getMessage(); if(message == null) { e.printStackTrace(); } else if(message.equals(Status.UNSUPPORTED_SAMPLE_SIZE.name())) status = Status.UNSUPPORTED_SAMPLE_SIZE; } finally { try { if (sin != null) sin.close(); if (fout != null) fout.close(); } catch (IOException e) { Log.e("javaFlacEncoder-FLAC_FileEncoder",e.getMessage()); } } //System.err.print("LastTotalSamples: "+lastTotalSamples); return status; } /** * Get the total number of samples encoded in last encode. This is here * primarily for use as a sanity check during debugging. * * @return Total number of samples encoded in last encode attempt. */ public int getLastTotalSamplesEncoded() { return this.lastTotalSamples; } }