Android 解码音频数据中的NaN值
我想使用Android 解码音频数据中的NaN值,android,android-mediacodec,pcm,Android,Android Mediacodec,Pcm,我想使用MediaCodec从音频文件中获取pcm样本。我成功地获得了它们,但解码数据中存在NaN值 这是什么意思?如何消除它们 这是我的密码: public float[] getPCMSamples(String audioPath) throws IOException { MediaExtractor extractor = new MediaExtractor(); MediaCodec decoder = null; int byte_num = 0;
MediaCodec
从音频文件中获取pcm样本。我成功地获得了它们,但解码数据中存在NaN值
这是什么意思?如何消除它们
这是我的密码:
public float[] getPCMSamples(String audioPath) throws IOException {
MediaExtractor extractor = new MediaExtractor();
MediaCodec decoder = null;
int byte_num = 0;
extractor.setDataSource(audioPath);
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; ++i) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("audio/")) {
extractor.selectTrack(i);
decoder = MediaCodec.createDecoderByType(mime);
decoder.configure(format, null, null, 0);
int rate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
int channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
long duration = format.getLong(MediaFormat.KEY_DURATION);
duration = (duration / 1000000) + 1;
int bitspersample = 16;
//compute how much byte required for whole song
byte_num = (rate * channels * (int) duration * bitspersample) / 8;
}
}
//Decode
decoder.start();
ByteBuffer[] inputBuffers = decoder.getInputBuffers();
ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
//info for passing to the dequeueOutputBuffer
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
//flag for the end of the stream
boolean isEOS = false;
//holding bytes obtained from each outputBuffer
byte[] decodedBytes = new byte[byte_num];
//index of decoded bytes so far
int decodedIdx = 0;
//Start decoding
while (true) {
//fill inputBuffer with audio encoded data
if (!isEOS) {
int inputBufferIndex = decoder.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
int sampleSize = extractor.readSampleData(inputBuffers[inputBufferIndex], 0);
if (sampleSize < 0) {
decoder.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
isEOS = true;
} else {
decoder.queueInputBuffer(inputBufferIndex, 0, sampleSize, extractor.getSampleTime(), 0);
extractor.advance();
}
}
}
int outputBufIndex = decoder.dequeueOutputBuffer(info, 10000);
if (outputBufIndex >= 0) {
Log.d(TAG, "got frame, size " + info.size + "/" + info.presentationTimeUs);
ByteBuffer buffer = outputBuffers[outputBufIndex];
byte[] temp = new byte[buffer.remaining()];
buffer.get(temp);
System.arraycopy(temp, 0, decodedBytes, decodedIdx, temp.length);
decodedIdx += temp.length;
decoder.releaseOutputBuffer(outputBufIndex, false /* render */);
if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
Log.d(TAG, "saw output EOS.");
break;
}
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = decoder.getOutputBuffers();
Log.d(TAG, "output buffers have changed.");
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat oformat = decoder.getOutputFormat();
Log.d(TAG, "output format has changed to " + oformat);
} else {
Log.d(TAG, "dequeueOutputBuffer returned " + outputBufIndex);
}
}
decoder.stop();
decoder.release();
FloatBuffer floatBuffer = ByteBuffer.wrap(decodedBytes).asFloatBuffer();
float[] decoded = new float[floatBuffer.remaining()];
floatBuffer.get(decoded);
return decoded;
}
public float[]getPCMSamples(字符串音频路径)引发IOException{
MediaExtractor提取器=新的MediaExtractor();
MediaCodec解码器=空;
int byte_num=0;
提取器.setDataSource(audioPath);
int numTracks=extractor.getTrackCount();
对于(int i=0;i=0){
int sampleSize=extractor.readSampleData(inputBuffers[inputBufferIndex],0);
如果(样本大小<0){
解码器.queueInputBuffer(inputBufferIndex,0,0,MediaCodec.BUFFER\u标志\u结束\u流);
isEOS=真;
}否则{
decoder.queueInputBuffer(inputBufferIndex,0,sampleSize,提取器.getSampleTime(),0);
提取器;
}
}
}
int outputBufIndex=decoder.dequeueOutputBuffer(信息,10000);
如果(outputBufIndex>=0){
Log.d(标记“got frame,size”+info.size+“/”+info.presentationTimeUs);
ByteBuffer buffer=outputBuffers[outputBufIndex];
byte[]temp=新字节[buffer.remaining()];
buffer.get(temp);
系统阵列复制(温度,0,解码字节,解码字节,温度长度);
decodedIdx+=温度长度;
decoder.releaseOutputBuffer(outputBufIndex,false/*render*/);
if(info.flags==MediaCodec.BUFFER\u FLAG\u结束\u流){
Log.d(标签“saw输出EOS”);
打破
}
}else if(outputBufIndex==MediaCodec.INFO\u输出\u缓冲区\u已更改){
outputBuffers=解码器。getOutputBuffers();
d(标记“输出缓冲区已更改”);
}else if(outputBufIndex==MediaCodec.INFO\u输出\u格式\u更改){
MediaFormat of格式=解码器.getOutputFormat();
Log.d(标记,“输出格式已更改为”+oformat);
}否则{
Log.d(标记“dequeueOutputBuffer returned”+outputBufIndex);
}
}
解码器。停止();
decoder.release();
FloatBuffer FloatBuffer=ByteBuffer.wrap(decodedBytes.asFloatBuffer();
float[]decoded=新的float[floatBuffer.remaining()];
floatBuffer.get(解码);
返回解码;
}
android上的原始解码音频通常是16位整数,而不是浮点数。因此,不要使用FloatBuffer
,而是使用ShortBuffer
NaN不是一个数字。当你尝试做一些不可能的事情,比如除以0,你就会得到它。要获得它们,要么是算法错误(需要防止那些不可能的操作),要么是数据错误。找出其中一个并修复它。