gpt4 book ai didi

java - 对于小文件大小,使用 Ogg Vorbis SPI 解码 .ogg 文件失败

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:04:42 29 4
gpt4 key购买 nike

我正在使用 Ogg Vorbis SPI作为解码 .ogg 文件的一种方式。

我用于加载 .ogg 文件并转换为 PCM 的代码片段与文档中建议的代码片段没有太大的不同:

// The streams are valid at this point.
try (InputStream bin = new BufferedInputStream(file.getInputStream(entry) );
AudioInputStream in = AudioSystem.getAudioInputStream(bin) ) {

AudioFormat baseFormat = in.getFormat();
// At this point the format is valid:
// VORBISENC 44100.0 Hz, unknown bits per sample, mono, 1 bytes/frame, 12000.0 frames/second,
// I can't make a Clip directly from this or it will be all buzzy, so I convert to PCM

// Decoding to PCM
AudioFormat decodedFormat =
new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false);

// This is where the issues appear...
AudioInputStream decodedInputStream = AudioSystem.getAudioInputStream(decodedFormat, in);

Clip clip = AudioSystem.getClip();
clip.open(decodedInputStream);

// entry.getName is basically the filename. Any files with '0' frame length didn't get converted properly.
System.out.println("Clip " + entry.getName() + " loaded at " + clip.getFrameLength() + " frame length");

return clip;
} catch { ... }

发生的事情是我正在加载几个小的声音文件,范围从 5K 的低到 32K 的高(ogg 格式)。但是,一些文件无法正确转换为 PCM。我注意到他们都有一些共同点;它们的尺寸范围为 5K - 6K。声音文件似乎在 7K 左右开始正确转换。我通过获取 11K 声音并将其削减直到它不再转换 (~6K) 来对此进行测试

我认为解决这个问题的一种方法是添加一些听不见的噪音来填充大小,但我更愿意只正确转换声音文件而不管大小。除了 API 本身之外,我对声音表示的概念是全新的,我不知道从哪里开始寻找为什么会发生这种情况。

最佳答案

我遇到了和你一样的情况,似乎在编码小文件和不适合原始缓冲区长度的文件时(很幸运)会由于 Vorbis 中的错误而被删除SPI 实现 - 它真的很旧,我希望他们会支持它并修复它。作为解决方法,您可以在 2 个位置修复 DecodedVorbisAudioInputStream.java:

    private int readFromStream(byte[] buffer, int index, int bufferSize_) {
int bytes = 0;
try {
bytes = oggBitStream_.read(buffer, index, bufferSize_);
}
catch (Exception e) {
if (TDebug.TraceAudioConverter)
TDebug.out("Cannot Read Selected Song");
bytes = -1;
}
if (bytes >= 0) {
currentBytes += bytes;
}
return bytes;
}

并从缓冲区读取:

case playState_ReadData:
int result;
index = oggSyncState_.buffer(bufferSize_);
buffer = oggSyncState_.data;
bytes = readFromStream(buffer, index, bufferSize_);
if (TDebug.TraceAudioConverter) {
TDebug.out("More data : " + bytes);
}
// has no data in buffer also
if (bytes == -1 && bufferSize_ - index == 0) {
playState = playState_Done;
if (TDebug.TraceAudioConverter) {
TDebug.out("Ogg Stream empty. Settings playState to playState_Done.");
}
break;
}
else {
if (bytes != -1) {
oggSyncState_.wrote(bytes);
}
if (bytes == 0 && bufferSize_ - index == 0) {
if ((oggPage_.eos() != 0) || (oggStreamState_.e_o_s != 0) || (oggPacket_.e_o_s != 0)) {
if (TDebug.TraceAudioConverter) {
TDebug.out("oggSyncState wrote 0 bytes: settings playState to playState_Done.");
}
playState = playState_Done;
}
if (TDebug.TraceAudioConverter) {
TDebug.out("oggSyncState wrote 0 bytes: but stream not yet empty.");
}
break;
}
}

result = oggSyncState_.pageout(oggPage_);
if (result == 0) {
if (TDebug.TraceAudioConverter) {
TDebug.out("Setting playState to playState_ReadData.");
}
playState = playState_ReadData;
break;
} // need more data
if (result == -1) { // missing or corrupt data at this page position
if (TDebug.TraceAudioConverter)
TDebug.out("Corrupt or missing data in bitstream; setting playState to playState_ReadData");
playState = playState_ReadData;
break;
}

oggStreamState_.pagein(oggPage_);

if (TDebug.TraceAudioConverter)
TDebug.out("Setting playState to playState_WriteData.");
playState = playState_WriteData;
break;

在读取时,它们会忽略已经从缓冲区中读取的字节,因此,它们只会跳过缓冲区中最后读取的字节。

希望对您有所帮助!

关于java - 对于小文件大小,使用 Ogg Vorbis SPI 解码 .ogg 文件失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23747940/

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