android - AudioRecorder无法正确录制

标签 android audio timer

我正在尝试使用AudioRecorder在一定时间间隔(对应于一定数量的样本)中记录一个wav文件。停止录音我用Timer().schedule(delay)停止了一段时间。但是无论该延迟的值是多少,文件总是大小相同,并且不可读。

public class Record extends Activity {
private static final int RECORDER_SAMPLERATE = 44100;
int compt=0;
int duration=1;
//int numSample= duration*RECORDER_SAMPLERATE;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;

private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private volatile Thread recordingThread=null;
private volatile boolean isRecording = false;

int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 
long mySubChunk1Size = 16;
short myBitsPerSample= 16;
int myFormat = 1;
int myChannels = 1;
long myByteRate =RECORDER_SAMPLERATE* myChannels * myBitsPerSample/8;
int myBlockAlign = myChannels * myBitsPerSample/8;
Handler handler;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/recordedSound"+compt+".wav";
DataOutputStream dd;

@Override
public void onCreate(Bundle savedInstanceState)  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_raw_rec);
    try
    {
        try {

            startRec();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        new Timer().schedule(new TimerTask()
        {
            @Override
            public void run()
            {

                recordingThread.interrupt();
                recordingThread=null;
                isRecording=false;
                recorder.stop();
                recorder.release();
                recorder = null;



            }

        }
        ,5000); //execute after 5 seconds of recording

    }//end try
    catch(IllegalStateException e) {
        e.printStackTrace();
    }

}


private void startRec() throws IOException{
    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);

    recorder.startRecording();


    isRecording = true;
    recordingThread = new Thread(new Runnable() {
        public void run() {
            writeToFile();
        }
    }, "AudioRecorder Thread");
    recordingThread.start();

}




private void writeToFile() {
    // Write the output audio in byte

    byte[] data= new byte[bufferSize];


    while (isRecording) {
        try{
            recorder.read(data, 0, bufferSize);
            Log.d("recorder value", "value"+recorder);
        }
        catch (NullPointerException e)
        {
            e.printStackTrace();
        }
        try {
            // // writes the data to file from buffer
            // // stores the voice buffer
            dd=new DataOutputStream( new FileOutputStream(filePath));

            dd.writeBytes("RIFF");
            dd.writeInt(0); // Final file size not known yet, write 0 
            dd.writeBytes("WAVE");
            dd.writeBytes("fmt ");
            dd.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
            dd.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
            dd.writeShort(Short.reverseBytes( (short) myChannels));// Number of channels, 1 for mono, 2 for stereo
            dd.writeInt(Integer.reverseBytes(RECORDER_SAMPLERATE)); // Sample rate
            dd.writeInt(Integer.reverseBytes( (RECORDER_SAMPLERATE*myBitsPerSample*myChannels/8))); // Byte rate, SampleRate*NumberOfChannels*BitsPerSample/8
            dd.writeShort(Short.reverseBytes((short) (myChannels*myBitsPerSample/8))); // Block align, NumberOfChannels*BitsPerSample/8
            dd.writeShort(Short.reverseBytes( myBitsPerSample)); // Bits per sample
            dd.writeBytes("data");
            dd.write(data);
            //dd.close();

        } catch (IOException e) {

            e.printStackTrace();
        }
    }

}

我究竟做错了什么?

最佳答案

您需要在while中的writeToFile循环的每次迭代期间创建一个新的WAV文件。

更好的方法是只将PCM数据缓冲区(不带任何头)写入临时文件。并确保只创建一次FileOutputStream,然后在录制结束时生成RIFF header 并将其写入目标WAV文件,然后再写入临时文件的内容。

关于android - AudioRecorder无法正确录制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24327417/

相关文章:

java - 我想要在 oncreate() Activity 之外从另一个类中提取 exoplayer 中的 YouTube 链接

java - 如何使用 Kotlin 或 Java 更改可绘制对象的描边颜色

java - Android 秒表代码更有效的方法?

当其他 channel (同一定时器)具有 i2c 备用功能时,我可以使用不同的定时器 channel 吗

android - 在浏览器中打开 "Platform off"后登录时持续出现 Facebook SDK http.protocol.ApiException

android - Exoplayer播放m3u8文件Android

java - 吉他调音的频率检测

java - 查找播放声音的文件

iphone - 播放声音循环或停止使用AudioServices播放

c++ - 系统时钟和辅助时钟的区别