This example selects the frequency and generates an audio sample based on the position of the user's finger on the X axis of the screen.
Because the code is relatively simple, you can directly use the Code if you don't need to talk about it.
[Java]
Public class FingerSynthesis extends Activity implements OnTouchListener
{
AudioSynthesisTask audioSynth; // specifies the thread used to play the audio sample.
Static final float BASE_FREQUENCY = 440; // baseline Audio Frequency
Float synth_frequency = BASE_FREQUENCY; // 440Hz, changes as your fingers move
Boolean play = false; // determines whether to generate audio samples.
@ 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.exe cute ();
}
@ 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; // set play to true or false based on user operations
Synth_frequency = event. getX () + BASE_FREQUENCY; // tracks the position of the user's finger and changes accordingly
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); // generates audio samples.
Angle + = angular_frequency;
}
AudioTrack. write (buffer, 0, buffer. length );
} Else
{
Try
{
Thread. sleep (50 );
} Catch (InterruptedException e)
{
E. printStackTrace ();
}
}
}
}
}
}
Public class FingerSynthesis extends Activity implements OnTouchListener
{
AudioSynthesisTask audioSynth; // specifies the thread used to play the audio sample.
Static final float BASE_FREQUENCY = 440; // baseline Audio Frequency
Float synth_frequency = BASE_FREQUENCY; // 440Hz, changes as your fingers move
Boolean play = false; // determines whether to generate audio samples.
@ 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.exe cute ();
}
@ 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; // set play to true or false based on user operations
Synth_frequency = event. getX () + BASE_FREQUENCY; // tracks the position of the user's finger and changes accordingly
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); // generates audio samples.
Angle + = angular_frequency;
}
AudioTrack. write (buffer, 0, buffer. length );
} Else
{
Try
{
Thread. sleep (50 );
} Catch (InterruptedException e)
{
E. printStackTrace ();
}
}
}
}
}
}