Java 混合8比特8000Hz PCM_ULAW样本的最简单方法是什么?

Java 混合8比特8000Hz PCM_ULAW样本的最简单方法是什么?,java,audio,voip,Java,Audio,Voip,我想在Java中混合使用多个ULAW示例。是否有一种方法可以在不转换为PCM的情况下执行此操作?我正在尝试做一个8000Hz的8位VoIP应用程序。Im使用AU文件(在goldwave中创建)进行测试,因为它们使用ULAW编码。我目前的做法是: [守则] AudioFormat f = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 16, 1, 2, 8000, false); SourceDataLine sdl

我想在Java中混合使用多个ULAW示例。是否有一种方法可以在不转换为PCM的情况下执行此操作?我正在尝试做一个8000Hz的8位VoIP应用程序。Im使用AU文件(在goldwave中创建)进行测试,因为它们使用ULAW编码。我目前的做法是:

[守则]

    AudioFormat f = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 16, 1, 2, 8000, false);
    SourceDataLine sdl = AudioSystem.getSourceDataLine(f);
    sdl.open(f);
    sdl.start();

    File file1 = new File("C:\\Scream3.au");
    AudioInputStream ais1 = AudioSystem.getAudioInputStream(file1);
    AudioInputStream aisTarget1 = AudioSystem.getAudioInputStream(f, ais1);

    File file2 = new File("C:\\Blackout3.au");
    AudioInputStream ais2 = AudioSystem.getAudioInputStream(file2);
    AudioInputStream aisTarget2 = AudioSystem.getAudioInputStream(f, ais2);

    byte[] data = new byte[10000];
    int[] calc = new int[5000];
    AudioInputStream[] streams = {aisTarget1, aisTarget2};
    int count = streams.length + 1;
    while (true) {
        int r = -1;
        for (int i = 0; i < streams.length; i++) {
            r = streams[i].read(data, 0, data.length);
            if (r == -1) break;
            for (int j = 0; j < calc.length; j++) {
                int tempVal = ((data[j * 2 + 1] << 8) | (data[j * 2] & 0xFF));
                calc[j] += tempVal;
            }
        }
        for (int i = 0; i < calc.length; i++) {
            calc[i] /= count;
            data[i * 2 + 0] = (byte) (calc[i] & 0xFF);
            data[i * 2 + 1] = (byte) (calc[i] >> 8);
        }
        if (r == -1) break;
        sdl.write(data, 0, data.length);
    }
AudioFormat f=新的AudioFormat(AudioFormat.Encoding.PCM_-SIGNED,8000,16,1,2,8000,false);
SourceDataLine sdl=AudioSystem.getSourceDataLine(f);
sdl.开放式(f);
sdl.start();
文件file1=新文件(“C:\\Scream3.au”);
AudioInputStream ais1=AudioSystem.getAudioInputStream(文件1);
AudioInputStream aisTarget1=AudioSystem.getAudioInputStream(f,ais1);
File file2=新文件(“C:\\Blackout3.au”);
AudioInputStream ais2=AudioSystem.getAudioInputStream(文件2);
AudioInputStream aisTarget2=AudioSystem.getAudioInputStream(f,ais2);
字节[]数据=新字节[10000];
int[]计算=新int[5000];
AudioInputStream[]streams={aisTarget1,aisTarget2};
int count=streams.length+1;
while(true){
int r=-1;
对于(int i=0;i8);
}
如果(r==-1)中断;
sdl.write(数据,0,数据长度);
}
[/code]

如果无法直接混合ulaw样本,我必须转换为PCM,如何从PCM格式转换(AudioFormat.Encoding.PCM_SIGNED,8000 Hz,16位,1通道,2字节帧大小,8000帧速率,小端) 至ULAW(8比特8000Hz)

我是否会做类似于: 1) 将波形头写入字节流 2) 将PCM数据写入字节流 3) 使用AudioSystem.getAudioInputStream(字节流)获取PCM AIS 4) 使用AudioSystem.getAudioInputStream(ulawFormat,PCM AIS)获取ULAW目标AIS

感谢您的帮助

编辑: 尝试将Mu定律转换为PCM(尝试使用公式):

[守则]

    AudioFormat f = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 8, 1, 1, 8000, false);
    SourceDataLine sdl = AudioSystem.getSourceDataLine(f);
    sdl.open(f);
    sdl.start();
    File file1 = new File("C:\\scream3.au");
    FileInputStream fis = new FileInputStream(file1);
    // Skip header
    fis.skip(24);
    byte[] data = new byte[8196];

    while (true) {
        int r = fis.read(data, 0, data.length);
        if (r == -1) break;
        for (int i = 0; i < r; i++) {
            float y = ((float) data[i] / Byte.MAX_VALUE);
            float sample = -1.0f * (float) (Math.signum(y) * (1.0f / 255.0f) * (Math.pow(1 + 255, Math.abs(y)) - 1.0f));
            data[i] = (byte) (sample * Byte.MAX_VALUE);
        }
        sdl.write(data, 0, data.length);
    }
    sdl.drain();
    sdl.stop();
    sdl.close();
    fis.close();
AudioFormat f=新的AudioFormat(AudioFormat.Encoding.PCM_-SIGNED,8000,8,1,1,8000,false);
SourceDataLine sdl=AudioSystem.getSourceDataLine(f);
sdl.开放式(f);
sdl.start();
文件file1=新文件(“C:\\scream3.au”);
FileInputStream fis=新的FileInputStream(file1);
//箕斗式掘进机
财政司司长(24);
字节[]数据=新字节[8196];
while(true){
int r=fis.read(数据,0,数据长度);
如果(r==-1)中断;
对于(int i=0;i

[/CODE]

我会手动将线性编码转换为线性编码,每次一个样本,使用中的公式

示例代码(基于OP的代码):


我会手动将线性编码转换为线性编码,每次一个样本,使用中的公式

示例代码(基于OP的代码):


谢谢你的回复!我正在尝试这样做,不幸的是我的数学不是很好。你能帮我吗?这和转换PCM和转换回PCM有什么不同?@Gabe:是一样的。我只是说你不需要写头,使用字节流等等。谢谢你的回复!我正在尝试这样做,不幸的是我的数学不是很好。C你能帮我吗?这和转换成PCM和转换回PCM怎么不一样?@Gabe:是一样的。我只是说你不需要写头,不需要使用字节流等等。
float sample1 = Math.signum(y1)/255.0*(Math.pow(256, Math.abs(y1))-1);
float sample2 = Math.signum(y2)/255.0*(Math.pow(256, Math.abs(y2))-1);
float combined = somethig * sample1 + (1-something) * sample2;
float result = Math.signum(combined)*Math.log(1+255*Math.abs(combined))/Math.log(256);