BigEndian,LittleEndian混乱在Xuggler

时间:2012-12-25 20:25:34

标签: java xuggler endianness

之前我提出了一个关于将byte[]转换为short[]的问题,我遇到的一个新问题是转换/不将数据从byte[]转换为BigEndian。 这是发生了什么:

  • 我正在使用TargetDataLine将数据读入byte[10000]
  • AudioFormat对象BigEndian设置为 true ,任意。
  • byte[]需要转换为short[],以便可以使用Xuggler进行编码
  • 我不知道AudioFormat BigEndian是应该设置为true还是false 我已经尝试了两种情况,但在这两种情况下我都得到了例外情况 要将byte[]转换为short[],请执行以下操作:

    fromMic.read(tempBufferByte, 0, tempBufferByte.length);
    for(int i=0;i<tempBufferShort.length;i++){
    tempBufferShort[i] = (short) tempBufferByte[i];
    }  
    

    其中:
    fromMicTargetDataLine tempBufferbytebyte[10000] tempBufferShortshort[10000] 我得到了例外:

       java.lang.RuntimeException: failed to write packet: com.xuggle.xuggler.IPacket@90098448[complete:true;dts:12;pts:12;size:72;key:true;flags:1;stream index:1;duration:1;position:-1;time base:9/125;]
    

    可能需要的其他信息:

  • 如何在Xuggler中设置用于添加音频的流:
  • writer.addAudioStream(0,1,fmt.getChannels(),(int)fmt.getSampleRate());
    

  • 我如何执行编码
  • writer.encodeAudio(1,tempBufferShort,timeStamp,TimeUnit.NANOSECONDS);
    

    AudioFormat上的Java Doc

      

    ...除了编码,音频格式还包括其他格式   进一步指定数据的确切排列的属性。   这些包括通道数,采样率,样本大小,字节   订单,帧速率和帧大小...

      

    对于16位采样(或任何其他大于一个字节的采样大小),byte   秩序很重要;每个样本中的字节都排列在其中   “小端”或“大端”风格。

    问题:

  • 我是否需要在BigEndian对象中将javax.sound.sampled.AudioFormat保持为 true

  • 导致错误的原因是什么?是格式吗?



  • 我想我会通过AudioFormat对象预先格式化BigEndian数据。

    3 个答案:

    答案 0 :(得分:3)

    如果您的数据确实是大端,您可以直接将其转换为(大端)短数组,如下所示:

    ByteBuffer buf = ByteBuffer.wrap(originalByteArray);
    short[] shortArray = buf.asShortBuffer().array();
    

    如果您的数据是大端,则生成的short数组将直接并正确地映射所有原始byte数组。所以,原始数组,如:

    // bytes
    [00], [ae], [00], [7f]
    

    将转换为:

    // shorts
    [00ae], [007f]
    

    答案 1 :(得分:2)

    您需要将两个字节转换为一个短,因此这行错误:

    tempBufferShort[i] = (short) tempBufferByte[i];
    

    你需要一些基本的东西

    tempBufferShort[i] = (short) 
       (tempBufferByte[i*2] & 0xFF)*256 + (tempBufferByte[i*2+1] & 0xFF);
    

    这将与big-endian字节数组一致。

    答案 2 :(得分:1)

    其他人对于字节到短转换的说法是正确的,但它不会导致你看到的问题,它只会导致输出音频主要是噪音。你可以用全零的缓冲区(或其他任何东西)调用writeAudio,这样,其他一切都相同,缓冲区中的值与调用是否成功无关(它们与你在输出中听到的内容有关),当然:))

    1. 异常是否发生在流的开头(第一个音频块)?你能成功写一个纯音频流吗?

    2. 拨打addAudioStream时设置音频编解码器。试试ICodec.ID.CODEC_ID_MP3ICodec.ID.CODEC_ID_AAC

    3. 检查fmt.getChannels()fmt.getSampleRate()是否正确。并非任何特定编解码器都支持所有可能的值。 (2 ch,44100 Hz几乎可以支持任何事情)。

    4. 您是否在编写音频和视频,以确保时间戳严格不减少?

    5. 您的时间戳显示的持续时间内是否有足够的音频样本?是tempBufferShort.length == ((timeStamp - lastTimeStamp) / 1e+9) * sampleRate * channels吗? (这可能只是大致相等,但它应该非常接近,可能会有轻微的舍入错误)。