【问题标题】:Reading and playing audio file读取和播放音频文件
【发布时间】:2014-05-01 20:19:24
【问题描述】:

我在 Android 2.0.1 (Motorola Droid A855) 上阅读和播放某些音频剪辑时遇到了一些问题。下面是我使用的代码段。它适用于某些文件,但对于其他文件,它只是不退出 while 循环。我试过检查

InputStream.available()

方法,但没有运气。我什至在卡住之前打印出了它正确读取的字节数。它似乎在最后一轮读取时卡在了循环中(剩余少于

    int sampleFreq = 44100;
    int minBufferSize = AudioTrack.getMinBufferSize(sampleFreq, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
    int bufferSize = 512;
    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sampleFreq, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);


    InputStream input;
    try {
        File fileID=new File(Environment.getExternalStorageDirectory(),resourceID);
        input = new FileInputStream( fileID);
        int filesize=(int)fileID.length();
        int i=0,byteread=0;     
        byte[] s = new byte[bufferSize];

        at.play();
        while((i = input.read(s, 0, bufferSize))>-1){
             at.write(s, 0, i);
             //at.flush(); 
             byteread+=i;
             Log.i(TAG,"playing audio "+byteread+"\t"+filesize);
        }

        at.stop();  
        at.release();
        input.close();


    } catch (FileNotFoundException e) {
        // TODO
        e.printStackTrace();
    } catch (IOException e) {
        // TODO
        e.printStackTrace();
    }       

音频文件大小约为 1-2MB,格式为 wav。以下是日志记录的示例-

> : playing audio 1057280   1058474
> : playing audio 1057792   1058474
> : playing audio 1058304   1058474

知道为什么会发生这种情况,因为它对某些音频文件运行完美。

【问题讨论】:

  • 它是怎么卡住的——它是反复得到一个意想不到的返回值,还是阻塞了?
  • 它只是阻止我猜,因为它没有退出 while 循环(我做/调用其他东西的地方)。我的主要问题是为什么它没有完成整个文件的读取。对于有效的文件,我看到代码读取整个文件(例如,bytesread = filesize)
  • 这是一个无效的假设,不是我查询的答案。阻塞意味着 read() 方法永远不会返回。但它很可能返回一个不会导致循环退出的值。您的日志调用应该显示正在发生的事情。
  • 我看到下面的日志——getBuffer超时(CPU挂了吗?)
  • 取出 at.write() 行,这样您就只是丢弃了数据,并通过仅读取文件来查看您获得的缓冲区大小。也许你得到一个奇怪的返回值,并且用那个大小调用 write 是不合法的。您可能还应该(暂时)在您尝试写入之前移动您的大小日志记录调用,这样您就知道您将在 实际调用它之前调用 write() 的大小。

标签: java android audio


【解决方案1】:

确保您对 write() 的调用始终提供整数个样本的字节大小。

对于您的 16 位立体声模式,它应该是 4 字节的整数倍。

此外,至少在最终写入之前,为了实现无卡顿操作,您应该真正尊重音频子系统的最小缓冲区大小,并在每次调用音频写入方法时至少提供同样多的数据。

如果您的源数据是 .wav 文件,请确保您实际上跳过了标头并仅从有效负载块开始读取样本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多