Android通过摇晃手机的频率来控制声音的频率

通过晃动手机的频率来修改播放声音的频率。效果很给力的说。主要通过sensor来算手机摇晃的频率,摇晃的频率越高,播放声音的速度越快。

 
1 /**
2 * @author Stay
3 * 通过摇晃手机的频率来改变声音的速度
4 */
5  public class ShakeSound extends Activity implements SensorEventListener,OnClickListener {
6 private static final float SHAKE_THRESHOLD = 50;
7 private static final String TAG = "ActivityTest";
8 private SensorManager manager;
9 private SoundManager sm;
10 private long curTime, lastUpdate;
11 private float last_x, last_y, last_z;
12 private float x,y,z;
13 private boolean isPlaying;
14 private int count = -2;
15 private float force;
16 private int audioCount = 0;
17 private float audioForce;
18 private Button btn;
19
20 @Override
21 protected void onCreate(Bundle savedInstanceState) {
22 super.onCreate(savedInstanceState);
23 setContentView(R.layout.main);
24 btn = (Button) this.findViewById(R.id.hello);
25 btn.setOnClickListener(this);
26 manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
27 sm = new SoundManager(this);
28 sm.addSound(1, "heixiu.ogg");
29 }
30
31 @Override
32 public void onSensorChanged(SensorEvent event) {
33 curTime = System.currentTimeMillis();
34 if ((curTime - lastUpdate) > 100) {
35 count ++ ;
36 if (count < 0) {
37 return;
38 }
39 if (count == 0) {
40 if (!isPlaying) {
41 Log.i(TAG, "sm.play(1, 0, 1.0f);");
42 sm.play(1, 0, 1.0f);
43 }
44 last_x = event.values[SensorManager.DATA_X];
45 last_y = event.values[SensorManager.DATA_Y];
46 last_z = event.values[SensorManager.DATA_Z];
47 return;
48 }
49 lastUpdate = curTime;
50 x = event.values[SensorManager.DATA_X];
51 y = event.values[SensorManager.DATA_Y];
52 z = event.values[SensorManager.DATA_Z];
53 curTime = System.currentTimeMillis();
54 // 每100毫秒检测一次
55   float deltaForce = Math.abs(x + y + z - last_x - last_y - last_z);
56 force = force + deltaForce;
57 updateAudioRate(deltaForce);
58 if (count >= SHAKE_THRESHOLD) {
59 Log.i(TAG, "unSensorListener");
60  // onShakeCallBack(force / count); get the score
61   unSensorListener();
62 if (isPlaying) {
63 sm.stop();
64 isPlaying = false;
65 }
66 count = - 2;
67 force = 0;
68 return;
69 }
70 last_x = x;
71 last_y = y;
72 last_z = z;
73 }
74 }
75
76
77 @Override
78 public void onAccuracyChanged(Sensor sensor, int accuracy) {
79 }
80
81 private void updateAudioRate(float force) {
82 float rate=0;
83 float prvAudioRate = 1;
84 audioCount =audioCount+1;
85 audioForce=audioForce+force;
86 if(audioCount>3){
87 //from 0-50 maps to 0.6 to 2
88 //rate=audioForce/audioCount*0.03+0.5;
89 //from 0-50 maps to 1 to 1.8
90   rate=(float) (audioForce/audioCount*0.012+1.0);
91 //myAlert(rate);
92   prvAudioRate=prvAudioRate+(rate-prvAudioRate)/3;
93 sm.setRate(prvAudioRate);
94 Log.i(TAG, "sm.setRate=" + prvAudioRate);
95 audioForce=0;
96 audioCount=0;
97 //prvAudioRate=rate;
98   }
99 }
100
101 private void setSensorListener() {
102 Log.i(TAG, "setSensorListener");
103 Sensor sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
104 manager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
105 }
106
107 private void unSensorListener() {
108 Log.i(TAG, "unregisterListener");
109 manager.unregisterListener(this);
110 }
111
112 @Override
113 public void onClick(View v) {
114 switch (v.getId()) {
115 case R.id.hello:
116 setSensorListener();
117 break;
118 default:
119 break;
120 }
121 }
1 /**
2 * @author Stay
3 * 声音管理类
4 */
5  public class SoundManager {
6 public SoundPool mSoundPool;
7 private HashMap<Integer, Integer> mSoundPoolMap;
8 private AudioManager mAudioManager;
9 private Context mContext;
10 private int mStreamID;
11 static final String LOG_TAG = "SoundManager";
12 private boolean mSoundEnable = true;
13 private float mRate = 1f;
14 private boolean playing = false;
15 private int loopMode = 0;
16 private int mPlayIndex = -1;
17
18 public SoundManager(Context mContext) {
19 this.mContext = mContext;
20 mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
21 mSoundPoolMap = new HashMap<Integer, Integer>();
22 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
23 }
24
25
26 public void addSound(int index, String audioName) {
27 // mSoundPoolMap.put(1, mSoundPool.load(mContext, SoundID, 1));
28   try {
29 mSoundPoolMap.put(index, mSoundPool.load(mContext.getAssets().openFd(audioName), 1));
30 } catch (IOException e) {
31 e.printStackTrace();
32 }
33 }
34
35 // loopMode=0:play once; loopMode=-1:loop mode;
36   public void play(int index, int loopMode, float rate) {
37 if (mSoundEnable) {
38 this.loopMode = loopMode;
39 mRate = checkRate(rate);
40
41 int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
42 // float streamVolume = 0.1f;
43 // notes: for loop mode, the priority should be set to 0, else it can't be stopped
44 // mStreamID=mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, loopMode, mRate);
45   if (mPlayIndex < 0) {
46 mStreamID = mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 0, loopMode, mRate);
47 } else {
48 mStreamID = mSoundPool.play(mSoundPoolMap.get(mPlayIndex), streamVolume, streamVolume, 0, loopMode, mRate);
49 }
50 playing = true;
51 }
52 }
53
54 // added for v 1.0.1, enable changing the audio remotely
55 public void setPlayIndex(int index) {
56 mPlayIndex = index;
57 }
58
59 public void setRate(float rate) {
60 if (mSoundEnable) {
61 mRate = checkRate(rate);
62 mSoundPool.setRate(mStreamID, mRate);
63 }
64 }
65
66 private float checkRate(float rate) {
67 if (rate > 2f) {
68 return 2f;
69 } else if (rate < 0.5f) {
70 return 0.5f;
71 } else {
72 return rate;
73 }
74 }
75
76 public void stepRate(float step) {
77 if (mSoundEnable) {
78 mRate = mRate + step;
79 mRate = checkRate(mRate);
80 mSoundPool.setRate(mStreamID, mRate);
81 }
82 }
83
84 public void pause() {
85 if (mSoundEnable) {
86 mSoundPool.pause(mStreamID);
87 // mSoundPool.autoPause();
88 }
89 }
90
91 public void resume() {
92 if (mSoundEnable) {
93 if (false == playing) {
94 play(1, loopMode, mRate);
95 } else {
96 mSoundPool.resume(mStreamID);
97 }
98 }
99 // mSoundPool.autoResume();
100 }
101
102 public void stop() {
103 if (mSoundEnable) {
104 playing = false;
105 mSoundPool.stop(mStreamID);
106 }
107 }
108
109 public void setSound(boolean soundEnable) {
110 mSoundEnable = soundEnable;
111 }
112
113 public void release() {
114 if (mSoundEnable) {
115 playing = false;
116 mSoundPool.release();
117 }
118 mSoundPool.release();
119 mSoundPool = null;
120 mSoundPoolMap.clear();
121 mSoundPoolMap = null;
122 }
123 }
原文地址:https://www.cnblogs.com/stay/p/2141737.html