2017-06-04 13 views
1

私は音を連続的に再生しようとしていますが、周波数はスムーズに変更する必要があります。たとえば、私のAudioTrackは現在100 Hzの周波数で再生しており、新しい周波数は1000 Hzです。それから、私は頻度を上げるのではなく、スムーズに変化に適応させることを望んでいます。現在のコードは次のようになります。スムーズな周波数変更

int buffSize = AudioTrack.getMinBufferSize(sampleRate, 
              AudioFormat.CHANNEL_OUT_MONO, 
              AudioFormat.ENCODING_PCM_16BIT); 
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, 
             AudioFormat.CHANNEL_OUT_MONO, 
             AudioFormat.ENCODING_PCM_16BIT, buffSize, 
             AudioTrack.MODE_STREAM); 
short samples[] = new short[buffSize]; 
int amp = 10000; 
double twopi = 8. * Math.atan(1.); 
double phase = 0.0; 
audioTrack.play(); 
while (playing) 
{ 
    double newFrequency = getFrequency(); 
    for (int i = 0; i < buffSize; i++) 
    { 
     samples[i] = (short) (amp * Math.sin(phase)); 
     phase += twopi * newFrequency/sampleRate; 
    } 
    audioTrack.write(samples, 0, buffSize); 
} 
audioTrack.stop(); 
audioTrack.release(); 

これはもちろんバックグラウンドで実行されます。

private int getMinSampleRate() 
{ 
    for (int i = 1; i < 100000; i++) 
     if (AudioTrack.getMinBufferSize(i, AudioFormat.CHANNEL_OUT_MONO, 
             AudioFormat.ENCODING_PCM_16BIT) > 0) 
      return i; 

    return -1; 
} 

答えて

1

あなたが移行をスムーズにするlow-pass filterを使用することができます。私は、sampleRateが自動的に可能な限り低い値に設定されています。別のexampleがあります。

double currentFrequency = getFrequency(); 
double smoothing = 10; // calculate based on your sample rate and desired time delta for the change 
while (playing) 
{ 
    double newFrequency = getFrequency(); 
    for (int i = 0; i < buffSize; i++) 
    { 
     // because you are filling the buffer, deltaTime will be a constant: the time between samples 
     currentFrequency += deltaTime * (newFrequency - currentFrequency)/smoothing; 
     samples[i] = (short) (amp * Math.sin(phase)); 
     phase += twopi * currentFrequency/sampleRate; 
    } 
    audioTrack.write(samples, 0, buffSize); 
} 

デルタを基準にして、増分ステップを使用して頻度の履歴レコードを新しい値に向かってゆっくりと新しい値に変更します。大きなデルタの場合、値は最初は速く変化し、最後には遅くなります。 IIRCでは、これは変更の加速を制御していないため、1次フィルタと呼ばれます。 2次フィルタは加速度を平滑化します。

さまざまな手法があります。フィルタはWikipediaでチェックしてください。