此方法生成 Square、Sin 和 Saw Tooth 波形
// Process audio
protected void processAudio()
{
short buffer[];
int rate =
AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
int minSize =
AudioTrack.getMinBufferSize(rate, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
// Find a suitable buffer size
int sizes[] = {1024, 2048, 4096, 8192, 16384, 32768};
int size = 0;
for (int s : sizes)
{
if (s > minSize)
{
size = s;
break;
}
}
final double K = 2.0 * Math.PI / rate;
// Create the audio track
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, rate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
size, AudioTrack.MODE_STREAM);
// Check audiotrack
if (audioTrack == null)
return;
// Check state
int state = audioTrack.getState();
if (state != AudioTrack.STATE_INITIALIZED)
{
audioTrack.release();
return;
}
audioTrack.play();
// Create the buffer
buffer = new short[size];
// Initialise the generator variables
double f = frequency;
double l = 0.0;
double q = 0.0;
while (thread != null)
{
// Fill the current buffer
for (int i = 0; i < buffer.length; i++)
{
f += (frequency - f) / 4096.0;
l += ((mute ? 0.0 : level) * 16384.0 - l) / 4096.0;
q += (q < Math.PI) ? f * K : (f * K) - (2.0 * Math.PI);
switch (waveform)
{
case SINE:
buffer[i] = (short) Math.round(Math.sin(q) * l);
break;
case SQUARE:
buffer[i] = (short) ((q > 0.0) ? l : -l);
break;
case SAWTOOTH:
buffer[i] = (short) Math.round((q / Math.PI) * l);
break;
}
}
audioTrack.write(buffer, 0, buffer.length);
}
audioTrack.stop();
audioTrack.release();
}
}
归功于billthefarmer 。
完整的源代码:
https://github.com/billthefarmer/sig-gen