Обработка звука в реальном времени Android

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

На данный момент у меня есть приложение, которое записывает звук в течение заранее определенного времени и сохраняет его в файле WAV, который затем обрабатывается.

Это работает довольно хорошо, но, поскольку меня просто интересует запись импульсных откликов, я подумал, что было бы неплохо, если бы мое приложение автоматически определяло, когда возник импульс, и просто сохраняло образцы за 0,5 сегмента до импульса. и до 1,5 секунд после (всего 2 секунды).

Вот как я имею дело с байтовым массивом файла wav:

double audioSample = (double) (array[i+1] << 8 | array[i] & 0xff)/ 32767.0;

Это дает мне значения между [-1,1], поэтому, допустим, моя идея заключалась бы в рассмотрении импульса любого звука более или менее 0,3. Я думаю, что решение будет заключаться в хранении образцов в буфере и проверке его значений в реальном времени, но я не совсем уверен, как это реализовать.

Вы, ребята, знаете какой-нибудь образец кода или что-нибудь, на что я могу взглянуть?


person paviflo    schedule 13.06.2014    source источник


Ответы (1)


Вы на правильном пути. Вы захотите сохранить свои сэмплы в кольцевом буфере, который достаточно велик, чтобы обрабатывать необходимое количество предтриггерных сэмплов. Вы можете легко найти код циклического буфера в Интернете или на SO. Как только ваше условие триггера выполнено, выгрузите содержимое кольцевого буфера на диск, установите условие и оттуда выполните запись на диск. Вот несколько псевдокодов для начала.

void ProcessSamples(double[] samples)
{
    if (!triggered)
    {
        // write your level test here. Return -1 if you don't find anything
        // otherwise return the index of the sample.
        int triggerPos = SearchForTrigger(samples);
        if (triggerPos >= 0)
        {
            circularBuffer.Add(samples, triggerPos); // add up to the trigger pos
            WriteSamplesToFile(circularBuffer.GetSamples());
            triggered = true;
        }
        else
        {
            circularBuffer.Add(samples, samples.Length); // add all of the samples.
        }
    }
    else
    {
        WriteSamplesToFile(samples);
    }
}
person jaket    schedule 13.06.2014
comment
Я пытался поработать над этим, но я немного зациклился на размерах буферных массивов. Если я хочу, чтобы кольцевой буфер давал мне 0,5 секунды выборок, какого размера он должен быть? Я знаю об AudioRecord.getMinBufferSize (RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); но я действительно не знаю, какому количеству времени соответствует этот bufferSize - person paviflo; 22.06.2014
comment
Это зависит от частоты дискретизации. При частоте дискретизации 48 кГц получается 48000 отсчетов в секунду, поэтому 0,5-секундный буфер должен содержать 24000 отсчетов. Удвойте это, если у вас два канала. Мой пример уже компенсировал размер выборки, предполагая, что выборки были преобразованы в двойные до буферизации. - person jaket; 23.06.2014
comment
Можете ли вы помочь мне с https://stackoverflow.com/questions/61184352/android-accessibility-service-real-time-audio-processing question - person Feroz Siddiqui; 13.04.2020