2016-05-18 38 views
1

我试图用扫一扫生成正弦音。我正在使用下面的代码,我从here得到。问题是,我可以听到200Hz以上的声音,但我听不到200Hz以下的声音(如20Hz或50Hz)。 请帮助我生成准确的正弦音调。如果您追踪正弦波的当前位置,并增加它基于当前频率,而不是计算每个相对于起始位置样本位置扫一扫生成正弦音 - Android

private final int sampleRate = 44100;    


public void generateTone(double startFreq, double endFreq, float duration) 
{ 
    double dnumSamples = duration * sampleRate; 
    dnumSamples = Math.ceil(dnumSamples); 
    numSamples = (int) dnumSamples; 
    double sample[] = new double[numSamples]; 

    double currentFreq = 0,numerator; 

    for (int i = 0; i < numSamples; ++i) { 
     numerator = (double) i/(double) numSamples; 
     currentFreq = startFreq + (numerator * (endFreq - startFreq))/2; 
     if ((i % 1000) == 0) { 
      Log.e("Current Freq:", String.format("Freq is: %f at loop %d of %d", currentFreq, i, numSamples)); 
     } 
     sample[i] = Math.sin(2 * Math.PI * i/(sampleRate/currentFreq)); 
    } 

    generatedSnd = new byte[2 * numSamples]; 
    int idx = 0; 
    for (final double dVal : sample) { 
     // scale to maximum amplitude 
     final short val = (short) ((dVal * 32767)); 
     // in 16 bit wav PCM, first byte is the low order byte 
     generatedSnd[idx++] = (byte) (val & 0x00ff); 
     generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 

    } 
} 

回答

1

您的代码将更加强劲。

double currentPos = 0.0; 
for (int i = 0; i < numSamples; ++i) { 
    numerator = (double) i/(double) numSamples; 
    currentFreq = startFreq + (numerator * (endFreq - startFreq))/2; 
    if ((i % 1000) == 0) { 
     Log.e("Current Freq:", String.format("Freq is: %f at loop %d of %d", currentFreq, i, numSamples)); 
    } 
    currentPos += 2 * Math.PI * (currentFreq/sampleRate); 
    sample[i] = Math.sin(currentPos); 
} 

这避免了潜在地导致当前位置向后移动的频率下降的问题。

如果你需要的音色褪色超过一定数量的样本,你可以添加以下代码:

int fadeInSamples = 5000; 
double fadeIn = (i < fadeInSamples) ? (double)i/(double)fadeInSamples : 1.0; 

sample[i] = Math.sin(currentPos) * fadeIn; 
+0

现在我可以听到音调..但有一个恼人的提示音开始时。我使用AudioTrack玩这个音 –

+0

'audioTrack =新AudioTrack(AudioManager.STREAM_MUSIC, 采样率,AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,(INT)NUMSAMPLES * 2, AudioTrack.MODE_STATIC); audioTrack.write(generatedSnd,0,generatedSnd.length); //加载轨道 audioTrack.play(); //播放音轨' –

+1

我不确定是什么原因造成的,这可能是音调开始时的不连续性。我已经添加了一些代码来淡入,希望能够掩盖它。 – samgak