IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: jak zastavit AudioTrack při pokynu z onTouchListener

V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Filip Barák
Člen
Avatar
Filip Barák:21.3.2018 19:21

Zdravím, potřebuji vytvořit android aplikaci, která bude generovat sinus o různé frekvenci právě tehdy, když budu držet tlačítko. Bohužel to tak zatím nefunguje.

@SuppressLint("ClickableViewAccessibility")
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fullscreen_start);


    Button melodie = (Button) findViewById(R.id.smelodie);
    OnTouchListener m_onTouchListener = new OnTouchListener() {

      int mBufferSize = AudioTrack.getMinBufferSize(44100,
        AudioFormat.CHANNEL_OUT_MONO,
        AudioFormat.ENCODING_PCM_8BIT);

      final AudioTrack mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
        AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
        mBufferSize, AudioTrack.MODE_STREAM);
      int duration = 50;
      double frequency = 500;

      public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
          duration *= 4410;
          double[] mSound = new double[duration];
          short[] mBuffer = new short[duration];
          for (int i = 0; i < mSound.length; i++) {
            mSound[i] = Math.sin((2.0 * Math.PI * i / (44100 / frequency)));
            mBuffer[i] = (short)(mSound[i] * Short.MAX_VALUE);
          }

          mAudioTrack.play();
          mAudioTrack.write(mBuffer, 0, mSound.length);

          else if (event.getAction() == android.view.MotionEvent.ACTION_UP) {

            mAudioTrack.pause();
            mAudioTrack.flush();
          }

          return true;
        }

      };
      melodie.setOnTouchListener(m_onTouchListener);

    };

toto je můj kód a problém je takový, že když zmáčknu tlačítko, přehraje se zvuk o délce, který nastavím zde

int duration = 50;

a teprve až dohraje, aktivuje se všechno za

MotionEvent.ACTION_UP

je úplně jedno jak dlouho tlačítko držím.
Dokázal by mi někdo poradit jak mám udělat to, aby zvuk hrál jen tehdy, když držím tlačítko? aby se zastavil až tlačítko pustím?
Děkuji za odpovědi.

 
Odpovědět
21.3.2018 19:21
Avatar
Neználek
Člen
Avatar
Odpovídá na Filip Barák
Neználek:24.3.2018 20:00

Problém je v tom, že zvuk se přehrává v UI vlákně v obsluze tlačítka.
Zvuk je třeba přehrávat v jiném vlákně a z UI vlákna pouze nastavovat příznak, zda generovat zvuk či nikoliv.

Android bohužel moc neznám. Možná by šlo použít AsyncTask. Při stisknutí tlačítka by se spustil task a při uvolnění by se zrušil.

 
Nahoru Odpovědět
24.3.2018 20:00
Avatar
Filip Barák
Člen
Avatar
Filip Barák:26.3.2018 11:54

Díky za odpověď, bohužel, tohle můj problém nevyřešilo. Mezitím jsem můj kód ještě trochu upravil, teď generuje počet vzorků na 1 vlnu a tu by měl opakovat dokud držím tlačítko. Praxe je taková, že po stisku tlačítka zvuk hraje "do nekonečna". Problém mám nyní v OnTouchListeneru, který nezaregistruje puštění tlačítka a ještě mi vyhodil takovou varování

Custon View "Button" has "setOnTouchLis­tener" called on it but does not override "PerformClick"

na kterou je na netu strašně moc různých příspěvků, ale zatím ani jedna odpověď mi toto varování neodstranila.
Už si opravdu nevím rady co s tím, jsem v tomhle zatím nováček tak budu rád za každou pomoc.
Můj aktuální kód:

import android.annotation.SuppressLint;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.view.MotionEvent;
import android.view.View.OnTouchListener;



public class fullscreen_start extends Activity {

    @SuppressLint("ClickableViewAccessibility")
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fullscreen_start);
        generator();
    }
 @SuppressLint("ClickableViewAccessibility")
           private void generator() {
               Button melodie = findViewById(R.id.bmelodie);

               melodie.setOnTouchListener(new OnTouchListener() {


                   int mBufferSize = AudioTrack.getMinBufferSize(44100,
                           AudioFormat.CHANNEL_OUT_MONO,
                           AudioFormat.ENCODING_PCM_8BIT);

                   final AudioTrack mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
                           AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
                           mBufferSize, AudioTrack.MODE_STREAM);
                   @Override
               public boolean onTouch(View v, MotionEvent event) {


                         while (event.getAction() == MotionEvent.ACTION_DOWN) {
                            v.performClick();


                             int ff = 500;
                             int duration = 1;
                             duration *= 44100/ff;

                             double[] mSound = new double[duration];
                             short[] mBuffer = new short[duration];

                             for (int i = 0; i < mSound.length; i++) {
                                 mSound[i] = Math.sin(2.0 * Math.PI * i / (44100 / ff));
                                 mBuffer[i] = (short) (mSound[i] * Short.MAX_VALUE);

                             }

                             mAudioTrack.play();
                             mAudioTrack.write(mBuffer, 0, mSound.length);
}
                   while (event.getAction() == MotionEvent.ACTION_UP) {
                   v.performClick();

                    // mAudioTrack.stop();
                    // mAudioTrack.release();
                    mAudioTrack.pause();
                    mAudioTrack.flush();



                }

                return false;
            }



        });
}
}
 
Nahoru Odpovědět
26.3.2018 11:54
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.