2010-06-01 3 views
1

Salut tout le monde Je voulais apprendre le Java depuis un moment (je me tiens d'habitude dans des langages comme C et Lua) mais l'achat d'un téléphone Android semble être un excellent moment pour début.Traitement du son complexe (changement de hauteur IE en boucle)

maintenant après avoir passé par le charmant ensemble de tutoriels et un peu passé enterré dans le code source, je commence à avoir la sensation pour cela alors quelle est ma prochaine étape? bien à plonger avec une application entièrement équipée avec des graphiques, le son, l'utilisation du capteur, la réponse tactile et un menu complet.

hmm maintenant il y a une légère énigme puisque je peux continuer à utiliser des références cryptiques à mon projet ou risquer de vous dire quelle est l'application mais en même temps ça va me faire ressembler à un nerf de science-fiction délirant si nu avec Pour le brief ...

Un tournevis sonique semi-fonctionnant (oh oui!) ma grande idée était de faire un tournevis d'animation où glisser les commandes de haut en bas moduler la fréquence et que la fréquence dicte les données de capteur qu'elle renvoie . Maintenant, j'ai un système de son semi-travail, mais c'est assez pauvre pour ce qu'il est conçu pour représenter et je ne serais tout simplement pas heureux de produire un produit final sous-pair, que ce soit mon premier ou non.

le problème:

  • son doit commencer en boucle lorsque l'utilisateur appuie sur le contrôle
  • le son doit cesser lorsque l'utilisateur relâche le contrôle
  • lors du déplacement de la commande vers le haut ou vers le bas le son effet doit pas modifier en conséquence
  • si l'utilisateur ne supprime pas là doigt avant la sauvegarde de l'application, il faut plaquer le boîtier du dispositif avec de l'or, il (œufs de Pâques; P)

maintenant je suis conscient de la façon dont mon premier 3 monolithique et c'est pourquoi j'apprécierais vraiment toute aide que je peux obtenir.

désolé pour combien mauvais ce code ressemble mais mon plan général est de créer les composants fonctionnels puis affiner le code plus tard, pas bon de peindre les murs si les toits ne sont pas finis.

voici mon entrée utilisateur, il a mis des choses de glissement est utilisé dans les graphiques pour le contrôle

@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; 

} 

et est là où ces méthodes se retrouvent dans mon son cours de piscine son horriblement compliqué, mais c'est parce que je suis en essayant une tonne de variantes pour que cela fonctionne, vous remarquerez aussi que je commence à coder l'index de manière rigide, encore une fois j'essayais de faire fonctionner les méthodes avant de les faire fonctionner correctement.

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); 
    } 

} 

ah ah! J'ai presque oublié, cela semble assez inefficace mais j'ai omis mon fil qui actualise la réalité, rien d'extraordinaire il appelle simplement:

mSonicAudio.playUpdate (1);

merci à l'avance, Matthew

Répondre

1

Il y a quelques points confus là-dedans que je pense, sont simplement couper et les problèmes de pâte en essayant d'obtenir la source dans cette page, mais en supposant que vous ne pas avoir des problèmes avec votre traitement de onTouchEvent , mes commentaires aléatoires sont:

  • Il semble que vous appelez play() toutes les 250 ms tant que le contact est maintenu. Je ne peux pas voir l'argument de boucle à l'appel de play() mais je suppose qu'il est -1. Si c'est le cas, vous lancez un tout nouveau son en boucle tous les 250 msc (play renvoie un unique streamId pour chaque flux audio que vous créez). Je pense que vous vouliez modifier la hauteur et l'amplitude d'un seul flux existant. Donc, je pense que vous vouliez quelque chose comme ceci:

 

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; 
    } 

Je laisse de côté la création/destruction de la piscine de son lui-même. Il semble que vous chargiez avec succès les données sonores dans la piscine sonore ok.

Notez que la charge renvoie un ID SOUND que vous passez à la commande PLAY mais que le jeu retourne un ID STREAM que vous utilisez dans la plupart des autres méthodes de SOUNDPOOL


Bien sûr, j'ai mon propres problèmes avec «reprendre» sur un son en boucle, alors prenez ce que je dis avec un grain de sel :-)

Bonne chance! Je suppose que j'aurais dû vérifier l'horodatage. Mes excuses si vous avez posté thie il y a 3 ans :-)

Questions connexes