/** * @author Stay * 通过摇晃手机的频率来改变声音的速度 */ public class ShakeSound extends Activity implements SensorEventListener,OnClickListener { private static final float SHAKE_THRESHOLD = 50; private static final String TAG = "ActivityTest"; private SensorManager manager; private SoundManager sm; private long curTime, lastUpdate; private float last_x, last_y, last_z; private float x,y,z; private boolean isPlaying; private int count = -2; private float force; private int audioCount = 0; private float audioForce; private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) this.findViewById(R.id.hello); btn.setOnClickListener(this); manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sm = new SoundManager(this); sm.addSound(1, "heixiu.ogg"); } @Override public void onSensorChanged(SensorEvent event) { curTime = System.currentTimeMillis(); if ((curTime - lastUpdate) > 100) { count ++ ; if (count < 0) { return; } if (count == 0) { if (!isPlaying) { Log.i(TAG, "sm.play(1, 0, 1.0f);"); sm.play(1, 0, 1.0f); } last_x = event.values[SensorManager.DATA_X]; last_y = event.values[SensorManager.DATA_Y]; last_z = event.values[SensorManager.DATA_Z]; return; } lastUpdate = curTime; x = event.values[SensorManager.DATA_X]; y = event.values[SensorManager.DATA_Y]; z = event.values[SensorManager.DATA_Z]; curTime = System.currentTimeMillis(); // 每100毫秒检测一次 float deltaForce = Math.abs(x + y + z - last_x - last_y - last_z); force = force + deltaForce; updateAudioRate(deltaForce); if (count >= SHAKE_THRESHOLD) { Log.i(TAG, "unSensorListener"); // onShakeCallBack(force / count); get the score unSensorListener(); if (isPlaying) { sm.stop(); isPlaying = false; } count = - 2; force = 0; return; } last_x = x; last_y = y; last_z = z; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } private void updateAudioRate(float force) { float rate=0; float prvAudioRate = 1; audioCount =audioCount+1; audioForce=audioForce+force; if(audioCount>3){ //from 0-50 maps to 0.6 to 2 //rate=audioForce/audioCount*0.03+0.5; //from 0-50 maps to 1 to 1.8 rate=(float) (audioForce/audioCount*0.012+1.0); //myAlert(rate); prvAudioRate=prvAudioRate+(rate-prvAudioRate)/3; sm.setRate(prvAudioRate); Log.i(TAG, "sm.setRate=" + prvAudioRate); audioForce=0; audioCount=0; //prvAudioRate=rate; } } private void setSensorListener() { Log.i(TAG, "setSensorListener"); Sensor sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); manager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); } private void unSensorListener() { Log.i(TAG, "unregisterListener"); manager.unregisterListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.hello: setSensorListener(); break; default: break; } }
通过晃动手机的频率来修改播放声音的频率。效果很给力的说。主要通过sensor来算手机摇晃的频率,摇晃的频率越高,播放声音的速度越快
/** * @author Stay * 声音管理类 */ public class SoundManager { public SoundPool mSoundPool; private HashMap<Integer, Integer> mSoundPoolMap; private AudioManager mAudioManager; private Context mContext; private int mStreamID; static final String LOG_TAG = "SoundManager"; private boolean mSoundEnable = true; private float mRate = 1f; private boolean playing = false; private int loopMode = 0; private int mPlayIndex = -1; public SoundManager(Context mContext) { this.mContext = mContext; mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); mSoundPoolMap = new HashMap<Integer, Integer>(); mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); } public void addSound(int index, String audioName) { // mSoundPoolMap.put(1, mSoundPool.load(mContext, SoundID, 1)); try { mSoundPoolMap.put(index, mSoundPool.load(mContext.getAssets().openFd(audioName), 1)); } catch (IOException e) { e.printStackTrace(); } } // loopMode=0:play once; loopMode=-1:loop mode; public void play(int index, int loopMode, float rate) { if (mSoundEnable) { this.loopMode = loopMode; mRate = checkRate(rate); int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // float streamVolume = 0.1f; // notes: for loop mode, the priority should be set to 0, else it can't be stopped // mStreamID=mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, loopMode, mRate); if (mPlayIndex < 0) { mStreamID = mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 0, loopMode, mRate); } else { mStreamID = mSoundPool.play(mSoundPoolMap.get(mPlayIndex), streamVolume, streamVolume, 0, loopMode, mRate); } playing = true; } } // added for v 1.0.1, enable changing the audio remotely public void setPlayIndex(int index) { mPlayIndex = index; } public void setRate(float rate) { if (mSoundEnable) { mRate = checkRate(rate); mSoundPool.setRate(mStreamID, mRate); } } private float checkRate(float rate) { if (rate > 2f) { return 2f; } else if (rate < 0.5f) { return 0.5f; } else { return rate; } } public void stepRate(float step) { if (mSoundEnable) { mRate = mRate + step; mRate = checkRate(mRate); mSoundPool.setRate(mStreamID, mRate); } } public void pause() { if (mSoundEnable) { mSoundPool.pause(mStreamID); // mSoundPool.autoPause(); } } public void resume() { if (mSoundEnable) { if (false == playing) { play(1, loopMode, mRate); } else { mSoundPool.resume(mStreamID); } } // mSoundPool.autoResume(); } public void stop() { if (mSoundEnable) { playing = false; mSoundPool.stop(mStreamID); } } public void setSound(boolean soundEnable) { mSoundEnable = soundEnable; } public void release() { if (mSoundEnable) { playing = false; mSoundPool.release(); } mSoundPool.release(); mSoundPool = null; mSoundPoolMap.clear(); mSoundPoolMap = null; } }