2012-03-16 39 views
13

EDIT: Kết hợp câu trả lời của uv001 đã thay đổi.Làm cách nào để chuyển đổi tệp WAV/OGG thành tệp FLAC trong Android?

Tôi chỉ có thể thấy rằng ICS 4.0 hỗ trợ giải mã FLAC, nhưng mã hóa. Tôi cần một số bộ mã hóa để chuyển đổi wav sang flac, nhưng hiện tại tôi không thể tìm thấy nó. Tôi tìm thấy có một jFlac avaible, nhưng tôi không biết làm thế nào để sử dụng thư viện này, chỉ đơn giản là chuyển đổi các tập tin.

Có ai cho tôi một tay không?

Hôm nay, tôi chỉ là một số ý tưởng của bản thân mình, khi sử dụng JavaFlacEncoder. và nó hoạt động cho một số bitrate của WAV.

Tôi đã thay đổi giá trị thành giá trị mã hóa cứng hiện đang hoạt động.

/* 
* Copyright (C) 2010 Preston Lacey http://javaflacencoder.sourceforge.net/ 
* All Rights Reserved. 
* 
* 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 javaFlacEncoder; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 

import java.io.IOException; 
/** 
* 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; 

    /** 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; 
    } 

    private void adjustConfigurations(){//(AudioFormat format) { 
     int sampleRate = 16000;//(int)format.getSampleRate(); 
     int sampleSize = 16; //(int)format.getSampleSizeInBits(); 
     int channels =1;// (int)format.getChannels(); 
     //int blockSize = sc.getMaxBlockSize(); 
     /*sc = new StreamConfiguration(channels, blockSize, blockSize, 
       sampleRate, sampleSize);*/ 
     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 { 
      FLACFileOutputStream fout = null; 
      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 { 
//   format = sin.getFormat(); 
      //sanitize and optimize configurations 
      adjustConfigurations(); //adjustConfigurations(format); 
      //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, flac.getThreadCount()); 
        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, flac.getThreadCount()); 
      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; 
     } 

     //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; 
    } 
} 
+0

Tôi hoàn toàn không hiểu câu hỏi của bạn; Bạn có muốn mã hóa một tập tin âm thanh bằng cách sử dụng Android của bạn hay bạn muốn "phát lại" một số tập tin được mã hóa trước đó? – Rob

+0

Tôi muốn sử dụng ASR từ google và muốn sử dụng android để ghi âm vào wav và sử dụng một số bộ mã hóa để chuyển đổi từ wav sang flac và tải lên google và nhận lại văn bản được nhận dạng. nhưng hiện tại android không có bộ mã hóa cho FLAC, chỉ bộ giải mã cho FLAC trong 3+/ICS4 + – temple

+0

Đây là thư viện FLAC trong C có makefile cho Android: http://github.com/pelya/commandergenius/tree/sdl_android/ Dự án/jni/flac Bạn có thể dễ dàng biên dịch một công cụ dòng lệnh "flac" cho Android, sử dụng lib này – pelya

Trả lời

3

Temple, Cảm ơn bài đăng và phản hồi với mã được đính kèm để chuyển đổi FLAC. Nó hoạt động như bạn mô tả với một vấn đề nhỏ.

FLACFileOutputStream (fout) và FileInputStream (sin) không được đóng ở cuối hàm. Vui lòng cập nhật bài đăng/mã của bạn để những người khác cũng có thể hưởng lợi.

finally { 
    try { 
      if (sin != null) sin.close(); 
      if (fout != null) fout.close(); 
    } catch (IOException e) {} 
} 

PS: FLACFileOutputStream fout cần được thăng cấp lên biến lớp để hoạt động.

0

Thay đổi dòng sau trong mã của bạn

unencodedSamples -= flac.t_encodeSamples(unencodedSamples, true); 

để

unencodedSamples -= flac.t_encodeSamples(unencodedSamples, true,flac.getThreadCount()); 
+0

Điều này yêu cầu định dạng và mô tả, bất kể đó là sự chính xác. –

Các vấn đề liên quan