Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可以写入SourceDataLine的数据的格式是什么?_Java_Audio_Javasound - Fatal编程技术网

Java 可以写入SourceDataLine的数据的格式是什么?

Java 可以写入SourceDataLine的数据的格式是什么?,java,audio,javasound,Java,Audio,Javasound,在java中,您可以创建如下的SourceDataLine: AudioFormat af = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100.0, 16, 1, 2, 44100.0, false); SourceDataLine sdl = AudioSystem.getSourceDataLine(af); 之后,您可以打开并向其中写入数据: byte[] data = new byte[1024]; fillw

在java中,您可以创建如下的SourceDataLine:

AudioFormat af = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100.0, 16, 1, 2, 44100.0, false);       
SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
之后,您可以打开并向其中写入数据:

byte[] data = new byte[1024];
fillwithsounds(data);

sdl.open()
sdl.start()
sdl.write(data, 0, 1024);
这一切都适用于单声道数据

我想做的是能够写入立体声数据,但我在网上找不到任何关于如何更改字节数组以写入立体声数据的文档

当我创建音频格式时,我似乎需要增加频道的数量——使其成为立体声——然后我需要将帧速率降低一半(否则Java会抛出一个IllegalArgumentException)

我不明白为什么会这样,也不明白我向DataSourceLine提供的数据的新格式应该是什么


也许有人在音频格式方面比我有更多的经验,我可以对这个问题有所了解。提前谢谢

我刚刚找到了解决方案,安德鲁·汤普森的评论正好解释了我需要什么

我想每个帧必须写两次,让我抓狂的是,Java不允许我只使用单声道的帧大小。(它抛出了一个非法的ArgumentException)

所以我将帧速率减半以满足Java的要求,但我不记得修改字节数组

我已经实现了一段代码,它接受“每帧2字节,1通道”字节[],并将其转换为“每帧1字节,2通道”字节[]

private static final float LEFT=-1;
专用静态最终浮动中心=0;
私有静态最终浮动权=1;
专用字节[]monoToStereo(字节[]数据,浮点平移){
字节[]输出=新字节[data.length];
对于(int i=0;i<(data.length-2);i+=2){
int currentvalue=(数据[i+1]*256+数据[i])/(256*2);
如果(盘==左| |盘==中心){
输出[i]=(字节)电流值;
}否则{
输出[i]=0;
}
如果(平移==右| |平移==中心){
输出[i+1]=(字节)电流值;
}否则{
输出[i+1]=0;
}
}
返回输出;
}

使用此功能,我可以播放立体声音频(虽然有软静态,但我可以清晰地听到原始曲目)

我用于立体声的格式如下:

        audioFmt = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
            44100, 16, 2, 4, 44100, false);
您可能希望将每帧字节数增加一倍,而不是将编码位减半。我不确定8位编码听起来像什么,但它肯定会比16位编码噪音更大

结果文件的长度是原来的两倍。然后,您可以获取构成16位采样的两个字节对,并将它们复制到下两个位置,以进行“单声道”播放(两个立体声通道完全相同)

鉴于:

frame = F
little end byte = A
big end byte = B
AB = 16-bit little-endian encoding
left channel = L
right channel = R
您的原始单声道:

F1A,F1B,F2A,F2B,F3A,F3B

使用上述格式的立体声:

F1AL,F1BL,F1AR,F1BR,F2AL,F2BL,F2AR,F2BR,F3AL,F3BL,F3AR,F3BR


我很可能把左右顺序搞混了。但我希望你能明白

我的理论是,不是由单帧,单帧,单帧组成的字节数组。字节数组现在应该由左帧、右帧、左帧、右帧、左帧、右帧组成。我试图实现它,但它没有给我任何合理的东西,而是给了我静态的东西。“在这之后,你可以打开它,然后向它写入数据:这一切对于mono数据来说都很好。”好的,你差不多做到了。无论您以原始格式为每个16字节帧写入什么,都要写入两次。这实际上是“通过两个扬声器进行单声道”,但如果您有不同的内容要写入另一个频道,请改为写入。“我试图实现这一点,但是…”为了更快地获得更好的帮助,请发布一条消息。谢谢,我编写此函数是为了实现您的理论,但我得到了一个非常奇怪的结果:我使用的正是你在回答的第一行中提到的音频格式。我将用我对“一个非常奇怪的结果”的定义写一个新的注释,以查看“一个非常奇怪的结果”与Pastebin函数的比较是否正常。我把这两份文件胡编乱造了。它说它们都使用32位编码(不是16位),并且标记为单声道。因此,原始文件每帧使用4个字节,而不是2个字节。您是否将输出格式设置为有2个通道?为什么结果是单核细胞增多?我不知道如何在Java中将32位转换为16位。我使用Audacity进行复杂的转换(除了单声道到立体声,反之亦然)。您可以将循环扩展为增量i乘以4,并在每个循环中传输4个字节(并相应地调整输出格式,为每帧2个通道和8个字节),并保留32位编码。很抱歉,这些文件是回放的录制。我不确定如何准确地从Java写回文件,但我可以研究一下。那么,验证以下内容会很有帮助:向我们展示原始wav文件的数据格式,向我们展示SDL使用的格式。需要再次检查所有值是否符合预期!
frame = F
little end byte = A
big end byte = B
AB = 16-bit little-endian encoding
left channel = L
right channel = R