此示例根据用户手指在屏幕的x轴方向上的位置,来选择频率并生成音频样本。
因为代码比较简单,那么话不多说,直接上代码。
public class FingerSynthesis extends Activity implements OnTouchListener { AudioSynthesisTask audioSynth;//播放音频样本的线程 static final float BASE_FREQUENCY = 440;//基准音频频率 float synth_frequency = BASE_FREQUENCY; // 440 Hz, 随着手指的移动会发生改变 boolean play = false;//控制是否生成音频样本 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); View mainView = this.findViewById(R.id.MainView); mainView.setOnTouchListener(this); audioSynth = new AudioSynthesisTask(); audioSynth.execute(); } @Override public void onPause() { super.onPause(); play = false; finish(); } public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: play = true;//根据用户操作将play设置为true或者false synth_frequency = event.getX() + BASE_FREQUENCY;//跟踪用户手指的位置,做出相应的改变 Log.v("FREQUENCY", "" + synth_frequency); break; case MotionEvent.ACTION_MOVE: play = true; synth_frequency = event.getX() + BASE_FREQUENCY; Log.v("FREQUENCY", "" + synth_frequency); break; case MotionEvent.ACTION_UP: play = false; break; case MotionEvent.ACTION_CANCEL: break; default: break; } return true; } private class AudioSynthesisTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { final int SAMPLE_RATE = 11025; int minSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minSize, AudioTrack.MODE_STREAM); audioTrack.play(); short[] buffer = new short[minSize]; float angle = 0; while (true) { if (play) { for (int i = 0; i < buffer.length; i++) { float angular_frequency = (float) (2 * Math.PI) * synth_frequency / SAMPLE_RATE; buffer[i] = (short) (Short.MAX_VALUE * ((float) Math .sin(angle)));//生成音频样本 angle += angular_frequency; } audioTrack.write(buffer, 0, buffer.length); } else { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }