您的位置:首页 > 移动开发 > Android开发

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

2012-08-15 21:19 627 查看
/**
  * @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;
     }
 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: