Android:播放PCM文件时出错

Android:播放PCM文件时出错,android,audio,pcm,Android,Audio,Pcm,我试图播放一个PCM文件,该文件是在从麦克风录制音频时创建的 我使用录音是因为我想分析麦克风录制的声音的频率 播放PCM文件的代码片段如下所示。但是当我试着播放文件时,有一个很大的噪音正在播放 FileInputStream fis=null; File l=null; l=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/f1.pcm"); byte[] buff

我试图播放一个PCM文件,该文件是在从麦克风录制音频时创建的

我使用录音是因为我想分析麦克风录制的声音的频率

播放PCM文件的代码片段如下所示。但是当我试着播放文件时,有一个很大的噪音正在播放

FileInputStream fis=null;
    File l=null;
    l=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/f1.pcm");

    byte[] buffer=new byte[(int)l.length()];

    try {
        fis = new FileInputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Notate/f1.pcm");
        fis.read(buffer);
    }
    catch(Exception e)
    {

    }
    int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);
    if (at!=null) {
        at.play();
        at.write(buffer, 0, buffer.length);
        at.stop();
        at.release();
    }
用于存储PCM文件的代码如下所示

private class RecordAudio extends AsyncTask<Void, Double, Void> {
    FileOutputStream os = null;
    BufferedOutputStream bos =null;
    DataOutputStream dos = null;
    @Override
    protected Void doInBackground(Void... params) {
        int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioEncoding);                // Gets the minimum buffer needed
        AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioEncoding, bufferSize);   // The RAW PCM sample recording
        File f=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/");
        if(!f.isDirectory()) {
            File newDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Notate/");
            newDirectory.mkdirs();
        }
        String filepath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/f1.pcm";
        short[] buffer = new short[blockSize];          // Save the raw PCM samples as short bytes
        try{
            os=new FileOutputStream(filepath);
        }
        catch(FileNotFoundException e)
        {

        }
        bos = new BufferedOutputStream(os);
        dos = new DataOutputStream(bos);
        try {
            audioRecord.startRecording();  //Start
        } catch (Throwable t) {
        }
        while (started) {
            int length=audioRecord.read(buffer, 0, blockSize);

            Yin alpha = new Yin(44100, 1024, 0.2);
            float[] floaters = new float[buffer.length];
            for (int i = 0; i < buffer.length; i++) {
                floaters[i] = buffer[i];
            }
            for(int k=0;k<length;k++) {
                try {
                    dos.writeShort(buffer[k]);


                } catch (IOException e) {

                }
            }
            float result = alpha.getPitch(floaters);
            publishProgress((double) result);

        }
        try{
            dos.close();
        }
        catch(IOException e){
            e.printStackTrace();
        }

        return null;
    }
私有类RecordAudio扩展异步任务{
FileOutputStream os=null;
BufferedOutputStream bos=null;
DataOutputStream dos=null;
@凌驾
受保护的Void doInBackground(Void…参数){
int bufferSize=AudioRecord.getMinBufferSize(sampleRate、channelConfig、audioEncoding);//获取所需的最小缓冲区
AudioRecord AudioRecord=新的音频记录(音频源、采样器、信道配置、音频编码、缓冲区大小);//原始PCM样本记录
文件f=新文件(Environment.getExternalStorageDirectory().getAbsolutePath()+“/Notate/”;
如果(!f.isDirectory()){
File newDirectory=新文件(Environment.getExternalStorageDirectory().getAbsolutePath()+“/Notate/”;
newDirectory.mkdirs();
}
字符串filepath=Environment.getExternalStorageDirectory().getAbsolutePath()+“/Notate/f1.pcm”;
short[]buffer=new short[blockSize];//将原始PCM样本保存为短字节
试一试{
os=新的FileOutputStream(filepath);
}
catch(filenotfounde异常)
{
}
bos=新的缓冲输出流(os);
dos=新数据输出流(bos);
试一试{
audioRecord.startRecording();//开始
}捕获(可丢弃的t){
}
while(启动){
int length=audioRecord.read(缓冲区,0,块大小);
阴α=新阴(4410010240.2);
float[]浮点数=新浮点数[buffer.length];
for(int i=0;i对于(int k=0;k
writeShort
以大端字节布局写入值,即最高有效字节排在第一位,而
AudioTrack
可能期望样本为小端字节(最低有效字节排在第一位)

如果在录制时使用
byte[]
而不是
short[]
,您将使事情变得更简单。然后,您可以使用
dos.write(缓冲区,0,长度);
简单地写入
DataOutputStream
。在这种情况下,您对浮点值的转换必须稍微修改一下:

for (int i = 0; i < length; i += 2) {
    floaters[i] = (short)(buffer[i] | (buffer[i+1] << 8));
}
for(int i=0;i