代码之家  ›  专栏  ›  技术社区  ›  jineb92

Android-音轨噪音[重复]

  •  1
  • jineb92  · 技术社区  · 7 年前

    我正在通过我的Android应用程序上的WebSocketClient接收一些字节[]。这些字节是MP3字节: 第三层帧单通道MPEG-1无校验和48 kHz,32 kbit/s 我试图做的是在收到一个音轨后,将每个字节[]写入一个音轨。问题是,这些字节[]是MP3,这是AudioTrack类不接受的压缩格式。我试着把它们解码成PCM。 下面是我创建音频曲目的方法:

    final AudioTrack player = new AudioTrack.Builder()
                .setAudioAttributes(new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                        .build())
                .setAudioFormat(new AudioFormat.Builder()
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setSampleRate(48000)
                        .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
                        .build())
                .setBufferSizeInBytes(AudioTrack.getMinBufferSize(48000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT))
                .build();
    

    最后,这是服务器发送给我的信息。我不知道我应该如何建立我的音轨来匹配这种格式。采样率设置为48000 Hz,我尝试了CHANNEL\u OUT\u立体声和单声道。我尝试了所有的编码参数,但我仍然有一个非常差的质量和高音。不知道我做错了什么。

    流#0:0:音频:mp3(libmp3lame),48000 Hz,单声道,s16p,32 kb/s

    编辑: 正如我在评论中所说,我尝试了我在相关帖子上找到的关于JLayer解码的东西,以下是新代码:

    public void addSample(byte[] data) throws BitstreamException, DecoderException {
        Decoder decoder = new Decoder();
        InputStream bis = new ByteArrayInputStream(data);
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        Bitstream bits = new Bitstream(bis);
        SampleBuffer pcmBuffer = (SampleBuffer) decoder.decodeFrame(bits.readFrame(), bits);
    
        for (int i = 0; i < pcmBuffer.getBufferLength(); i++) {
            if (pcmBuffer.getBuffer()[i] != 0) {
                outStream.write(pcmBuffer.getBuffer()[i] & 0xff);
                outStream.write((pcmBuffer.getBuffer()[i] >> 8) & 0xff);
            }
        }
        System.out.println("--------");
        for (int j = 0; j < outStream.toByteArray().length; j++) {
            System.out.println(outStream.toByteArray()[j]);
        }
        System.out.println("--------");
        mTrack.write(outStream.toByteArray(), 0, outStream.toByteArray().length);
        bits.closeFrame();
    }
    

    我没有直接写入pcmBuffer中包含的短[]数据,而是通过一个外流和一些掩码操作在字节[]中对其进行解码。我得到了完全相同的结果(机器人声音)。但正如你们所见,我试着在字节数组中循环,我正在写我的音轨,我试着打印每个数据。以下是结果示例:

    11-20 10:18:42.331 1749-2268/? I/System.out: 0
    11-20 10:18:42.331 1749-2268/? I/System.out: 48
    11-20 10:18:42.331 1749-2268/? I/System.out: 0
    11-20 10:18:42.331 1749-2268/? I/System.out: 46
    11-20 10:18:42.331 1749-2268/? I/System.out: 0
    11-20 10:18:42.331 1749-2268/? I/System.out: 44
    11-20 10:18:42.331 1749-2268/? I/System.out: 0
    11-20 10:18:42.331 1749-2268/? I/System.out: 44
    11-20 10:18:42.331 1749-2268/? I/System.out: 0
    11-20 10:18:42.331 1749-2268/? I/System.out: 45
    11-20 10:18:42.331 1749-2268/? I/System.out: 0
    11-20 10:18:42.331 1749-2268/? I/System.out: 48
    11-20 10:18:42.331 1749-2268/? I/System.out: 0
    

    正如我所怀疑的那样,数据实际上写为(左,右,左,右)。。。我不知道如何从这些信号中获得真正的单声道MP3信号。

    1 回复  |  直到 7 年前
        1
  •  0
  •   webo80    7 年前

    好吧,如果输入已经是PCM,你的代码就可以工作了,所以你需要一些第三方代码。

    如果您不想弄乱本机代码(C/C++)和JNI桥,我建议您使用 JLayer

    代码示例:

    Player player;
    /* create your input stream, bis in your code */     
    player = new Player(bis);
    player.play();