Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android音频录制到wav_Android_Audio_Audio Recording_Android Audiomanager_Android Audiorecord - Fatal编程技术网

Android音频录制到wav

Android音频录制到wav,android,audio,audio-recording,android-audiomanager,android-audiorecord,Android,Audio,Audio Recording,Android Audiomanager,Android Audiorecord,我用Android上的录音机录制了一段音频,它生成了一个原始PCM文件。我正试图把它转换成我可以听的格式(例如wav或mp3) 我从这个例子开始,但不知道从这里开始: 以下是: 这是我要录制的代码(注意,我使用倒计时来告诉它何时开始和停止录制 public class AudioRecordService extends Service { Toast toast; private static final int RECORDER_SAMPLERATE = 44100;

我用Android上的录音机录制了一段音频,它生成了一个原始PCM文件。我正试图把它转换成我可以听的格式(例如wav或mp3)

我从这个例子开始,但不知道从这里开始:

以下是:

这是我要录制的代码(注意,我使用倒计时来告诉它何时开始和停止录制

public class AudioRecordService extends Service {
    Toast toast;
    private static final int RECORDER_SAMPLERATE = 44100;
    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
    private AudioRecord record = null;
    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
    int BytesPerElement = 2; // 2 bytes in 16bit format
    private Thread recordingThread = null;
    private boolean isRecording = false;
    int buffsize = 0;

    public AudioRecordService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public int onStartCommand(Intent intent, int flags, int startId)
    {
        try {
            buffsize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);

            record = new AudioRecord(MediaRecorder.AudioSource.MIC,
                RECORDER_SAMPLERATE, RECORDER_CHANNELS,
                RECORDER_AUDIO_ENCODING, buffsize);

            record.startRecording();

            CountDownTimer countDowntimer = new CountDownTimer(15000, 1000) {
                public void onTick(long millisUntilFinished) {
                    toast = Toast.makeText(AudioRecordService.this, "Recording", Toast.LENGTH_SHORT);
                    toast.show();
                    isRecording = true;
                    recordingThread = new Thread(new Runnable() {
                        public void run() {
                            writeAudioDataToFile();
                        }
                    }, "AudioRecorder Thread");
                    recordingThread.start();
                }

                public void onFinish() {
                    try {
                        toast.cancel();
                        Toast.makeText(AudioRecordService.this, "Done Recording ", Toast.LENGTH_SHORT).show();
                        isRecording = false;
                        record.stop();
                        record.release();
                        record = null;
                        recordingThread = null;
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }


            }};
            countDowntimer.start();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return Service.START_STICKY;
    }

    private byte[] short2byte(short[] sData) {
        int shortArrsize = sData.length;
        byte[] bytes = new byte[shortArrsize * 2];
        for (int i = 0; i < shortArrsize; i++) {
            bytes[i * 2] = (byte) (sData[i] & 0x00FF);
            bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
            sData[i] = 0;
        }
        return bytes;

    }

    private void writeAudioDataToFile() {
        try {
            //String filePath = "/sdcard/voice8K16bitmono.pcm";
            String extState = Environment.getExternalStorageState();
            // Path to write files to
            String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC + "/test").getAbsolutePath();

            String fileName = "audio.pcm";
            String externalStorage = Environment.getExternalStorageDirectory().getAbsolutePath();
            File file = new File(externalStorage + File.separator + fileName);

            // if file doesnt exists, then create it
            if (!file.exists()) {
                file.createNewFile();
            }
            short sData[] = new short[BufferElements2Rec];

            FileOutputStream os = null;
            try {
                os = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            while (isRecording) {
                // gets the voice output from microphone to byte format

                record.read(sData, 0, BufferElements2Rec);
                System.out.println("Short wirting to file" + sData.toString());
                try {
                    // // writes the data to file from buffer
                    // // stores the voice buffer
                    byte bData[] = short2byte(sData);
                    os.write(bData, 0, BufferElements2Rec * BytesPerElement);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
公共类AudioRecordService扩展服务{
吐司;
专用静态最终积分记录仪\u采样器=44100;
专用静态最终整数记录器\u通道=单声道中的AudioFormat.CHANNEL\u;
专用静态最终整数记录器\u音频\u编码=AudioFormat.ENCODING\u PCM\u 16位;
私人录音记录=空;
int BufferElements2Rec=1024;//要播放2048(2K),因为我们只使用1024个字节
int bytesperement=2;//16位格式的2个字节
私有线程recordingThread=null;
私有布尔值isRecording=false;
int buffsize=0;
公共录音服务{
}
@凌驾
公共IBinder onBind(意向){
//TODO:将通信通道返回到服务。
抛出新的UnsupportedOperationException(“尚未实现”);
}
公共int onStartCommand(Intent Intent、int标志、int startId)
{
试一试{
buffsize=AudioRecord.getMinBufferSize(单声道中的RECORDER\u SAMPLERATE、AudioFormat.CHANNEL\u、AudioFormat.ENCODING\u PCM\u 16位);
记录=新的音频记录(MediaRecorder.AudioSource.MIC,
记录仪采样器、记录仪通道、,
录音机\音频\编码,大小);
record.startRecording();
倒数计时器倒数计时器=新的倒数计时器(15000,1000){
公共void onTick(长毫秒未完成){
toast=toast.makeText(AudioRecordService.this,“录音”,toast.LENGTH\u SHORT);
toast.show();
isRecording=true;
recordingThread=新线程(new Runnable()){
公开募捐{
WriteeAudioDataToFile();
}
}“录音机线程”);
recordingThread.start();
}
公共无效onFinish(){
试一试{
toast.cancel();
Toast.makeText(AudioRecordService.this,“录制完毕”,Toast.LENGTH_SHORT.show();
isRecording=false;
record.stop();
record.release();
记录=null;
recordingThread=null;
}捕获(例外e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}};
countDowntimer.start();
}
捕获(例外情况除外)
{
例如printStackTrace();
}
return Service.START\u STICKY;
}
专用字节[]短2字节(短[]sData){
int shortArrsize=sData.length;
字节[]字节=新字节[shortArrsize*2];
对于(int i=0;i>8);
sData[i]=0;
}
返回字节;
}
私有void writeeAudioDataToFile(){
试一试{
//String filePath=“/sdcard/voice8K16bitmono.pcm”;
字符串extState=Environment.getExternalStorageState();
//将文件写入的路径
String path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC+“/test”).getAbsolutePath();
字符串fileName=“audio.pcm”;
字符串externalStorage=Environment.getExternalStorageDirectory().getAbsolutePath();
File File=新文件(externalStorage+File.separator+fileName);
//如果文件不存在,则创建它
如果(!file.exists()){
createNewFile();
}
短sData[]=新短[BufferElements2Rec];
FileOutputStream os=null;
试一试{
os=新文件输出流(文件);
}catch(filenotfounde异常){
e、 printStackTrace();
}
while(isRecording){
//获取从麦克风到字节格式的语音输出
记录读取(sData,0,BufferElements2Rec);
System.out.println(“短连接到文件”+sData.toString());
试一试{
////将数据从缓冲区写入文件
////存储语音缓冲区
字节bData[]=short2byte(sData);
写入(bData,0,BufferElements2Rec*bytesperement);
}捕获(IOE异常){
e、 printStackTrace();
}
}
试一试{
os.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
捕获(例外情况除外){
例如printStackTrace();
}
}
}
我的audio.pcm已创建。但是我不知道如何播放它。我假设bDate[]是正在写入的字节数组。我创建的链接说他们使用了这些文件,但没有显示如何执行的示例

如果有关系的话,我已经用GoldWave打开了这个文件。它打开了,但是音频被弄乱了

我还注意到我的文件是2秒,我想这是因为BytesPerElement和BufferElements2Rec。如果你能帮我解决这个问题,那将是15秒,那就太好了


提前感谢!

PCM文件和WAV文件之间的唯一区别是PCM文件没有头,而WAV文件有头。WAV头有播放suc的关键信息
private byte[] wavFileHeader(long totalAudioLen, long totalDataLen, long longSampleRate,
      int channels, long byteRate, byte bitsPerSample) {
    byte[] header = new byte[44];
    header[0] = 'R'; // RIFF/WAVE header
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f'; // 'fmt ' chunk
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = 16; // 4 bytes: size of 'fmt ' chunk
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1; // format = 1
    header[21] = 0;
    header[22] = (byte) channels;
    header[23] = 0;
    header[24] = (byte) (longSampleRate & 0xff);
    header[25] = (byte) ((longSampleRate >> 8) & 0xff);
    header[26] = (byte) ((longSampleRate >> 16) & 0xff);
    header[27] = (byte) ((longSampleRate >> 24) & 0xff);
    header[28] = (byte) (byteRate & 0xff);
    header[29] = (byte) ((byteRate >> 8) & 0xff);
    header[30] = (byte) ((byteRate >> 16) & 0xff);
    header[31] = (byte) ((byteRate >> 24) & 0xff);
    header[32] = (byte) (channels * (bitsPerSample / 8)); //
    // block align
    header[33] = 0;
    header[34] = bitsPerSample; // bits per sample
    header[35] = 0;
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    header[40] = (byte) (totalAudioLen & 0xff);
    header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
    header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
    header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
    return header;
  }
private byte[] createAdtsHeader(int length) {
        int frameLength = length + 7;
        byte[] adtsHeader = new byte[7];

        adtsHeader[0] = (byte) 0xFF; // Sync Word
        adtsHeader[1] = (byte) 0xF1; // MPEG-4, Layer (0), No CRC
        adtsHeader[2] = (byte) ((MediaCodecInfo.CodecProfileLevel.AACObjectLC - 1) << 6);
        adtsHeader[2] |= (((byte) SAMPLE_RATE_INDEX) << 2);
        adtsHeader[2] |= (((byte) CHANNELS) >> 2);
        adtsHeader[3] = (byte) (((CHANNELS & 3) << 6) | ((frameLength >> 11) & 0x03));
        adtsHeader[4] = (byte) ((frameLength >> 3) & 0xFF);
        adtsHeader[5] = (byte) (((frameLength & 0x07) << 5) | 0x1f);
        adtsHeader[6] = (byte) 0xFC;

        return adtsHeader;
    }