2010-06-01 57 views
1

大家好,我一直想要学习Java一段时间的意义(我通常保持自己的语言,如C和Lua),但购买Android手机似乎是一个很好的时间开始。复杂的声音处理(循环播放时的IE音高变化)

现在我们经历了一系列可爱的教程并花了一段时间埋在源代码中,我开始感受它,所以我的下一步是什么?以及与图形,声音,传感器使用,触摸响应和完整的菜单功能齐全的应用程序潜水。

嗯现在有一个小问题,因为我可以继续对我的项目使用神秘的引用或冒险告诉你应用程序是什么,但同时它会让我看起来像一个疯狂的科幻书呆子如此裸露我的简要...

一个半工作的声波螺丝刀(哦,是的!)我的宏伟想法是制作一个动画螺丝刀上下滑动控件调节频率,频率决定了它返回的传感器数据。 现在我有一个半工作音响系统,但它的设计代表了它的相当差,我不会很高兴生产一个低于标准的最终产品,无论它是我的第一个还是不是。

问题:

  • 声音必须开始循环,当用户按下控制
  • 声音必须停止当用户释放控制
  • 移动控制向上或向下的声音时效果必须相应地改变音调
  • 如果用户在退出应用程序之前没有移除手指,则必须在该设备的外壳上镀金(复活节彩蛋; P)

现在我知道第一个3的外观是多么庞大,这就是为什么我会非常感谢我能得到的任何帮助。

对于这段代码看起来有多糟糕,但我的总体规划是创建功能组件,然后稍后优化代码,如果屋顶未完成,没有好的绘画墙。

这里是我的用户输入,他设置幻灯片的东西在图形用于控制

@Override 
public boolean onTouchEvent(MotionEvent event) 
{ 
    //motion event for the screwdriver view 
    if(event.getAction() == MotionEvent.ACTION_DOWN) 
    { 
      //make sure the users at least trying to touch the slider 
      if (event.getY() > SonicSlideYTop && event.getY() < SonicSlideYBottom) 
      { 
       //power setup, im using 1.5 to help out the rate on soundpool since it likes 0.5 to 1.5 
       SonicPower = 1.5f - ((event.getY() - SonicSlideYTop)/SonicSlideLength); 

       //just goes into a method which sets a private variable in my sound pool class thing 
       mSonicAudio.setPower(1, SonicPower); 

       //this handles the slides graphics 
       setSlideY ((int) event.getY()); 


    @Override 
public boolean onTouchEvent(MotionEvent event) 
{ 
    //motion event for the screwdriver view 
    if(event.getAction() == MotionEvent.ACTION_DOWN) 
    { 
      //make sure the users at least trying to touch the slider 
      if (event.getY() > SonicSlideYTop && event.getY() < SonicSlideYBottom) 
      { 
       //power setup, im using 1.5 to help out the rate on soundpool since it likes 0.5 to 1.5 
       SonicPower = 1.5f - ((event.getY() - SonicSlideYTop)/SonicSlideLength); 

       //just goes into a method which sets a private variable in my sound pool class thing 
       mSonicAudio.setPower(1, SonicPower); 

       //this handles the slides graphics 
       setSlideY ((int) event.getY()); 

       //this is from my latest attempt at loop pitch change, look for this in my soundPool class 
       mSonicAudio.startLoopedSound(); 
      } 
    } 


    if(event.getAction() == MotionEvent.ACTION_MOVE) 
    { 

      if (event.getY() > SonicSlideYTop && event.getY() < SonicSlideYBottom) 
      { 
       SonicPower = 1.5f - ((event.getY() - SonicSlideYTop)/SonicSlideLength); 
       mSonicAudio.setPower(1, SonicPower); 
       setSlideY ((int) event.getY()); 
      } 
    } 


      if(event.getAction() == MotionEvent.ACTION_UP) 
      { 
       mSonicAudio.stopLoopedSound(); 
       SonicPower = 1.5f - ((event.getY() - SonicSlideYTop)/SonicSlideLength); 
       mSonicAudio.setPower(1, SonicPower); 
      } 

     return true; 

} 

这里的地方这些方法在我的声音池类的可怕混乱的结束,但是那是因为我一直尝试大量变体以使其发挥作用,您还会注意到我开始对索引进行硬编码,并且在让它们正常工作之前,我试图让这些方法正常工作。

package com.mattster.sonicscrewdriver; 

import java.util.HashMap; 

import android.content.Context; 
import android.media.AudioManager; 
import android.media.SoundPool; 

public class SoundManager 
{ 
    private float mPowerLvl = 1f; 
    private SoundPool mSoundPool; 
    private HashMap<Integer, Integer> mSoundPoolMap; 
    private AudioManager mAudioManager; 
    private Context mContext; 
    private int streamVolume; 
    private int LoopState; 
    private long mLastTime; 
    public SoundManager() 
    { 

    } 

    public void initSounds(Context theContext) 
    { 
     mContext = theContext; 
     mSoundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0); 
     mSoundPoolMap = new HashMap<Integer, Integer>(); 
     mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);  
     streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
    } 

    public void addSound(int index,int SoundID) 
    { 
     mSoundPoolMap.put(1, mSoundPool.load(mContext, SoundID, 1)); 
    } 


    public void playUpdate(int index) 
    { 
     if(LoopState == 1) 
     { 
      long now = System.currentTimeMillis(); 
      if (now > mLastTime) 
      { 
       mSoundPool.play(mSoundPoolMap.get(1), streamVolume, streamVolume, 1, 0, mPowerLvl);  
       mLastTime = System.currentTimeMillis() + 250; 
      } 
     } 

    } 

    public void stopLoopedSound() 
    { 
     LoopState = 0; 
     mSoundPool.setVolume(mSoundPoolMap.get(1), 0, 0); 
     mSoundPool.stop(mSoundPoolMap.get(1)); 
    } 
    public void startLoopedSound() 
    { 
     LoopState = 1; 
    } 

    public void setPower(int index, float mPower) 
    { 

     mPowerLvl = mPower; 
     mSoundPool.setRate(mSoundPoolMap.get(1), mPowerLvl); 
    } 

} 

啊哈!我几乎忘了,这看起来相当无效,但我省略了我的线程,实际更新它,没什么花哨,它只是调用:

mSonicAudio。playUpdate(1);

在此先感谢,马修

回答

1

有,我认为只是剪切和粘贴问题,试图让源进入这个网页,但假设你没有你的onTouchEvent处理问题有一些容易混淆的点,我的随机评论是:

  • 它看起来像你正在每250毫秒调用play(),而触摸举行。我看不到play()调用的循环参数,但我认为它是-1。如果是这样,那么你将每250ms发射一个全新的循环声音(播放会为你创建的每个音频流返回一个唯一的streamId)。

  • 我想你想修改单个现有流的音高和幅度。所以,我认为你想这样的事情:

 

int mySoundStreamId = 0; 

... 

onDown() 
    if(mySoundStreamId == 0) { 
    // create the one true stream 
    mySoundStreamId = mySOundPool.play(initial power and freq modifiers, loop = -1) 
    } else { 
    // resume the one true stream 
    mySoundPool.resume(mySoundStreamId); // note: a STREAM id is NOT a SOUND id. 
    } 

onUp() 
    if(mySoundStreamId != 0) { 
     // pause the one true stream 
     mySoundPool.pause(mySoundStreamId) // stop() will release all the samples you held 
    } 


onWiggle() 
    if(mySoundStreamId != 0) { 
     // modify parameters of the one true stream 
     mySoundPool.setPitch(mySoundStreamId, newPitch); // too lazy to look up real soundPool command 
    } 

onGameOver 
    if(mySoundStreamId != 0) { 
     // shut down and release the samples of the one true stream 
     mySoundPool.setLoop(mySountStreamId, 0); // otherwise some phones will keep looping after shutdown 
     mySoundPool.stop(mySoundStreamId); // no resume possible after this, need to reload samples 
     mySOundStreamId = 0; 
    } 

我省略了声音池本身的创建/销毁。这听起来像你成功地将声音数据加载到声音池中。

此外,负载返回您传递给PLAY命令 一个声音ID但PLAY返回你在大多数其他的Soundpool方法当然


中使用流ID,我有我自己的问题与循环的声音'简历',所以采取我说的一粒盐:-)

好运!我想我应该检查时间戳。我的道歉,如果你发布thie 3年前:-)