java - 将 PCM 原始字节转换为 WAV 字节

标签 java html5-audio wav pcm transcoding

我正在监听实时电话并且能够获取原始 PCM 字节。 我还可以通过 java 的音频 api 收听这些字节。 这些都可以在小程序上运行。

现在我希望能够将电话调用的原始 PCM 字节转换为 WAV 字节,以便我可以将其直接写入 ServletOutputStream。这将允许浏览器真正监听电话。

有人知道我如何能够即时将一些原始 PCM 字节 [] 转换为 WAV 字节 [] 吗?

我见过的例子都与将一个文件转换为另一个文件有关。

java pcm to wav

How can I write a WAV file from byte array in java?

谢谢。

最佳答案

已经有一段时间了,但我认为这可能会对某人有所帮助。这是我的解决方案 - 我将字节写回任何输出流(在我的例子中是 servletoutputstream)。首先,我将 WAV header (44 字节)写入输出流并写入 pcm 字节(您需要将 pcm 数据转换为字节数组)。我在 html 中使用了音频标签,并将 src 标签指定为我的 api url,它工作得很好。

public void streamCloudObject(OutputStream stream, InputStream pcmData) throws IOException {

    stream.write(WAVHeader.build(44100,5242880));
    //byte_chunk_size is stream buffer size, I have it as 1MB, so at a time you are streaming 1MB of bytes
    byte[] outBytes = new byte[BYTE_CHUNK_SIZE];

    while(true) {   
        int r = pcmData.read(outBytes);
        if(r == -1)
            break;      
        stream.write(outBytes,0,r); 

    }

}


public class WAVHeader {

private static final int CHUNK_SIZE = 36;
private static final int BIT_RATE_16 = 16;
private static final int MONO = 1;
private static final int HEADER_SIZE = 44;

//inputStreamLength - I send the pcm filesize here and I get it from s3.
public static byte[] build(int sampleRate,int inputStreamLength) {

    byte[] header = new byte[HEADER_SIZE];
    int srate = resp.getSampleRate();
    int channel = MONO;
    int format = BIT_RATE_16;
    long dataLength = inputStreamLength;

    long totalDataLen = dataLength + CHUNK_SIZE;
    long bitrate = srate * channel * format;

    header[0] = 'R'; 
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f'; 
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = (byte) format; 
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1; 
    header[21] = 0;
    header[22] = (byte) channel; 
    header[23] = 0;
    header[24] = (byte) (srate & 0xff);
    header[25] = (byte) ((srate >> 8) & 0xff);
    header[26] = (byte) ((srate >> 16) & 0xff);
    header[27] = (byte) ((srate >> 24) & 0xff);
    header[28] = (byte) ((bitrate / 8) & 0xff);
    header[29] = (byte) (((bitrate / 8) >> 8) & 0xff);
    header[30] = (byte) (((bitrate / 8) >> 16) & 0xff);
    header[31] = (byte) (((bitrate / 8) >> 24) & 0xff);
    header[32] = (byte) ((channel * format) / 8); 
    header[33] = 0;
    header[34] = 16; 
    header[35] = 0;
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    header[40] = (byte) (dataLength  & 0xff);
    header[41] = (byte) ((dataLength >> 8) & 0xff);
    header[42] = (byte) ((dataLength >> 16) & 0xff);
    header[43] = (byte) ((dataLength >> 24) & 0xff);
    return header;
}
}

关于java - 将 PCM 原始字节转换为 WAV 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34652746/

相关文章:

javascript - 即使在点击处理程序上,Html5 音频也不会加载/播放

javascript - Chrome Extension webAudio API 停止 Windows 省电模式

c++ - 如何使用 libsndfile 将 .wav 文件加载到数组中?

c++ - 以编程方式转换 WAV

Java Netbeans 覆盖 JPanel 中的 paint() 方法

java - java 和 python 中的 Whirlpool 哈希给出不同的结果

javascript - Safari 11 对 HTML5 音频的新自动播放限制

java - 添加数据库中不存在的额外列

java - Spring Security 的刷新权限

matlab - 分析Wav文件格式