[转载]Android通过摇晃手机的频率来控制声音的频率

[转载]Android通过摇晃手机的频率来控制声音的频率 – stay – 博客园.

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

/**
* @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;
}
}

/**
* @author Stay
* 声音管理类
*/
public class SoundManager {
public SoundPool mSoundPool;
private HashMap 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();
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; } } [/java]

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏