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,你就会得到它。要获得它们,要么是算法错误(需要防止那些不可能的操作),要么是数据错误。找出其中一个并修复它。