2010-06-01 72 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年前:-)