[英]What's a more memory-efficient way of taking part of a byte[]?
我有一個立體聲音頻數據的ByteArrayOutputStream
。 目前,我正在這樣做,我知道這很糟糕:
WaveFileWriter wfw = new WaveFileWriter();
AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, 44100, 16, 1, 2, 44100, false);
byte[] audioData = dataout.toByteArray(); //bad bad bad
int length = audioData.length;
byte[] monoData = new byte[length/2]; //bad bad bad
for(int i = 0; i < length; i+=4){
monoData[i/2] = audioData[i];
monoData[1+i/2] = audioData[i+1];
}
ByteArrayInputStream bais = new ByteArrayInputStream(monoData);
AudioInputStream outStream = new AudioInputStream(bais,format,length);
wfw.write(outStream, Type.WAVE,output);
有什么更好的方法? 我可以將ByteArrayOutputStream
轉換為ByteArrayInputStream
以便從中讀取嗎?
編輯
好的,所以我深入研究了正在使用的ByteArrayOutputStream
的類。 正在使用以下命令進行填充:
dataout.write(convbuffer, 0, 2 * vi.channels * bout);
如果有幫助,我可以將其換成其他東西,但是我應該使用什么呢?
我嘗試將其替換為:
for(int j = 0;j < bout; j += 2){
dataout.write(convbuffer,2*j,2);
}
但這不起作用,不確定為什么。
您不能一次讀取一個樣本的音頻數據,然后在讀取樣本時將其寫入文件嗎?
同樣,您當前的代碼似乎毫無意義地覆蓋了 —感謝您的糾正,@ fredley。 monoData
。
首先用簡單的英語陳述你在做什么; 這將幫助您理解它, 然后轉向代碼。
這是我用的,而不是普通的ByteArrayOutputStream。 您會得到一個方便的toByteArrayInputStream()
+ toByteBuffer()
(我傾向於使用很多ByteBuffer)
希望許多人可以找到下面的代碼有用,某些方法已從原始類中刪除。
干杯!
public class ByteBufStream extends ByteArrayOutputStream implements Serializable{
private static final long serialVersionUID = 1L;
public ByteBufStream(int initSize){
super(initSize);
}
//+few more c-tors, skipped here
public ByteArrayInputStream toByteArrayInputStream(){
return new ByteArrayInputStream(getBuf(),0, count);
}
public ByteBuffer toByteBuffer(){
return ByteBuffer.wrap(getBuf(), 0 , count);
}
public int capacity(){
return buf.length;
}
public byte[] getBuf(){
return buf;
}
public final int size() {
return count;
}
private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException{
out.defaultWriteObject();
out.writeInt(capacity());
out.writeInt(size());
writeTo(out);
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
in.defaultReadObject();
int capacity = in.readInt();
int size = in.readInt();
byte[] b = new byte[capacity];
for (int n=0;n<size;){
int read = in.read(b, n, size-n);
if (read<0) throw new StreamCorruptedException("can't read buf w/ size:"+size);
n+=read;
}
this.buf = b;
this.count = size;
}
}
雖然我通常不講授技巧,但這一技巧可能無害,玩得開心!
如果要從普通的ByteArrayOutputStream中竊取buf [],請查看以下方法...
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
}
我想您知道您現在需要做什么:
class ByteArrayOutputStreamHack extends OutputStream{
public ByteArrayInputStream in;
public void write(byte b[], int off, int len) {
in = new ByteArrayInputStream(b, off, len);
}
public void write(int b){
throw new AssertionError();
}
}
ByteArrayOutputStreamHack hack = new ByteArrayOutputStreamHack()
byteArrayOutputStream.writeTo(hack);
ByteArrayInputStream in = hack.in; //we done, we cool :)
像new ByteArrayInputStream(dataout.toByteArray())
嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.