Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jpxiong
Forked from xynophon/EditAACUnit.java
Created July 10, 2017 05:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpxiong/e0870d3235dfb27ccc06ecf9eb3aacbb to your computer and use it in GitHub Desktop.
Save jpxiong/e0870d3235dfb27ccc06ecf9eb3aacbb to your computer and use it in GitHub Desktop.
VoiceRecorder edit recorded file
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.HashMap;
import android.util.Log;
public class EditAACUnit extends EditUnit
{
public EditAACUnit(File voiceFile)
{
mvoiceFile = voiceFile;
try
{
mOffset = 0;
stream = new FileInputStream(mvoiceFile);
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
}
private File mvoiceFile;
private FileInputStream stream;
// private FileOutputStream out;
private HashMap<Integer, Block> mAtomMap;
int mSampleRate;
int mSamplesPerFrame;
private int mOffset;
private int mMdatOffset;
private int mMinGain;
private int mMaxGain;
private int mNumFrames;
private int[] mFrameOffsets;
private int[] mFrameLens;
private int[] mFrameGains;
public static final int _FTYP = 0x66747970;
public static final int _MOOV = 0x6d6f6f76;
public static final int _MVHD = 0x6d766864;
public static final int _TRAK = 0x7472616b;
public static final int _TKHD = 0x746b6864;
public static final int _MDIA = 0x6d646961;
public static final int _MDHD = 0x6d646864;
public static final int _HDLR = 0x68646c72;
public static final int _MINF = 0x6d696e66;
public static final int _DINF = 0x64696e66;
public static final int _STBL = 0x7374626c;
public static final int _STSD = 0x73747364;
public static final int _MP4A = 0x6d703461;
public static final int _STTS = 0x73747473;
public static final int _STSZ = 0x7374737a;
public static final int _STSC = 0x73747363;
public static final int _STCO = 0x7374636f;
public static final int _SMHD = 0x736d6864;
public static final int _FREE = 0x66726565;
public static final int _MDAT = 0x6d646174;
class Block {
public int start;
public int len; // including header
public byte[] header;
public byte[] data;
};
void readFrameAndComputeGain(InputStream stream, int frameIndex)
throws java.io.IOException {
if (mFrameLens[frameIndex] < 4) {
mFrameGains[frameIndex] = 0;
stream.skip(mFrameLens[frameIndex]);
return;
}
int initialOffset = mOffset;
byte[] data = new byte[4];
stream.read(data, 0, 4);
mOffset += 4;
int idSynEle = (0xe0 & data[0]) >> 5;
switch(idSynEle) {
case 0: // ID_SCE: mono
int monoGain = ((0x01 & data[0]) << 7) | ((0xfe & data[1]) >> 1);
mFrameGains[frameIndex] = monoGain;
break;
case 1: // ID_CPE: stereo
int windowSequence = (0x60 & data[1]) >> 5;
int windowShape = (0x10 & data[1]) >> 4;
int maxSfb;
int scaleFactorGrouping;
int maskPresent;
int startBit;
if (windowSequence == 2) {
maxSfb = 0x0f & data[1];
scaleFactorGrouping = (0xfe & data[2]) >> 1;
maskPresent =
((0x01 & data[2]) << 1) |
((0x80 & data[3]) >> 7);
startBit = 25;
} else {
maxSfb =
((0x0f & data[1]) << 2) |
((0xc0 & data[2]) >> 6);
scaleFactorGrouping = -1;
maskPresent = (0x18 & data[2]) >> 3;
startBit = 21;
}
if (maskPresent == 1) {
int sfgZeroBitCount = 0;
for (int b = 0; b < 7; b++) {
if ((scaleFactorGrouping & (1 << b)) == 0) {
sfgZeroBitCount++;
}
}
int numWindowGroups = 1 + sfgZeroBitCount;
int skip = maxSfb * numWindowGroups;
startBit += skip;
}
int bytesNeeded = 1 + ((startBit + 7) / 8);
byte[] oldData = data;
data = new byte[bytesNeeded];
data[0] = oldData[0];
data[1] = oldData[1];
data[2] = oldData[2];
data[3] = oldData[3];
stream.read(data, 4, bytesNeeded - 4);
mOffset += (bytesNeeded - 4);
int firstChannelGain = 0;
for (int b = 0; b < 8; b++) {
int b0 = (b + startBit) / 8;
int b1 = 7 - ((b + startBit) % 8);
int add = (((1 << b1) & data[b0]) >> b1) << (7 - b);
firstChannelGain += add;
}
mFrameGains[frameIndex] = firstChannelGain;
break;
default:
if (frameIndex > 0) {
mFrameGains[frameIndex] = mFrameGains[frameIndex - 1];
} else {
mFrameGains[frameIndex] = 0;
}
break;
}
int skip = mFrameLens[frameIndex] - (mOffset - initialOffset);
stream.skip(skip);
mOffset += skip;
}
private void parsingAtoms(int atomType) throws IOException
{
byte[] header;
byte[] data;
int length;
switch(atomType)
{
// header
case _MOOV:
case _TRAK:
case _MDIA:
case _MINF:
case _STBL:
{
header = new byte[8];
data = new byte[0];
stream.read(header, 0, 8);
length = ((0xff & header[0]) << 24) |
((0xff & header[1]) << 16) |
((0xff & header[2]) << 8) |
((0xff & header[3]));
mOffset += 8;
break;
}
case _STSZ:
{
header = new byte[20];
stream.read(header, 0, 20);
length = ((0xff & header[0]) << 24) |
((0xff & header[1]) << 16) |
((0xff & header[2]) << 8) |
((0xff & header[3]));
mNumFrames =
((0xff & header[16]) << 24) |
((0xff & header[17]) << 16) |
((0xff & header[18]) << 8) |
((0xff & header[19]));
Log.e("writeFile", "mNumFrames : "+mNumFrames);
mFrameOffsets = new int[mNumFrames];
mFrameLens = new int[mNumFrames];
mFrameGains = new int[mNumFrames];
byte[] frameLenBytes = new byte[4 * mNumFrames];
stream.read(frameLenBytes, 0, 4 * mNumFrames);
mOffset += 4 * mNumFrames;
for (int i = 0; i < mNumFrames; i++) {
mFrameLens[i] =
((0xff & frameLenBytes[4 * i + 0]) << 24) |
((0xff & frameLenBytes[4 * i + 1]) << 16) |
((0xff & frameLenBytes[4 * i + 2]) << 8) |
((0xff & frameLenBytes[4 * i + 3]));
}
data = new byte[length-20];
data = frameLenBytes;
break;
}
case _STTS:
{
header = new byte[16];
stream.read(header, 0, 16);
length = ((0xff & header[0]) << 24) |
((0xff & header[1]) << 16) |
((0xff & header[2]) << 8) |
((0xff & header[3]));
mSamplesPerFrame =
((0xff & header[12]) << 24) |
((0xff & header[13]) << 16) |
((0xff & header[14]) << 8) |
((0xff & header[15]));
data = new byte[length-16];
stream.read(data, 0, length-16);
break;
}
case _MDAT:
{
header = new byte[8];
stream.read(header, 0, 8);
length = ((0xff & header[0]) << 24) |
((0xff & header[1]) << 16) |
((0xff & header[2]) << 8) |
((0xff & header[3]));
data = new byte[length-8];
stream.read(data, 0, length-8);
int initialOffset = mMdatOffset;
mOffset = initialOffset;
Log.e("parseMdat", "mOffset : "+mMdatOffset);
for (int i = 0; i < mNumFrames; i++) {
mFrameOffsets[i] = mOffset;
if (mOffset - initialOffset + mFrameLens[i] > length - 16) {
mFrameGains[i] = 0;
} else {
readFrameAndComputeGain(stream, i);
}
if (mFrameGains[i] < mMinGain)
mMinGain = mFrameGains[i];
if (mFrameGains[i] > mMaxGain)
mMaxGain = mFrameGains[i];
}
break;
}
default:
{
header = new byte[8];
stream.read(header, 0, 8);
length = ((0xff & header[0]) << 24) |
((0xff & header[1]) << 16) |
((0xff & header[2]) << 8) |
((0xff & header[3]));
data = new byte[length-8];
stream.read(data, 0, length-8);
break;
}
}
Block atom = new Block();
atom.header = header;
atom.data = data;
atom.len = length;
Log.e("parsingAtoms", "atom.len : "+atom.len);
Log.e("parsingAtoms", "mOffset : "+mOffset);
// FREE
if (header[0] == 0 &&
header[4] == 'f' &&
header[5] == 'r' &&
header[6] == 'e' &&
header[7] == 'e')
{
//pass
}
else
{
mAtomMap.put(atomType, atom);
}
if(atomType == _STCO)
{
mMdatOffset = ((0xff & data[8]) << 24) |
((0xff & data[9]) << 16) |
((0xff & data[10]) << 8) |
((0xff & data[11]));
Log.e("parsingAtom", "mMdatOffset : "+mMdatOffset);
}
if(atomType == _STSD)
{
Log.e("parseMp4aFromStsd", "data[40] : "+data[40]);
Log.e("parseMp4aFromStsd", "data[41] : "+data[41]);
setSampleRate(((0xff & data[40]) << 8) | ((0xff & data[41])));
}
if(atomType == _STTS)
{
setSamplePerFrame(((0xff & data[4]) << 24) |
((0xff & data[5]) << 16) |
((0xff & data[6]) << 8) |
((0xff & data[7])));
}
}
private void parseAAC()
{
mAtomMap = new HashMap<Integer, Block>();
try
{
if(getFTYP())
{
parseMOOV();
parseFREE();
parseMDAT();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
private boolean getFTYP() throws IOException
{
byte[] header = new byte[8];
stream.read(header, 0, 8);
if (header[0] == 0 &&
header[4] == 'f' &&
header[5] == 't' &&
header[6] == 'y' &&
header[7] == 'p')
{
Block atom = new Block();
atom.start = mOffset;
atom.header = header;
atom.len = ((0xff & header[0]) << 24) |
((0xff & header[1]) << 16) |
((0xff & header[2]) << 8) |
((0xff & header[3]));
byte [] data = new byte[atom.len-8];
stream.read(data, 0, atom.len-8);
atom.data = data;
mOffset += atom.len;
mAtomMap.put(_FTYP, atom);
return true;
}
else
{
return false;
}
}
private void parseMOOV() throws IOException
{
parsingAtoms(_MOOV);
parseMVHD();
parseTRAK();
}
private void parseMVHD() throws IOException
{
parsingAtoms(_MVHD);
}
private void parseTRAK() throws IOException
{
parsingAtoms(_TRAK);
parseTKHD();
parseMDIA();
}
private void parseTKHD() throws IOException
{
parsingAtoms(_TKHD);
}
private void parseMDIA() throws IOException
{
parsingAtoms(_MDIA);
parseMDHD();
parseHDLR();
parseMINF();
}
private void parseMDHD() throws IOException
{
parsingAtoms(_MDHD);
}
private void parseHDLR() throws IOException
{
parsingAtoms(_HDLR);
}
private void parseMINF() throws IOException
{
parsingAtoms(_MINF);
parseSMHD();
parseDINF();
parseSTBL();
}
private void parseSMHD() throws IOException
{
parsingAtoms(_SMHD);
}
private void parseDINF() throws IOException
{
parsingAtoms(_DINF);
}
private void parseSTBL() throws IOException
{
parsingAtoms(_STBL);
parseSTSD();
parseSTTS();
parseSTSZ();
parseSTSC();
parseSTCO();
}
private void parseSTSD() throws IOException
{
parsingAtoms(_STSD);
}
private void parseSTTS() throws IOException
{
parsingAtoms(_STTS);
}
private void parseSTSZ() throws IOException
{
parsingAtoms(_STSZ);
}
private void parseSTSC() throws IOException
{
parsingAtoms(_STSC);
}
private void parseSTCO() throws IOException
{
parsingAtoms(_STCO);
}
private void parseFREE() throws IOException
{
parsingAtoms(_FREE);
}
private void parseMDAT() throws IOException
{
mMinGain = 255;
mMaxGain = 0;
parsingAtoms(_MDAT);
}
private void setSampleRate(int rate)
{
mSampleRate = rate;
}
private void setSamplePerFrame(int sample)
{
mSamplesPerFrame = sample;
}
public void SetAtomData(int atomType, byte[] data) {
Block atom = mAtomMap.get(atomType);
if (atom == null) {
atom = new Block();
mAtomMap.put(atomType, atom);
}
if(atomType == _STSZ)
{
atom.len = data.length + 20;
}
else
{
atom.len = data.length + 8;
}
atom.header[0] = (byte)((atom.len >> 24) & 0xff);
atom.header[1] = (byte)((atom.len >> 16) & 0xff);
atom.header[2] = (byte)((atom.len >> 8) & 0xff);
atom.header[3] = (byte)(atom.len & 0xff);
if(atomType == _STTS)
{
atom.header[8] = data[0];
atom.header[9] = data[1];
atom.header[10] = data[2];
atom.header[11] = data[3];
atom.header[12] = data[4];
atom.header[13] = data[5];
atom.header[14] = data[6];
atom.header[15] = data[7];
byte[] tempdata = new byte[8];
for(int i = 0; i < 8; i++)
{
tempdata[i] = data[8+i];
}
data = null;
data = tempdata;
}
if(atomType == _STSZ)
{
atom.header[16] = (byte)((mNumFrames >> 24) & 0xff);
atom.header[17] = (byte)((mNumFrames >> 16) & 0xff);
atom.header[18] = (byte)((mNumFrames >> 8) & 0xff);
atom.header[19] = (byte)(mNumFrames & 0xff);
}
atom.data = data;
}
private byte[] editFile(int startValue, int numFrames) throws IOException
{
mOffset = 0;
mMdatOffset = 0;
setFTYP();
setMOOV(startValue, numFrames);
setMDAT(startValue, numFrames);
// out = new FileOutputStream(mvoiceFile);
return mergeByte();
// out.close();
}
private void setFTYP()
{
SetAtomData(_FTYP, new byte[] {
'i', 's', 'o', 'm',
0, 0, 0, 0,
'i', 's', 'o', 'm',
'3', 'g', 'p', '4'
});
}
private void setMOOV(int startFrame, int numFrames)
{
setTRAK(startFrame, numFrames);
mAtomMap.get(_MOOV).len =
8 +
mAtomMap.get(_MVHD).len +
mAtomMap.get(_TRAK).len;
setHeaderLength(_MOOV, mAtomMap.get(_MOOV).len);
mMdatOffset = mAtomMap.get(_FTYP).len + mAtomMap.get(_MOOV).len + 8;
setSTCO();
}
private void setTRAK(int startFrame, int numFrames)
{
setMDIA(startFrame, numFrames);
mAtomMap.get(_TRAK).len =
8 +
mAtomMap.get(_TKHD).len +
mAtomMap.get(_MDIA).len;
setHeaderLength(_TRAK, mAtomMap.get(_TRAK).len);
}
private void setMDIA(int startFrame, int numFrames)
{
setMINF(startFrame, numFrames);
mAtomMap.get(_MDIA).len =
8 +
mAtomMap.get(_MDHD).len +
mAtomMap.get(_HDLR).len +
mAtomMap.get(_MINF).len;
setHeaderLength(_MDIA, mAtomMap.get(_MDIA).len);
}
private void setMINF(int startFrame, int numFrames)
{
setSTBL(startFrame, numFrames);
mAtomMap.get(_MINF).len =
8 +
mAtomMap.get(_DINF).len +
mAtomMap.get(_SMHD).len +
mAtomMap.get(_STBL).len;
setHeaderLength(_MINF, mAtomMap.get(_MINF).len);
}
private void setSTBL(int startFrame, int numFrames)
{
setSTTS(startFrame, numFrames);
setSTSZ(startFrame, numFrames);
setSTSC(startFrame, numFrames);
mAtomMap.get(_STBL).len =
8 +
mAtomMap.get(_STSD).len +
mAtomMap.get(_STTS).len +
mAtomMap.get(_STSC).len +
mAtomMap.get(_STSZ).len +
mAtomMap.get(_STCO).len;
setHeaderLength(_STBL, mAtomMap.get(_STBL).len);
}
private void setSTTS(int startVaue, int numFrames)
{
SetAtomData(_STTS, new byte[] {
0, 0, 0, 0, // version / flags
0, 0, 0, 1, // entry count
(byte) ((numFrames >> 24) & 0xff),
(byte) ((numFrames >> 16) & 0xff),
(byte) ((numFrames >> 8) & 0xff),
(byte) (numFrames & 0xff),
(byte) ((mSamplesPerFrame >> 24) & 0xff),
(byte) ((mSamplesPerFrame >> 16) & 0xff),
(byte) ((mSamplesPerFrame >> 8) & 0xff),
(byte) (mSamplesPerFrame & 0xff)
});
}
private void setSTSZ(int startFrame, int numFrames)
{
byte[] stszData = new byte[4 * numFrames];
mNumFrames = numFrames;
for (int i = 0; i < numFrames; i++) {
stszData[4 * i] =
(byte)((mFrameLens[startFrame + i] >> 24) & 0xff);
stszData[1 + 4 * i] =
(byte)((mFrameLens[startFrame + i] >> 16) & 0xff);
stszData[2 + 4 * i] =
(byte)((mFrameLens[startFrame + i] >> 8) & 0xff);
stszData[3 + 4 * i] =
(byte)(mFrameLens[startFrame + i] & 0xff);
}
SetAtomData(_STSZ, stszData);
}
private void setSTSC(double startVaue, int numFrames)
{
SetAtomData(_STSC, new byte[] {
0, 0, 0, 0,
0, 0, 0, 1,
0, 0, 0, 1,
(byte) ((numFrames >> 24) & 0xff),
(byte) ((numFrames >> 16) & 0xff),
(byte) ((numFrames >> 8) & 0xff),
(byte) (numFrames & 0xff),
0, 0, 0, 1
});
}
private void setHeaderLength(int atomType, int length)
{
mAtomMap.get(atomType).header[0] = (byte)((length >> 24) & 0xff);
mAtomMap.get(atomType).header[1] = (byte)((length >> 16) & 0xff);
mAtomMap.get(atomType).header[2] = (byte)((length >> 8) & 0xff);
mAtomMap.get(atomType).header[3] = (byte)(length & 0xff);
}
private void setSTCO()
{
mAtomMap.get(_STCO).data[8] = (byte)((mMdatOffset >> 24) & 0xff);
mAtomMap.get(_STCO).data[9] = (byte)((mMdatOffset >> 16) & 0xff);
mAtomMap.get(_STCO).data[10] = (byte)((mMdatOffset >> 8) & 0xff);
mAtomMap.get(_STCO).data[11] = (byte)(mMdatOffset & 0xff);
}
private void setMDAT(int startFrame, int numFrames)
{
int maxFrameLen = 0;
for (int i = 0; i < numFrames; i++) {
if (mFrameLens[startFrame + i] > maxFrameLen)
maxFrameLen = mFrameLens[startFrame + i];
}
byte[] buffer;
byte[] tempbuffer = new byte[mAtomMap.get(_MDAT).data.length];
setHeaderLength(_MDAT, maxFrameLen);
int pos = 0;
int mdatpos = 0;
int start = 0;
int end = 0;
tempbuffer = mAtomMap.get(_MDAT).data;
for (int i = 0; i < numFrames; i++) {
int skip = mFrameOffsets[startFrame + i] - pos - 2835032;
int len = mFrameLens[startFrame + i];
if (skip < 0) {
continue;
}
if (skip > 0) {
if(start == 0)
{
start = skip;
end = start;
}
}
end += len;
}
buffer = new byte[end-start];
for(int j = start; j < end; j++)
{
buffer[j - start] = mAtomMap.get(_MDAT).data[j];
}
mAtomMap.get(_MDAT).data = null;
mAtomMap.get(_MDAT).data = buffer;
}
private byte[] mergeByte()
{
byte bkFTYP[] = byteMerger(mAtomMap.get(_FTYP).header, mAtomMap.get(_FTYP).data);
byte bkMOOV[] = byteMerger(mAtomMap.get(_MOOV).header, byteMerger(mAtomMap.get(_MVHD).header, mAtomMap.get(_MVHD).data));
byte bkTRAK[] = byteMerger(mAtomMap.get(_TRAK).header, byteMerger(mAtomMap.get(_TKHD).header, byteMerger(mAtomMap.get(_TKHD).data, mAtomMap.get(_MDIA).header)));
byte bkMDHD[] = byteMerger(mAtomMap.get(_MDHD).header, byteMerger(mAtomMap.get(_MDHD).data, byteMerger(mAtomMap.get(_HDLR).header, byteMerger(mAtomMap.get(_HDLR).data, mAtomMap.get(_MINF).header))));
byte bkDINF[] = byteMerger(mAtomMap.get(_DINF).header, byteMerger(mAtomMap.get(_DINF).data, mAtomMap.get(_STBL).header));
byte bkSTSD[] = byteMerger(mAtomMap.get(_STSD).header,
byteMerger(mAtomMap.get(_STSD).data,
byteMerger(mAtomMap.get(_STTS).header,
byteMerger(mAtomMap.get(_STTS).data,
byteMerger(mAtomMap.get(_STSZ).header,
byteMerger(mAtomMap.get(_STSZ).data,
byteMerger(mAtomMap.get(_STSC).header,
byteMerger(mAtomMap.get(_STSC).data,
byteMerger(mAtomMap.get(_STCO).header, mAtomMap.get(_STCO).data)))))))));
byte bkSMHD[] = byteMerger(mAtomMap.get(_SMHD).header, mAtomMap.get(_SMHD).data);
byte bkMDAT[] = byteMerger(mAtomMap.get(_MDAT).header, mAtomMap.get(_MDAT).data);
byte byteMerged[] = byteMerger(bkFTYP, byteMerger(bkMOOV, byteMerger(bkTRAK, byteMerger(bkMDHD, byteMerger(bkDINF, byteMerger(bkSTSD, byteMerger(bkSMHD, bkMDAT)))))));
return byteMerged;
}
private void setDuration(int duration)
{
mAtomMap.get(_MVHD).data[16] = (byte)((duration >> 24) & 0xff);
mAtomMap.get(_MVHD).data[17] = (byte)((duration >> 16) & 0xff);
mAtomMap.get(_MVHD).data[18] = (byte)((duration >> 8) & 0xff);
mAtomMap.get(_MVHD).data[19] = (byte)(duration & 0xff);
mAtomMap.get(_TKHD).data[20] = (byte)((duration >> 24) & 0xff);
mAtomMap.get(_TKHD).data[21] = (byte)((duration >> 16) & 0xff);
mAtomMap.get(_TKHD).data[22] = (byte)((duration >> 8) & 0xff);
mAtomMap.get(_TKHD).data[23] = (byte)(duration & 0xff);
}
public byte[] editVoiceFile(double start, double end)
{
parseAAC();
int startValue = secondsToFrame(start/1000.0);
int endValue = secondsToFrame(end/1000.0);
setDuration((int)(end - start));
int numFrames = endValue - startValue;
//write
try
{
return editFile(startValue, numFrames);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private int secondsToFrame(double seconds)
{
Log.e("secondsToFrame", "seconds : "+seconds);
Log.e("secondsToFrame", "mSampleRate : "+mSampleRate);
return (int)(1.0 * seconds * mSampleRate / mSamplesPerFrame + 0.5);
}
}
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
public class EditAMRUnit extends EditUnit{
public EditAMRUnit(File f,long duration){
super.mVoiceFile = f;
super.mDuration = duration;
mPacketUnit = 13;
mHeaderNumSeparator = 6;
}
public void setSecondFile(File f){
super.mVoiceFileSecond = f;
}
public void mergeVoiceFile(){
byte byteHeader[] = getHeader();
byte byteBody1[] = getBody(mVoiceFile);
byte byteBody2[] = getBody(mVoiceFileSecond);
byte byteMerged[] = byteMerger(byteBody1,byteBody2);
byte byteResult[] = byteMerger(byteHeader,byteMerged);
try{
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(mVoiceFile.getAbsolutePath()));
bos.write(byteResult);
bos.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void mergeVoiceFileForPause(){
byte byteHeader[] = getHeader();
byte byteBody1[] = getBody(tempSavedData);
byte byteBody2[] = getBody(mVoiceFile);
byte byteMerged[] = byteMerger(byteBody1,byteBody2);
byte byteResult[] = byteMerger(byteHeader,byteMerged);
tempSavedData = new byte[(int)byteResult.length];
tempSavedData = byteResult;
}
public byte[] editVoiceFile(int startValue,int endValue){
byte byteHeader[] = getHeader();
byte byteBody[] = getBody(mVoiceFile);
byte byteModifiedBody[] = getModifiedBody(byteBody, startValue, endValue);
byte byteResult[] = byteMerger(byteHeader, byteModifiedBody);
return byteResult;
}
}
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
public class EditQCPUnit extends EditUnit{
private int mEditPoint[] ={4, 182, 190, 194};
private long xorHelper1 = 0x000000FF;
private long xorHelper2 = xorHelper1 << 8;
private long xorHelper3 = xorHelper1 << 16;
private long xorHelper4 = xorHelper1 << 24;
public EditQCPUnit(File f,long duration){
super.mVoiceFile = f;
super.mDuration = duration;
mPacketUnit = 35;
mHeaderNumSeparator = 194;
}
public void setSecondFile(File f){
super.mVoiceFileSecond = f;
}
public byte[] getModifiedHeader(byte[] headerBuffer, byte[] bodyBuffer){
int thirdModifyByte = bodyBuffer.length;
int firstModifyByte = thirdModifyByte + 186; //BA = 186
int secondModifyByte = thirdModifyByte/35;
byte[] buffer = new byte[headerBuffer.length];
byte[] firstByteArray = new byte[4];
byte[] secondByteArray = new byte[4];
byte[] thirdByteArray = new byte[4];
firstByteArray[0] = (byte)(firstModifyByte & xorHelper1);
firstByteArray[1] = (byte)((firstModifyByte & xorHelper2) >> 8);
firstByteArray[2] = (byte)((firstModifyByte & xorHelper3) >> 16);
firstByteArray[3] = (byte)((firstModifyByte & xorHelper4) >> 24);
secondByteArray[0] = (byte)(secondModifyByte & xorHelper1);
secondByteArray[1] = (byte)((secondModifyByte & xorHelper2) >> 8);
secondByteArray[2] = (byte)((secondModifyByte & xorHelper3) >> 16);
secondByteArray[3] = (byte)((secondModifyByte & xorHelper4) >> 24);
thirdByteArray[0] = (byte)(thirdModifyByte & xorHelper1);
thirdByteArray[1] = (byte)((thirdModifyByte & xorHelper2) >> 8);
thirdByteArray[2] = (byte)((thirdModifyByte & xorHelper3) >> 16);
thirdByteArray[3] = (byte)((thirdModifyByte& xorHelper4) >> 24);
for(int i=0;i<mEditPoint[3];i++){
if(i == mEditPoint[0] || i == (mEditPoint[0]+1)|| i == (mEditPoint[0]+2) || i == (mEditPoint[0]+3) ){
if(i == mEditPoint[0]){
buffer[i] = firstByteArray[0] ;
}else if(i == mEditPoint[0]+1){
buffer[i] = firstByteArray[1] ;
}else if(i == mEditPoint[0]+2){
buffer[i] = firstByteArray[2] ;
}else{
buffer[i] = firstByteArray[3] ;
}
}else if(i == mEditPoint[1] || i == (mEditPoint[1]+1) || i == (mEditPoint[1]+2) || i == (mEditPoint[1]+3)){
if(i == mEditPoint[1]){
buffer[i] = secondByteArray[0] ;
}else if(i == mEditPoint[1]+1){
buffer[i] = secondByteArray[1] ;
}else if(i == mEditPoint[1]+2){
buffer[i] = secondByteArray[2] ;
}else{
buffer[i] = secondByteArray[3] ;
}
}else if(i == mEditPoint[2] || i == (mEditPoint[2]+1) || i == (mEditPoint[2]+2) || i == (mEditPoint[2]+3)){
if(i == mEditPoint[2]){
buffer[i] = thirdByteArray[0] ;
}else if(i == mEditPoint[2]+1){
buffer[i] = thirdByteArray[1] ;
}else if(i == mEditPoint[2]+2){
buffer[i] = thirdByteArray[2] ;
}else{
buffer[i] = thirdByteArray[3] ;
}
}else{
buffer[i]=(byte)headerBuffer[i];
}
}
return buffer;
}
public void mergeVoiceFile(){
byte byteHeader[] = getHeader();
byte byteBody1[] = getBody(mVoiceFile);
byte byteBody2[] = getBody(mVoiceFileSecond);
byte byteMerged[] = byteMerger(byteBody1,byteBody2);
byte byteModifiedHeader[] = getModifiedHeader(byteHeader, byteMerged);
byte byteResult[] = byteMerger(byteModifiedHeader,byteMerged);
try{
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(mVoiceFile.getAbsolutePath()));
bos.write(byteResult);
bos.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void mergeVoiceFileForPause(){
byte byteHeader[] = getHeader();
byte byteBody1[] = getBody(tempSavedData);
byte byteBody2[] = getBody(mVoiceFile);
byte byteMerged[] = byteMerger(byteBody1,byteBody2);
byte byteModifiedHeader[] = getModifiedHeader(byteHeader, byteMerged);
byte byteResult[] = byteMerger(byteModifiedHeader,byteMerged);
tempSavedData = new byte[(int)byteResult.length];
tempSavedData = byteResult;
}
public byte[] editVoiceFile(int startValue,int endValue){
byte byteBody[] = getBody(mVoiceFile);
byte byteHeader[] = getModifiedHeader(getHeader(),byteBody);
byte byteModifiedBody[] = getModifiedBody(byteBody, startValue, endValue);
byte byteResult[] = byteMerger(byteHeader, byteModifiedBody);
return byteResult;
}
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import android.app.Activity;
import android.util.Log;
public class EditUnit {
protected File mVoiceFile;
protected File mVoiceFileSecond;
protected int mHeaderNumSeparator;
protected long mDuration;
protected int mPacketUnit;
protected Activity mActivity;
protected byte[] tempSavedData;
public void mergeVoiceFile(){};
public void setChangeFile(File f,long duration){
mVoiceFile = f;
mDuration = duration;
}
public byte[] getHeader(){
byte[] headerBuffer = new byte[mHeaderNumSeparator];
try{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(mVoiceFile));
bis.read(headerBuffer,0,mHeaderNumSeparator);
bis.close();
}catch(Exception e){
e.printStackTrace();
}
return headerBuffer;
}
public byte[] getBody(File f){
ByteBuffer bodyByteBuffer = ByteBuffer.allocateDirect((int)f.length()-mHeaderNumSeparator);
byte[] bodyBuffer = new byte[(int)f.length()];
try{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
bis.read(bodyBuffer);
bis.close();
}catch(Exception e){
e.printStackTrace();
}
bodyByteBuffer.position(0);
bodyByteBuffer.put(bodyBuffer, mHeaderNumSeparator, (int)f.length()-mHeaderNumSeparator);
return bodyByteBuffer.array();
}
public byte[] getBody(byte[] b){
ByteBuffer bodyByteBuffer = ByteBuffer.allocateDirect((int)b.length-mHeaderNumSeparator);
bodyByteBuffer.position(0);
bodyByteBuffer.put(b, mHeaderNumSeparator, (int)b.length-mHeaderNumSeparator);
return bodyByteBuffer.array();
}
public byte[] getModifiedBody(byte[] bodyBuffer, int startDuration, int finishDuration){
int duration100ms = (int)mDuration/100;
int totalSt100ms = startDuration/100;
int totalEd100ms = finishDuration/100;
int bitTo100msFile = bodyBuffer.length * 8 / duration100ms;
int countOfStPacketRemoving = (bitTo100msFile * totalSt100ms)/mPacketUnit/8 ;
int countOfEdPacketRemoving = (bitTo100msFile * (duration100ms-totalEd100ms))/mPacketUnit/8;
int stremovingByte = (countOfStPacketRemoving) * mPacketUnit;
int edremovingByte = (countOfEdPacketRemoving) * mPacketUnit;
ByteBuffer bodyByteBuffer = ByteBuffer.allocateDirect(bodyBuffer.length - stremovingByte - edremovingByte);
bodyByteBuffer.position(0);
bodyByteBuffer.put(bodyBuffer,stremovingByte,bodyBuffer.length - stremovingByte - edremovingByte);
bodyByteBuffer.position(0);
return bodyByteBuffer.array();
}
public byte[] byteMerger(byte[] byte1, byte[] byte2){
ByteBuffer buffer = ByteBuffer.allocateDirect(byte1.length+byte2.length);
buffer.position(0);
buffer.put(byte1);
buffer.position(byte1.length);
buffer.put(byte2);
buffer.position(0);
return buffer.array();
}
public void saveTempFile(){
tempSavedData = new byte[(int)mVoiceFile.length()];
try{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(mVoiceFile));
bis.read(tempSavedData);
bis.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void saveOutputFileForPause(){
try{
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(mVoiceFile.getAbsolutePath()));
bos.write(tempSavedData);
bos.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment