Зацикливание аудио файла - PullRequest
2 голосов
/ 27 апреля 2011

Я пытаюсь генерировать и играть в прямоугольную волну. Я генерирую сигнал и затем использую

track = new AudioTrack(AudioManager.STREAM_MUSIC,
                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT, minSize,
                AudioTrack.MODE_STREAM);    
track.write(signal, 0, signal.length);

и затем вызывая track.play (). Проблема в том, что он играет только один раз. Похоже, что есть метод для установки точек цикла, но я не знаю, что добавить для кадров.

Я также пытался вызвать track.write (), а затем track.play () в цикле while, но есть небольшая задержка, и я все равно не думаю, что это правильный путь.

Как правильно создать бесшовную петлю?

Ответы [ 4 ]

6 голосов
/ 27 апреля 2011

Очень похожий вопрос: https://stackoverflow.com/questions/4241724/androidaudiotrack-setlooppoint-issue

Если я правильно прочитал документы по Android, вы используете 16-битные сэмплы, поэтому signal.length / 2 - это количество сэмплов. Я бы попробовал:

track.setLoopPoints(0, signal.length/2, -1);
1 голос
/ 30 мая 2013

Чтобы зациклить MODE_STREAM, дождитесь окончания цикла записи. Затем установите точки петли, затем снова вызовите play. Ничто из того, что я сделал с зацикливанием или даже без зацикливания AudioTrack, не вылечило щелчок при запуске.

0 голосов
/ 12 ноября 2015

Я столкнулся с той же проблемой сейчас, и кажется, что цикл не работает для меня, всегда есть небольшой разрыв между циклами, затем я пытаюсь продолжить генерировать звук и подавать аудиотрек, он работает для меня:

class ToneGenerator {
    int sampleRate = 8000;
    double sample[] = null;
    byte generatedSnd[] = null;
    int m_ifreq = 400;
    Thread m_PlayThread = null;
    boolean m_bStop = false;
    AudioTrack m_audioTrack = null;
    int m_play_length = 1000;//in seconds

    static public void PlayTone(int freq, int play_length) {
        ToneGenerator player = new ToneGenerator();
        player.m_ifreq = freq;
        player.m_play_length = play_length;
        player.play();
    }

    synchronized void stop() {
        m_bStop = true;
        if (m_PlayThread != null) {
            try {
                m_PlayThread.interrupt();
                m_PlayThread.join();
                m_PlayThread = null;
            } catch (Exception e) {

            }
        }
        if (m_audioTrack != null) {
            m_audioTrack.stop();
            m_audioTrack.release();
            m_audioTrack = null;
        }
    }

    synchronized void play() {
        m_bStop = false;
        m_PlayThread = new Thread() {
            public void run() {
                try {
                    int iToneStep = 0;

                    m_audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                            sampleRate, AudioFormat.CHANNEL_OUT_MONO,
                            AudioFormat.ENCODING_PCM_16BIT, 2 * sampleRate,
                            AudioTrack.MODE_STREAM);

                    while (!m_bStop && m_play_length-- > 0) {
                        genTone(iToneStep++);

                        m_audioTrack.write(generatedSnd, 0, generatedSnd.length);
                        if (iToneStep == 1) {
                            m_audioTrack.play();
                        }
                    }
                } catch (Exception e) {
                    Log.e("Tone", e.toString());
                } catch (OutOfMemoryError e) {
                    Log.e("Tone", e.toString());
                }

            }
        };
        m_PlayThread.start();
    }

    //Generate tone data for 1 seconds
    synchronized void genTone(int iStep) {
        sample = new double[sampleRate];

        for (int i = 0; i < sampleRate; ++i) {
            sample[i] = Math.sin(2 * Math.PI * (i + iStep * sampleRate) / (sampleRate / m_ifreq));
        }

        // convert to 16 bit pcm sound array
        // assumes the sample buffer is normalised.
        generatedSnd = new byte[2 * sampleRate];
        int idx = 0;
        for (final double dVal : sample) {
            // scale to maximum amplitude
            final short val = (short) ((dVal * 32767));
            // in 16 bit wav PCM, first byte is the low order byte
            generatedSnd[idx++] = (byte) (val & 0x00ff);
            generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
        }
    }

}
0 голосов
/ 20 июня 2012

Чтобы зациклить аудиофайл бесконечное количество раз, установите значение цикла -1. Чтобы устранить задержку при зацикливании аудиофайла, используйте класс SoundPool вместо MediaPlayer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...