2017-02-20 19 views
0

ここで私はアンドロイドスタジオで連続した正弦波を生成するために使用しているコードです。すべてがスレッド内で実行されます。私の質問は:私がaudio.write()を呼び出すと、バッファに残っている可能性のあるデータはどうなりますか?古いサンプルをダンプして新しいセットを書き込むのですか、それとも新しいサンプル配列を残りのサンプルに追加しますか?AudioTrack.write()のバッファ内のデータはどうなりますか

int buffSize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT); 
      //create the AudioTrack object 
      AudioTrack audio = new AudioTrack( AudioManager.STREAM_MUSIC, 
               sr, 
               AudioFormat.CHANNEL_OUT_MONO, 
               AudioFormat.ENCODING_PCM_16BIT, 
               buffSize, 
               AudioTrack.MODE_STREAM); 
      //initialise values for synthesis 
      short samples[]= new short[buffSize]; //array the same size as buffer 
      int amp=10000;       //amplitude of the waveform 
      double twopi = 8.*Math.tan(1.);   //2*pi 
      double fr = 440;      //the frequency to create 
      double ph = 0;       //phase shift 
      //start audio 
      audio.play(); 
      //synthesis loop 
      while (isRunning) 
      { 
       fr=440+4.4*sliderVal; 

       for (int i=0;i<buffSize;i++) 
       { 
         samples[i]=(short)(amp*Math.sin(ph)); 
         ph+=twopi*fr/sr; 
       } 
       audio.write(samples,0,buffSize); 
      } 
      //stop the audio track 
      audio.stop(); 
      audio.release(); 

答えて

0

デバイスの能力に基づいてバッファサイズを正しく設定しています。これは、待ち時間を最小限に抑えるために非常に重要です。

次に、バッファを構築し、それらをハードウェアにチャンクして聞こえるようにします。言うまでもなく「そこに」というものはありません。バッファが構築された後、毎回track.writeにバッファ全体を書き込みます。

以下は私のgenerateToneルーチンです。あなたのものとよく似ています。周波数(Hz)とMSでの期間で、このようなように呼び出されます:

AudioTrack sound = generateTone(440, 250); 

そしてgenerateToneクラス:

private AudioTrack generateTone(double freqHz, int durationMs) { 
    int count = (int)(44100.0 * 2.0 * (durationMs/1000.0)) & ~1; 
    short[] samples = new short[count]; 
    for(int i = 0; i < count; i += 2){ 
     short sample = (short)(Math.sin(2 * Math.PI * i/(44100.0/freqHz)) * 0x7FFF); 
     samples[i + 0] = sample; 
     samples[i + 1] = sample; 
    } 
    AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, 
    AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 
    count * (Short.SIZE/8), AudioTrack.MODE_STATIC); 
    track.write(samples, 0, count); 
    return track; 
} 

AudioTrackあなたが右のアルゴを持っている場合は、音の任意の種類を作成することができますので、涼しいです。 PuredataとCsoundは、Androidでも簡単に使えます。

、フィードバックのための

+0

おかげで(私は実用的なプロジェクトの私の本のAndroidソフトウェア開発 - コレクションにオーディオに大きな章を書いた)右のトラックに私を得ました。次のxサンプルを書き込む前にデバイスがxサンプルを再生したことを確実にするために同期が必要な場合はありますか? – Johan

+0

それを聞いてうれしい!さて、あなたは同期する必要はありませんが、あなたは "続ける"必要があります。バッファー・サイズのブロックをすばやく埋めることができない場合は、スキップまたはドロップアウトが発生します。あなたはそれが聞こえるので、これが起こることを知っています。これは、オーディオ待ち時間の問題のためにAndroidで大きな問題になります。これまで製作されたすべてのAndroid搭載端末は、iOS搭載端末よりも待ち時間が長くなります。信じがたいですが、本当です。 AudioBuffersSizeと呼ばれるGoogleのオープンソースのアプリは、バッファサイズやサンプレートなどのデバイスの機能を示しています。その後、オーディオアプリで正しく設定することができます。 –

+0

ありがとうございました!私はまだその問題に遭遇していません。別々の軽量なwriteToBufferスレッドを書くのは良い考えですか? – Johan

関連する問題