Android пульсирует значком при изменении громкости .wav

Я создаю приложение для Android, которое пульсирует значком - простой импульс, 2-кратный размер при максимальной громкости и 1x при отсутствии громкости - на основе звука. Стоит отметить, что мой минимальный API равен 15.

Пользователь выбирает режим (файл) для воспроизведения, и я использую AudioTrack для его воспроизведения в бесконечном цикле. Каждый образец wav варьируется от ‹ секунды до 2 или 3 секунд. Audiotrack позволяет мне устанавливать громкость и высоту звука в режиме реального времени на основе ввода пользователя (SoundPool неправильно меняет высоту звука в Kitkat). Поскольку громкость меняется в каждой аудиодорожке, я пытаюсь уменьшить и увеличить значок. До сих пор я пробовал визуализатор для получения формы сигнала и данных fft во время воспроизведения трека, но я не уверен, что это правильно.

Есть ли способ получить (ближайшие возможные) изменения db в реальном времени из аудиодорожки? Функция формы волны, кажется, всегда находится между 108 и 112, поэтому я не думаю, что использую ее правильно. Самый простой пример файла pulse.wav — здесь

Моя аудиодорожка инициализируется с использованием байта [] из данных PCM

AudioTrack mAudioTrack = new AudioTrack(AudioAudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, getMinBuffer(sound), AudioTrack.MODE_STATIC);
mAudioTrack.write(mSound, 0, mSound.length);
mAudioTrack.setLoopPoints(0, (int)(mSound.length / 4), -1);

Мой визуализатор

Visualizer mVisualizer = new Visualizer(mAudioTrack.getAudioSessionId());
mVisualizer.setEnabled(false);
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener {
    @Override
    public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {
        double sum = 0;

        for (int i = 0; i < bytes.length; i++) {
            sum += Math.abs(bytes[i]) * Math.abs(bytes[i]);
        }

        double volume = (double) Math.sqrt(1.0d * sum / bytes.length);
        //THIS IS THE RESIZE FUNCTION//
        //resizeHeart((double) volume);
        System.out.println("Volume: " + volume); //always prints out between 108 and 112.
    }
    @Override
    public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {
        //not sure what to do here.
    }
}, Visualizer.getMaxCaptureRate() / 2, true, true);
mVisualizer.setEnabled(true);

person Brian Charles    schedule 13.11.2014    source источник


Ответы (1)


Проблема в том, что вы обрабатываете байты как выборки, даже если вы указали 16-битный размер выборки. Попробуйте что-то вроде этого (обратите внимание, что пресс не нужен, так как вы все равно возводите квадрат):

    for (int i = 0; i < bytes.length/2; i+=2) {
        int sample = bytes[i] << 8 || bytes[i+1];
        sum += sample * sample;
    }
person jaket    schedule 14.11.2014
comment
Это приводит к предупреждению оператора '||' нельзя применить к 'int', 'byte'. Какие-либо предложения? - person Brian Charles; 14.11.2014