天天看点

跟踪手指在屏幕上的位置生成音频样本并播放

此示例根据用户手指在屏幕的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();
                    }
                }
            }
        }
    }
}