[英]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.