Как я могу сделать так, чтобы громкость воспроизводимой музыки колебалась с моим таймером? - PullRequest
0 голосов
/ 10 мая 2018

Я пытаюсь сделать второй звук в этом приложении.колебаться в объеме на основе кривой синуса в зависимости от времени прохождения.Как бы вы предложили мне отредактировать то, что у меня уже есть, чтобы это работало?Любая помощь была бы удивительной!

Извините. Если какой-то код плохой, я на некоторое время отошел от этого и добавил несколько разделов, которые ранее комментировал.Я не был уверен, было ли это по уважительной причине или нет, поэтому я добавил его обратно.

MediaPlayer beep;
MediaPlayer sound2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); //call superclass onCreate
    setContentView(R.layout.activity_main); //inflate the GUI


    minutesChanged = (TextView) findViewById(R.id.minutesChanged);
    secondsChanged = (TextView) findViewById(R.id.secondsChanged);
    minutesTotal = (TextView) findViewById(R.id.totalMinutesEntered);
    secondsTotal = (TextView) findViewById(R.id.totalSecondsEntered);
    percentageFinishedAmount = (TextView) findViewById(R.id.percentageFinishedAmount);
    errorMessage = (TextView) findViewById(R.id.errorMessage);



    secondEditText =
            (EditText) findViewById(R.id.secondEditText);
    secondEditText.addTextChangedListener(secondEditTextWatcher);


    minuteEditText =
            (EditText) findViewById(R.id.minuteEditText);
    minuteEditText.addTextChangedListener(minuteEditTextWatcher);

    whichSound =
            (EditText) findViewById(R.id.whichSound);
    whichSound.addTextChangedListener(whichSoundTextWatcher);

    seekBarSeconds =
            (SeekBar) findViewById(R.id.seekBarSeconds);
    seekBarSeconds.setOnSeekBarChangeListener(seekBarListener);

    seekBarMinutes =
            (SeekBar) findViewById(R.id.seekBarMinutes);
    seekBarMinutes.setOnSeekBarChangeListener(seekBarListener);

    percentSeekBar =
            (SeekBar) findViewById(R.id.seekBarTotal);

    beep = MediaPlayer.create(MainActivity.this, R.raw.beep);
    sound2 = MediaPlayer.create(MainActivity.this, R.raw.sound);


}

private void calculate() {

    totalmili = minutesT + secondsT;



    new CountDownTimer(totalmili + 2000, interv) {
        public void onTick(long millisUntilFinished) {

            secondsEllapsed = (int) ((totalmili + 2000 - millisUntilFinished) / 1000);
            minutesEllapsed = secondsEllapsed / 60;
            secondsEllapsed = secondsEllapsed % 60;


            totalTimeEllapsed = secondsEllapsed + (minutesEllapsed * 60);
            Log.d("Lucas", "total time elapsed " + totalTimeEllapsed);


            if (totalTimeEllapsed < 10) {
                errorMessage.setText("Elapsed Time: " + minutesEllapsed + " : 0" + secondsEllapsed);
            } else if (totalTimeEllapsed >= 10) {
                errorMessage.setText("Elapsed Time: " + minutesEllapsed + " : " + secondsEllapsed);
            }

            //set seekBar minutes/seconds and changing minute/seconds textView
            seekBarMinutes.setProgress(minutesEllapsed);
            minutesChanged.setText(Integer.toString(minutesEllapsed));
            seekBarSeconds.setProgress(secondsEllapsed);
            secondsChanged.setText(Integer.toString(secondsEllapsed));

            double t = sin((360/totalmili) *(totalTimeEllapsed*1000));
            float left = (float) ((t+1.0)*0.9/2.0+0.1);
            float right = (float) ((t+1.0)*0.9/2.0+0.1);
            sound2.setVolume(left,right);
            Log.d("Lucas", "value of left and red respectively " + left + ", " +right);

            if(sound == 1){

                musicPlaying = beep.isPlaying();

                if(musicPlaying == true){

                    beep.pause();
                    beep.seekTo(0);
                    beep.start();

                } else {
                    beep.start();
                }


            }else if (sound == 2){

            if(start ==1) {
                sound2.seekTo(19);
                sound2.start();
                start = 2;


                    float left = (float) ((sin(totalTimeEllapsed)+1.0)*0.9/2.0+0.1);
                    float right = (float) ((sin(totalTimeEllapsed)+1.0)*0.9/2.0+0.1);
                    sound2.setVolume(left, right);
                   Log.d("Lucas", "value of left and red respectively " + left + ", " +right);

                musicPlaying = sound2.isPlaying();

            }else if(start ==2){

                if (totalTimeEllapsed == 11) {

                    sound2.pause();
                    sound2.seekTo(34);
                    sound2.start();




                } else if (totalTimeEllapsed == 22) {

                    sound2.pause();

                }

            }


            //calculate total percentage finished, set percentage text, set total percentage seekBar
            int percentProgress = (int) Math.round(((double) totalTimeEllapsed) / ((double) (totalmili) / 1000) * 100);
            percentageFinishedAmount.setText(percentProgress + "% ");
            percentSeekBar.setProgress(percentProgress);

            //change background and text color bassed on increasing progress
            errorMessage.setBackgroundColor(Color.argb(255, (int) (percentProgress * 2.5), 0, 0));
            errorMessage.setTextColor(Color.argb(255, (int) (255 - (percentProgress * 2.5)), 255, 255));

        }

        public void onFinish() {
            //display on finish text
            errorMessage.setText("Done!");
        }
    }.start();


}

//listener object for the EditText's text-changed events
private final TextWatcher minuteEditTextWatcher = new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start,
                              int before, int count) {

        // set hours Total and converts minutes to milliseconds
        if (s.charAt(start + count - 1) == '\n') {
            minuteEditText.getText().replace(start + count - 1, start + count, " ");
            s = minuteEditText.getText();
            Log.d("Lucas", "in enter key min, s = " + s);
            try {
                minutesT = Integer.parseInt(s.toString());
                minutesTotal.setText(String.valueOf(minutesT) + " Minutes");
                percentageFinishedAmount.setText(" ");
                minutesT *= 60000;

            } catch (NumberFormatException e) {
                minutesTotal.setText("");
                minutesT = 0;
            }
        }
    }


    @Override
    public void afterTextChanged(Editable s) {
    }

    @Override
    public void beforeTextChanged(
            CharSequence s, int start, int count, int after) {
    }
};


// listener object for the EditText's text-changed events
private final TextWatcher secondEditTextWatcher = new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start,
                              int before, int count) {
        //  set minutes Total when text is changed, calls calculate, changes seconds to milliseconds
        if (s.charAt(start + count - 1) == '\n') {
            secondEditText.getText().replace(start + count - 1, start + count, " ");
            s = secondEditText.getText();
            Log.d("Lucas", "in enter key sec, s = " + s);


            try {
                secondsT = Integer.parseInt(s.toString());
                secondsTotal.setText(String.valueOf(secondsT) + " Seconds");
                secondsT *= 1000;
                percentageFinishedAmount.setText(" ");
                calculate();

            } catch (NumberFormatException e) {
                secondsTotal.setText("");
                secondsT = 0;

            }
        }

    }

    @Override
    public void afterTextChanged(Editable s) {
    }

    @Override
    public void beforeTextChanged(
            CharSequence s, int start, int count, int after) {
    }
};

1 Ответ

0 голосов
/ 11 мая 2018

Yowza.Я не совсем понимаю, какие требования предъявляются здесь или что вы делаете.

Мой подход был бы радикально другим, и, возможно, упущен смысл вашей попытки.Он будет иметь следующие элементы:

1) Вывод через SourceDataLine, так как это дает вам ручку, чтобы влиять на громкость каждого кадра.

2) Для каждого кадра обращайтесь к указателю в Sin LUT, который содержит столько же элементов, сколько необходимо для соответствия желаемой скорости.(Но было бы также неплохо просто создать аргумент в синусоидальной функции, которая увеличивает правильную величину каждого кадра, чтобы получить желаемую скорость. Нет необходимости вступать в войну из-за того, что функция или LUT работают лучше.)

3) Умножьте кадр SDL на значение Sin LUT.

Например, LFO 1 Гц будет означать либо LUT из 44100 элементов, либо аргумент, который увеличивается на 1/44100 на кадр.

Что касается получения доступа к отдельным звуковым кадрам, см. Учебное пособие Использование файлов и преобразователей формата / чтение звуковых файлов и найдите в примере пример с комментарием «Вот, сделайте что-нибудь полезное»с аудиоданными, которые теперь находятся в массиве audioBytes ".Эта полезная вещь будет состоять в том, чтобы преобразовать байты в PCM (есть другие способы объяснения StackOverflow), получить значение следующей функции sin и умножить, а затем преобразовать обратно в байты.

РЕДАКТИРОВАТЬ: Глядя в MediaPlayer API, яЯ не уверен, что вы сможете эффективно делать то, что вы хотите с этим классом.

Игрок не готов ответить на команды квази-немедленно, пока его статус не перейдет в MediaPlayer.Status.READY, что, как правило, обычно происходит после завершения предварительного ролика.

Означает ли это какой-то размер буфера, который ограничивает частоту, с которой вы можете делать обновления тома?ИДК.Когда мы сталкиваемся с проблемами размера буфера, которые приводят к максимальному количеству обновлений в секунду, нужно внимательно слушать, чтобы убедиться, что нет щелчков или молний из-за разрывов, когда громкость переходит с одного уровня на другой.Многое также зависит от количества накладных расходов, возникающих под капотом, когда вы устанавливаете положение для каждого изменения громкости.

С выходом SourceDataLine у ​​вас есть чистый доступ к каждому кадру, который в значительной степени устраняет потенциальные проблемы с застежкой-молнией.Я должен добавить заявление об отказе от ответственности, хотя я не работал с MediaPlayer и, возможно, не знаю о возможностях, которыми вы можете воспользоваться.В любом случае, SDL - это низкий уровень, мощный и эффективный.

...