【问题标题】:audiotrack: playing noise for a raw pcm 16bit wav file音轨:为原始 pcm 16 位 wav 文件播放噪音
【发布时间】:2018-09-25 02:25:08
【问题描述】:

我正在尝试播放大小为 230mb 和 20 分钟的 wav 文件,其属性如下:

ffmpeg -i 1.wav

Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s

我正在学习如何使用音轨。

我找到了两种使用音轨播放此音频的解决方案。

方案一:下面播放音频

int frequency = 44100;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration,audioEncoding);

AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
        channelConfiguration, audioEncoding, bufferSize,
        AudioTrack.MODE_STREAM);

int count = 0;
byte[] data = new byte[bufferSize];
try{
    FileInputStream fileInputStream = new FileInputStream(listMusicFiles.get(0).listmusicfiles_fullfilepath);
    DataInputStream dataInputStream = new DataInputStream(fileInputStream);
    audioTrack.play();

    while((count = dataInputStream.read(data, 0, bufferSize)) > -1){
        audioTrack.write(data, 0, count);
    }

    audioTrack.stop();
    audioTrack.release();
    dataInputStream.close();
    fileInputStream.close();
}
catch (FileNotFoundException e){
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

第二种解决方案:播放噪音

int frequency = 44100;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration,audioEncoding);

short[] audiodata = new short[bufferSize];

try {

    DataInputStream dis = new DataInputStream(
            new BufferedInputStream(new FileInputStream(
                    listMusicFiles.get(0).listmusicfiles_fullfilepath)));

    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency,
            channelConfiguration, audioEncoding, bufferSize,
            AudioTrack.MODE_STREAM);

    audioTrack.play();

    while (dis.available() > 0) {
        int i = 0;
        while (dis.available() > 0 && i < audiodata.length) {
            audiodata[i] = dis.readShort();
            i++;
        }
        audioTrack.write(audiodata, 0, audiodata.length);
    }

    dis.close();
} catch (Throwable t) {
    Log.e("AudioTrack", "Playback Failed");
}

我是短样本和字节样本的新手。我试图理解,但并不那么容易。

我可以理解第一个解决方案是使用字节样本,而第二个解决方案是使用短样本。

那么为什么第二个解决方案不起作用。

【问题讨论】:

    标签: android audio pcm


    【解决方案1】:

    short 类型的默认大小是two bytes。你也可以看看this documentation

    音轨有一个推荐的缓冲区大小和采样率,可以使用this answer 中建议的方式找到。请看一下。

    但是,使用建议的采样率(在您的情况下为 44100 Hz)和使用以下代码段获得的建议缓冲区大小播放音频非常重要。

    AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding) 
    

    在您使用short 数组的实现中,缓冲区大小加倍,因此在播放音频时会产生噪音。我建议,您可以考虑使用short 在您的实现中通过将大小除以二来更改缓冲区大小。

    short[] audiodata = new short[(int) bufferSize / 2];
    

    希望您已了解问题所在。

    【讨论】:

    • 现在缓冲区大小如何翻倍。我试过 buffersize/2 仍然有噪音。
    • 你能用bufferSize * 2试试吗(即加倍缓冲区大小)?
    • 如果简而言之缓冲区大小,我指的是本教程here。但是,在this answer 中,它建议增加缓冲区大小。请查看我分享的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 2021-03-04
    相关资源
    最近更新 更多