0

AudioRecord を使用してマイク データを読み取り、RandomAccessFile を使用して wav ファイルに書き込みます。これはコードです:

public class MainActivity extends Activity {
    AudioManager am = null;
    AudioRecord record =null;
    // AudioTrack track =null;
    final int SAMPLE_FREQUENCY = 44100;
    final int SIZE_OF_RECORD_ARRAY = 1024;  // 1024 ORIGINAL
    final int WAV_SAMPLE_MULTIPLICATION_FACTOR = 1;
    int i= 0;
    boolean isPlaying = false;
    private volatile boolean keepThreadRunning;
//  private RandomAccessFile stateFile, stateFileTemp, savToDisk;
    private RandomAccessFile savToDisk;
    private FileDescriptor fd = new FileDescriptor(); 
    private File delFile, renFile;
    String stateFileLoc = Environment.getExternalStorageDirectory().getPath(); 
    // To keep hederWriter() happy
    private short nChannels = 1;
    private int sRate = SAMPLE_FREQUENCY;
    private short mBitsPersample = 16; // represents 16 bits of one PCM sample
    private int payload;

    class MyThread extends Thread{
        private volatile boolean needsToPassThrough;
        // /*
        MyThread(){
            super();
        }

        MyThread(boolean newPTV){
            this.needsToPassThrough = newPTV;
        }
        // */

        // /*
        @Override
        public void run(){
             short[] lin = new short[SIZE_OF_RECORD_ARRAY];
            // byte[] lin = new byte[SIZE_OF_RECORD_ARRAY];
            int num = 0;
            // /*
            if(needsToPassThrough){
                record.startRecording();
                // track.play();
            }
            // */
            while (keepThreadRunning) {
            // while (!isInterrupted()) {
                // num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
                num = record.read(lin, 0, lin.length);
                try {
                    // savToDisk.write(lin); // use only this line if lin is a byte array

                    // use the for loop block below if lin is an array of short
                    for(i=0;i <lin.length; i++)
                        savToDisk.writeShort(Short.reverseBytes(lin[i]));

                    // payload += lin.length; // use this line if lin is an array of byte
                    payload = payload + (lin.length)*2;
                    fd.sync();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                /*
                catch (SyncFailedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                */
            }
            // /*
            record.stop();
            // track.stop();
            record.release();
            // track.release();
            // */
        }
        // */

        // /*
        public void stopThread(){
            keepThreadRunning = false;
        }
        // */
    }

    MyThread newThread;

    private void init() {
        int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
        // Toast.makeText(getApplicationContext(), Integer.toString(min), Toast.LENGTH_SHORT).show(); // Shows 4096
        record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO,
                                 AudioFormat.ENCODING_PCM_16BIT, min);
        // int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        // track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
        am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
        am.setMode(AudioManager.MODE_IN_COMMUNICATION);

        try {
            savToDisk = new RandomAccessFile(stateFileLoc+"/audSampData.wav", "rw");

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            fd = savToDisk.getFD();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

    }

    private void writeHeader(){
        try {
            savToDisk.setLength(0); // Set file length to 0, to prevent unexpected behavior in case the file already existed
            savToDisk.writeBytes("RIFF");
            savToDisk.writeInt(0); // Final file size not known yet, write 0 
            savToDisk.writeBytes("WAVE");
            savToDisk.writeBytes("fmt ");
            savToDisk.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
            savToDisk.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
            savToDisk.writeShort(Short.reverseBytes(nChannels));// Number of channels, 1 for mono, 2 for stereo
            savToDisk.writeInt(Integer.reverseBytes(sRate)); // Sample rate
            savToDisk.writeInt(Integer.reverseBytes(sRate*nChannels*mBitsPersample/8)); // Byte rate, SampleRate*NumberOfChannels*mBitsPersample/8
            savToDisk.writeShort(Short.reverseBytes((short)(nChannels*mBitsPersample/8))); // Block align, NumberOfChannels*mBitsPersample/8
            savToDisk.writeShort(Short.reverseBytes(mBitsPersample)); // Bits per sample
            savToDisk.writeBytes("data");
            savToDisk.writeInt(0); // Data chunk size not known yet, write 0
            fd.sync();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    protected void onResume(){
        super.onResume();
        // newThread.stopThread();
        Log.d("MYLOG", "onResume() called");
        init();
        writeHeader();
        keepThreadRunning = true;
        // */


        // newThread = new MyThread(true);
        newThread = new MyThread(isPlaying);
        newThread.start();

    }

    @Override
    protected void onPause(){
        super.onPause();
        Log.d("MYLOG", "onPause() called");
        newThread.stopThread();
        // android.os.Process.killProcess(android.os.Process.myPid());
        try {
            savToDisk.seek(4);
            savToDisk.writeInt(Integer.reverseBytes(36+payload));
            savToDisk.seek(40);
            savToDisk.writeInt(Integer.reverseBytes(payload));
            savToDisk.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
        payload = 0;
        Log.d("MYLOG","onCreate() called");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        newThread.stopThread();
        // android.os.Process.killProcess(android.os.Process.myPid());
        // killProcess(android.os.Process.myPid());
        // newThread.interrupt();
        // delFile.delete();
         Log.d("MYLOG", "onDestroy() called");
         /*
         try {
            savToDisk.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        */
    }

    public void passStop(View view){
        Button playBtn = (Button) findViewById(R.id.button1);  
        // /*
        if(!isPlaying){
            record.startRecording();
            // track.play();
            isPlaying = true;
            playBtn.setText("Pause");
        }
        else{
           record.stop();
           // track.pause();
           isPlaying=false;
           playBtn.setText("Pass through");
        }
        // */
    }



}  

オーディオ プレーヤーで wav ファイルを再生すると、再生速度が速くなり、フレームがスキップされるようです。この理由は何でしょうか?フレームのスキップの問題はおそらく、writeShort()関数を使用して、オーディオ サンプル データを個別に格納する短い配列の各要素を書き出すという事実によるものだと思いますが、その場合は、データの書き込みを伴う回避策を提案してください。ショートとして(write(byte[])短い配列でオーディオサンプルを取得することを含むメインプロジェクトでこのコードの一部を使用する必要があるため、関数を使用しません)。また、なぜ高速化されるのですか?

4

1 に答える 1

0

これを見てください、この質問は私を正しい軌道に乗せました。

Android : audiorecord クラスを使用してオーディオを録音すると、早送りとして再生されます

于 2014-03-12T18:22:34.427 に答える