2014-12-08 2 views
0

음색을 생성하고 재생하는 Android 앱을 만들었으며 내 에뮬레이터에서 제대로 작동하지만 실제 기기에서는 1 분 정도 지나면 " "작동을 멈 춥니 다. 왜 어떤 아이디어?몇 초 후 Android 앱 재생 음악이 작동하지 않습니다.

package com.funguscow; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Point; 
import android.media.AudioFormat; 
import android.media.AudioManager; 
import android.media.AudioTrack; 
import android.os.Bundle; 
import android.os.Handler; 
import android.view.Display; 
import android.view.MotionEvent; 
import android.view.View; 

public class Afspl extends Activity { 

    public DrawView vi; 
    private Point size; 
    Display disp; 
    public int wide, high, cx, cy; 
    boolean doPlay = false; 
    Thread soundPlayer; 
    int note = 0; 
    int lastNote = note; 
    boolean changed = false; 
    int countTick = 0; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     disp = getWindowManager().getDefaultDisplay(); 
     try{ 
      disp.getSize(size); 
      wide = size.x; 
      high = size.y; 
     }catch(Exception e){ 
      wide = disp.getWidth(); 
      high = disp.getHeight(); 
     } 
     cx = 0; //tracks mouse x 
     cy = 0; //tracks mouse y 
     vi = new DrawView(getApplicationContext()); 
     setContentView(vi); 
     soundPlayer = new Thread(new Runnable(){ 
      public void run(){ 
       int count = 0; 
       while(true){ 
        try{ 
        Thread.sleep((long)(duration * 10)); 
        }catch(Exception e){} 
        //if(++countTick>) 
        if(!doPlay){ 
         if(count==1 && track.getState()==AudioTrack.STATE_INITIALIZED)track.stop(); 
         continue; 
        } 
        lastNote = note; 
        note = cy * 12/high; 
        changed = (lastNote!=note); 
        if(cx > wide/2)note+=12; 
        int freq = (int)(440 * Math.pow(1.059463, note)); 
        genTone(freq); 
        if(count==0){ 
        handler.post(new Runnable(){ 
         public void run(){ 
          playSound(); 
         } 
        }); 
        count++; 
        }else{ 
         handler.post(new Runnable(){ 
          public void run(){ 
           if(++countTick >= 10){ 
            countTick = 0; 
            return; 
           } 
           track.release(); 
           playSound(); 
          } 
         }); 
        } 
       } 
      } 
     }); 
     soundPlayer.start(); 
    } 

    private int waveType = 0; 


    class DrawView extends View{ 
     Paint paint = new Paint(); 

     public DrawView(Context context){ 
      super(context); 
     } 

     public void onDraw(Canvas c){ 
      int red = 256; 
      int green = 0; 
      int blue = 0; 
      int curInc = 0; 
      for(int i=0; i<24; i++){ 
       if(curInc==0){ 
        green += 256/2; 
        if(green>=256){ 
         curInc = 1; 
        } 
       } 
       else if(curInc == 1){ 
        red -= 256/2; 
        if(red<=0){ 
         curInc = 2; 
        } 
       } 
       else if(curInc == 2){ 
        blue += 256/2; 
        if(blue >= 256){ 
         curInc = 3; 
        } 
       } 
       else if(curInc == 3){ 
        green -= 256/2; 
        if(green<=0){ 
         curInc = 4; 
        } 
       } 
       else if(curInc == 4){ 
        red += 256/2; 
        if(red>=256){ 
         curInc = 5; 
        } 
       }else if(curInc == 5){ 
        blue -= 256/2; 
        if(blue<=0){ 
         curInc=0; 
        } 
       } 
       int width = wide; 
       int start = 0; 
       if(i<12){ 
        width/=2; 
       } 
       else{ 
        start = width/2; 
        red = 256-red; 
        green = 256-green; 
        blue = 256-blue; 
       } 

       paint.setColor(getColor(red, blue, green)); 
       int height = high/12; 
       int starty = i * height; 
       int endy = (i+1) * height; 
       if(i>=12){ 
        starty = (i-12) * height; 
        endy = (i-11) * height; 
       } 
       c.drawRect(start, starty, width, endy, paint); 
      } 
      paint.setColor(Color.WHITE); 
      c.drawRect((wide * 11)/12, (high*11)/12, wide, high, paint); 
     } 
     public int getColor(int r, int g, int b){ 
      int red = (r << 16) & 0x00ff0000; 
      int green = (g << 8) & 0x0000ff00; 
      int blue = b & 0x000000ff; 
      return 0xff000000 | red | green | blue; 
     } 
    } 

    public boolean onTouchEvent(MotionEvent me){ 
     int type = me.getActionMasked(); 
     switch(type){ 
     case MotionEvent.ACTION_DOWN: 
      cx = (int)me.getX(); 
      cy = (int)me.getY(); 
      doPlay = true; 
      return true; 
     case MotionEvent.ACTION_UP: 
      doPlay = false; 
      if(cx > (wide * 11)/12 && cy > (high * 11)/12){ 
       if(++waveType>3)waveType=0; 
      } 
      return true; 
     case MotionEvent.ACTION_MOVE: 
      cx = (int)me.getX(); 
      cy = (int)me.getY(); 
      return true; 
     default: 
      return super.onTouchEvent(me); 
     } 
    } 

    public double duration = 1; 
    public int sampleRate = 8000; 
    public int numSamples = (int)duration * sampleRate; 
    public final double[] samples = new double[numSamples]; 
    public final byte[] generatedSnd = new byte[numSamples * 2]; 
    public Handler handler = new Handler(); 
    AudioTrack track; 


    public void genTone(int freq){ 
     float period = (float)sampleRate/(float)freq; 

     for(int i = 0; i<numSamples; i++){ 
      switch(waveType){ 
      case 0: 
       samples[i] = Math.sin(2 * i * Math.PI/period); 
       break; 
      case 1: 
       samples[i] = (int)(i/period) % 2 == 0 ? -1 : 1; 
       break; 
      case 2: 
       samples[i] = (i % period)/period; 
       break; 
      default: 
       samples[i] = (2 * Math.asin(Math.sin(2 * Math.PI * i/period))/Math.PI); 
      } 
     } 
     int idx = 0; 
     int efcx = cx; 
     if(cx>wide/2)efcx = wide-cx; 
     int volume = 32767 * 2 * efcx/wide; 
     for (final double dVal : samples) { 
      final short val = (short) ((dVal) * volume); 

      generatedSnd[idx++] = (byte) (val & 0x00ff); 
      generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
     } 
    } 


    public void playSound(){ 
     track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC); 
     track.write(generatedSnd, 0, generatedSnd.length); 
     track.play(); 
    } 




} 

그래서 ... 어떻게 내가 제대로 "작동이 중지"가없는이 응용 프로그램의 기능을 할 수 있습니다 : 이 거의 모든 일이 클래스는? 이 수업 중에 뭔가 바뀌어야합니까? 대답이 있다면 애매하게하지 마시고 코딩 문제와 해결 방법을 보여주십시오. 고맙습니다.

+0

예외 세부 사항이 없습니까? – tachyonflux

+0

어떻게받을 수 있습니까? 내가 말했듯이 실제 장치 (LG Lucid 2)에서만 에뮬레이터에는 문제가 없습니다. –

+0

디버그 모드에서 실행하고 장치에서 예외를 제공 할 수 있는지 확인하십시오. – liorsolomon

답변

0

track.getState()가 STATE_UNINITIALIZED가 아니 었는지 확인해야했으며 stop()을 호출하기 전에 track.getPlayState()가 PLAYSTATE_STOPPED가 아니 었는지 확인해야했습니다.

+0

쓰기 전에 track.play를 호출하십시오. ADB 로그를 확인할 수 있으며 버퍼 언더런과 같은 유용한 정보가있을 수 있습니다. 가끔 문제가 발생하면 getState가 정보를 제공하지 않습니다. – nmnir