2015-12-28 16 views
18

私のAndroidアプリでは、スマートフォンのマイクからいくつかの音声を取り込んで、ただちにマイクのように遅れなく再生したいと思います。私は現在、AudioRecordAudioTrackのクラス(私が読んだもの)を使用することを考えていますが、どのように進めるべきかについてはあまりよく分かりません。即時音声入力&出力Android

私はスタックオーバーフローに関するその他の質問をチェックしましたが、私は何をしたいのか正確に答えていません。そして、ほとんどは2012年からです。

これらのクラスを使用して、同時にオーディオを入出力するにはどうすればよいですか?

私はMediaRecorder APIを見ましたが、私が読んだところでは、オーディオをファイルに保存する必要がありますが、これは望ましくありません。私の要求を満たすためにそれを二本にすることはできますか?または、私はちょうどを使用してより良いですか?

おかげ

EDIT:

final Thread record = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (!Thread.interrupted()) { 
       MediaRecorder microphone = new MediaRecorder(); 
       microphone.setAudioSource(MediaRecorder.AudioSource.MIC); 
        microphone.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
       microphone.setOutputFile(filename); 
       microphone.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
       try { 
        microphone.prepare(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       microphone.start(); 
      } 
     } 
    }); 

    final Thread play = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      while (!Thread.interrupted()) { 
       player = new MediaPlayer(); 
       try { 
        player.setDataSource(filename); 
        player.prepare(); 
        player.start(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    }); 

を私はIllegal State Exception | Start failed: -38を取得しています:ここで

を@Pradip Pramanickが示唆されているように以下の私の更新されたコードです。しかし、私はmicrophone.startの後にmicrophone.prepareと呼んでいます...何が問題だと思われますか?マイクを使っている他のバックグラウンドアプリがあるかもしれないと言った他のスレッドを検索しました。私は自分のデバイスを検索しました:Moto X Play(第3世代)は見つかりませんでした。 (私は「OK Google」の音声認識をオフにしていたが、エラーは続いていた)。

ERRORログ:ここ

は、最新のエラーを示すログ-猫です:IO例外がplayer.setDataSource(filename)であるように思わ

01-31 09:37:21.064 344-3339/? E/MediaPlayerService: offset error 
01-31 09:37:21.065 1835-1922/com.synerflow.testapp E/MediaPlayer: Unable to create media player 

01-31 09:37:21.065 1835-1922/com.synerflow.testapp I/Player: player.prepare() has failed 
01-31 09:37:21.065 1835-1922/com.synerflow.testapp W/System.err: java.io.IOException: setDataSourceFD failed.: status=0x80000000 

、ファイル名の変数は文字列です。Environment.getExternalStorageDirectory().getAbsolutePath() + "\voice.3gp"

+0

なぜこのようにしたいのですか? –

+0

@ ste-fuちょっと試してみてください。あなたはこれを行う方法を知っていますか? – SynerFlow

+1

このようなストリームを転送できるだけである必要がありますhttp://stackoverflow.com/questions/5381969/android-how-to-record-mp3-radio-audio-stream/5384161#5384161たぶん、小さなバッファもあります。なぜ本当に疑問に思っています。もしあなたがそうしたら、あなたはオーディオフィードバックにかなり苦しんでしまうでしょうか。 –

答えて

3

私が考える限り、それは非常に簡単な方法で行うことができます。私はそれを試していないが、あなたはそれを試してみてください。私はそれがうまくいくと思います:

再生用に別のものを録音するための2つのスレッドを作成します。 スレッドがTRecordとTPlayであるとします。 TRecordのrunメソッドで

は、この操作を行います。

public void run(){ 
     MediaRecorder mRecorder = null; 
     mRecorder = new MediaRecorder(); 
     mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
     mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
     mRecorder.setOutputFile(mFileName); 
     mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 

     try { 
      mRecorder.prepare(); 
     } catch (IOException e) { 
      //todo 
     } 

     mRecorder.start(); 
} 

をそして、それはTPlayのrunメソッドは、次の操作を行います。mainactivityで今

public void run() { 
MediaPlayer mPlayer = null; 
mPlayer = new MediaPlayer(); 
     try { 
      mPlayer.setDataSource(mFileName); 
      mPlayer.prepare(); 
      mPlayer.start(); 
     } catch (IOException e) { 
      //todo 
     } 
} 

は、単純に二つのスレッドを作成します。最初にTRecordスレッドを起動してからTplayを実行します。それを試してみてください。ここ

は、ファイル拡張子のためのコードです:

mFileName = Environment.getExternalStorageDirectory().getAbsolutePath(); 
mFileName += "/audiorecordtest.3gp"; 
+0

を参照してください。こんにちは、mFileNameは何ですか?それはあらかじめ定義されたファイルですか?また、私は話し終えた後にファイルを取り除きたいです。これはどうすればできますか? – SynerFlow

+0

また、この場合、ファイルの拡張子はどうすればよいでしょうか?出力ファイル/データソースを設定するコードを含めることができますか? – SynerFlow

+0

私はそれを編集しました。 –

2

これは、Android上で、実際には本当に難しいです。 Google自身も非常に良い(しかしわずかに長い)videoを持っています。

これらはまた、さまざまなデバイス用にa page explaining their latency testing methods and benchmarksを持っています。

本質的に、Androidはゼロ遅延オーディオを実行できませんが、ハードウェアパートナーが必要なハードウェアとプラットフォーム拡張を追加するのを止めるものは何もありません。

0

これを試してください。私はこれを実行していない。

 recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
     RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
     RECORDER_AUDIO_ENCODING, bufferSize * BytesPerElement); 

    recorder.startRecording(); 

    isRecording = true; 

    recordingThread = new Thread(new Runnable() { 

    public void run() { 

     try { 
      int intSize = android.media.AudioTrack.getMinBufferSize(RECORDER_SAMPLERATE,AudioFormat.CHANNEL_OUT_MONO , RECORDER_AUDIO_ENCODING); 
      byte[] sData = new byte[bufferSize]; 
      AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, RECORDER_SAMPLERATE, AudioFormat.CHANNEL_OUT_MONO, RECORDER_AUDIO_ENCODING, intSize, AudioTrack.MODE_STREAM); 
      while(isRecording){ 
      recorder.read(sData, 0, bufferSize); //isRecording = false; onStop button 

      if (at!=null) { 
       at.play(); 
       // Write the byte array to the track 
       at.write(sData, 0, sData.length); 
       at.stop(); 
       at.release(); 
      } 
      } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
    }, "AudioRecorder Thread"); 
    recordingThread.start(); 
+0

私のプロジェクトの前の部分の1つで、うまくいきました。それを正しくアセンブルして、サンプルレート44100などの変数を初期化する必要があります。 – kAmol

+0

したがって、動作します。しかし、その声は非常にひどくひどく奇妙です。これが起こっている理由は何ですか?また、 'BytesPerElement'はどれくらいですか? – SynerFlow

+0

サンプルレート44100と 'RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT'を試してください。バッファサイズ= 'AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE、 RECORDER_CHANNELS、RECORDER_AUDIO_ENCODING)'を考慮していただければ幸いです。 動作する場合は、回答としてマークするのを忘れないでください。 :) – kAmol

関連する問題