什么是一种更节省内存的方式来参与字节[]?

时间:2011-03-26 18:35:29

标签: java bytearray inputstream

我有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);
}

但这不起作用,不确定原因。

3 个答案:

答案 0 :(得分:3)

您不能一次读取一个样本的音频数据,并在阅读时将样本写入文件吗?

您的当前代码似乎也毫无意义地覆盖了monoData - 感谢您的纠正,@ fredley。

首先说明你用简单的英语做什么;这将有助于您理解它,然后转向代码。

答案 1 :(得分:1)

这是我使用的而不是vanilla ByteArrayOutputStream。你得到了一个方便的toByteArrayInputStream() + toByteBuffer()(我倾向于使用相当多的ByteBuffers)

希望很多人都能找到下面有用的代码,有些方法会从原始类中删除。

干杯!

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 :)

答案 2 :(得分:-1)

new ByteArrayInputStream(dataout.toByteArray())