gpt4 book ai didi

java - MP3 文件在读取过程中失真

转载 作者:行者123 更新时间:2023-12-02 05:45:11 24 4
gpt4 key购买 nike

我目前正在开发一个播放声音的应用程序。我使用 Java Sound API 实现了标准 WAV 文件的播放,没​​有任何问题,一切正常。现在我也想添加对 MP3 的支持,但我遇到了一个奇怪的问题:播放失真。我正在努力找出我做错了什么,我将不胜感激任何正确方向的引导。我正在使用 Mp3SPI ( http://www.javazoom.net/mp3spi/documents.html ) 来播放 Mp3 文件。

我已经尝试查看输出并用从 mp3 获得的输出录制了一个 wav 文件,然后比较了原始文件和录制文件的波形。事实证明,在录制的文件中,有很多样本为 0,或者非常接近 0。较长的音调会被分解,波形始终返回到 0,然后跳回到原始波形所在的位置。

我像这样打开文件:


private AudioInputStream mp3;
private AudioInputStream rawMp3;

private void openMP3(File file) {

// open the Audio INput Stream
try {
rawMp3 = AudioSystem.getAudioInputStream(file);
AudioFormat baseFormat = rawMp3.getFormat();
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false);
mp3 = AudioSystem.getAudioInputStream(decodedFormat, rawMp3);
} catch (UnsupportedAudioFileException | IOException ex) {
Logger.getLogger(SoundFile.class.getName()).log(Level.SEVERE, null, ex);
}
}

我读取Mp3文件的部分:

byte[] data = new byte[length];    
// read the data into the buffer
int nBytesRead = 0;
while (nBytesRead != - 1 && nBytesRead < length) {
nBytesRead = mp3.read(data, 0, data.length - nBytesRead);
}

我还将字节数组转换为 double ,也许我在这里做错了什么(我对使用按位运算符相当陌生,所以也许存在问题

double[][] frameBuffer = new double[2][1024]; // 2 channel stereo buffer
int nFramesRead = 0;
int byteIndex = 0;
// convert the data into double and write it to frameBuffer
for (int i = 0; i < length; ++i) {
for (int c = 0; c < 2; ++c) {
byte a = data[byteIndex++];
byte b = data[byteIndex++];
int val = a | b << 8; // a is the least significant byte. | functions as a + here. b << 8 moves 8 zeroes to the end of b.
frameBuffer[c][i] = (double) val / (double) Short.MAX_VALUE;
nFramesRead++;
}
}

随后使用双阵列来播放声音。当播放 wav 文件时,我对缓冲区做了完全相同的事情,所以我很确定它必须是在读取过程中发生的事情,而不是我向输出发送错误的字节。

我希望它可以在 Mp3SPI 中开箱即用,但不知何故,某些东西会破坏音频。如果您有任何建议,我也愿意尝试其他库来播放 MP3。实际上,只需一个原始 MP3 数据的解码器就足够了。

最佳答案

事实证明,mp3(输入)的 AudioFormat 和输出的 AudioFormat 不匹配,显然导致了失真。因此,将这些匹配后,播放就可以了!

关于java - MP3 文件在读取过程中失真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56102143/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com