2016-04-14 6 views
0

私はシンセサイザーを3つの基本タイプのサウンドを生成できるようにしています。サウンドを再生しているときに、再生が完了する前後に発生します。なぜ私はそれを理解できません。Android Audiotrackはサウンドの前後にクリックします

あらゆる種類のサウンドで起こります。正弦波では音量が最大です。ここで

は私が

int amp = 32767; 
double phase = 0.0; 

protected void onCreate(Bundle savedInstanceState) { 
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
     AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 
     String nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE); 
     sampleRate = Integer.parseInt(nativeParam); 
     nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER); 
     bufSize = Integer.parseInt(nativeParam); 
    } 
    else { 
     sampleRate = 44100; 
     bufSize = AudioTrack.getMinBufferSize(sampleRate, 
       AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 
    } 

    audioOutput = new AudioOutput(); 
    audioOutput.Start(sampleRate, bufSize); 

    samples = new short[bufSize]; // buffer size is 512 

    playTask.execute(); 
} 

class PlayTask extends AsyncTask<Object, Void, Void> { 
    @Override 
    protected Void doInBackground(Object[] params) { 
     android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE); 

     while (!this.isCancelled()) { 
      while (touched) { 
       generateTone(); 
       audioOutput.write(samples, 0, samples.length); 
      } 
     } 
     return null; 
    } 
} 

private void generateTone() { 
    double phaseIncrement = (2 * Math.PI)/sampleRate; 
    switch (currentShape) { 
     case SINE: 
      for (int i = 0; i < bufSize; i++) { 
       samples[i] = (short) (amp * Math.sin(phase)); 
       phase += phaseIncrement * freq; 
       if (phase > 2 * Math.PI) 
        phase -= 2 * Math.PI; 
      } 
      break; 
     case SAWTOOTH: 
      for (int i = 0; i < bufSize; i++) { 
       samples[i] = (short) (amp * (phase - amp)); 
       phase += phaseIncrement * freq; 
       if (phase > 2 * Math.PI) 
        phase -= 2 * Math.PI; 
      } 
      break; 
     case SQUARE: 
      for (int i = 0; i < bufSize; i++) { 
       if (phase < Math.PI) 
        samples[i] = (short) amp; 
       else 
        samples[i] = (short) -amp; 
       phase += phaseIncrement * freq; 
       if (phase > 2 * Math.PI) 
        phase -= 2 * Math.PI; 
      } 
      break; 
    } 
} 

public class AudioOutput { 
    private AudioTrack mAudioTrack; 
    private int mFrameRate; 

    public void Start(int sampleRate, int bufferSize) { 
     Stop(); 
     mFrameRate = sampleRate; 
     mAudioTrack = createAudioTrack(bufferSize); 

     mAudioTrack.play(); 
    } 

    private AudioTrack createAudioTrack(int buffsize) { 
     return new AudioTrack(AudioManager.STREAM_MUSIC, 
       mFrameRate, AudioFormat.CHANNEL_OUT_MONO, 
       AudioFormat.ENCODING_PCM_16BIT, buffsize, 
       AudioTrack.MODE_STREAM); 
    } 

    public int write(short[] buffer, int offset, int length) { 
     return write = mAudioTrack.write(buffer, offset, length); 
    } 

    public void Stop() { 
     if (mAudioTrack != null) { 
      mAudioTrack.stop(); 
      mAudioTrack.release(); 
      mAudioTrack = null; 
     } 
    } 
} 

サウンドオーディオサンプルを生成するために使用するコードです: https://soundcloud.com/syntey/sinewavetest

誰もがどこ問題がある可能性が知っていますか?あなたがゼロ交差点で、各バッファの開始と終了されていません

おかげ

+0

実際のwaveファイルへのリンクはありますか?私はそれを聞いてからより多くの情報を見ることができると思う。 – jaket

+0

確かhttp://www.mediafire.com/download/hotb3wpz7q3v2jc/sinewave+test.wav – Syntey

+0

リストされていないコードのどこでもフェードイン/アウトしていますか?生成された信号には明らかに何らかのエンベロープがあります。また、正弦波には多くの歪みがあります。 – jaket

答えて

1

。各バッファの開始時のランダム位相は、非常に最初のサンプルにあまりにも急峻な立ち上がり時間を生じさせる可能性が高い。ゼロからゼロまでの最初と最後の数十サンプルがテーパ(余弦コサインテーパ)されていると助けになるかもしれません。

+0

私はそのリセットフェーズを0に修正しましたが、私はその終わりを理解できません。あなたはテーパのいくつかのプログラムされた例を知っていますか?私は何かを見つけようとしましたが、何もありません – Syntey

関連する問題