Подтвердить что ты не робот

Как я могу обнаружить эти звуковые аномалии?

У iOS есть проблема с записью через некоторые аудиоустройства USB. Он не может быть надежно воспроизведен (происходит каждые 1 из ~ 2000-3000 записей в партиях и тихо исчезает), и мы в настоящее время вручную проверяем наш звук на любые проблемы с записью. Это приводит к тому, что небольшое количество выборок (1-20) сдвигается на небольшое число, которое звучит как своего рода "треск".

Они выглядят так:

Waveform with abnormality

ближе:

enter image description here

ближе:

enter image description here

другая, одна ошибка образца в другом месте в том же звуковом файле:

enter image description here

Вопрос в том, как они могут быть алгоритмически обнаружены (при условии прямого доступа к выборкам), не вызывая ложных срабатываний на высокочастотном звуке с такими формами сигналов:

enter image description here

Бонусные очки: после определения как можно большего числа ошибок, как звук может быть "зафиксирован"?

Дополнительные бонусные баллы: что может быть причиной этой проблемы в аудио драйверах/аппаратных средствах iOS USB (предполагается, что они есть).

4b9b3361

Ответ 1

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

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

В MATLAB я загружаю данные (в этом примере я использую dirty-sample-other.wav)

y1 = wavread('dirty-sample-pictured.wav');
y2 = wavread('dirty-sample-other.wav');
y3 = wavread('clean-highfreq.wav');

data = y2;

и используйте следующий код:

logdata = log(1+data);
difflogdata = diff(logdata);

Итак, вместо этого графика исходных данных:

original data

получаем:

diff-log-data

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

Original data zoomed

и один для разности логарифмов:

Diff-log-data zoomed

Этот график может помочь найти области вручную, но в идеале мы хотим найти их с помощью алгоритма. То, как я это делал, было сделать движущееся окно размером 6, вычисляя среднее значение окна (всех точек, за исключением минимального значения), и сравнивайте это с максимальным значением. Если максимальная точка является единственной точкой, которая выше среднего значения и по крайней мере вдвое больше, чем средняя, ​​она считается положительным экстремальным значением.

Затем я использовал порог подсчетов, по крайней мере, половина окон, перемещающихся над значением, должна была определить его как крайнее значение, чтобы оно могло быть принято.

Умножая все точки с (-1), этот алгоритм снова запускается для определения минимальных значений.

Пометив положительные крайности "о" и отрицательные крайности на "*", получим следующие два графика. Один для разности логарифмов:

diff-log-data with found extremes

и один для исходных данных:

original data with found extremes

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

diff-log-data with found extremes zoomed

Кажется, что большинство интервалов найдено, и есть только небольшое количество ложных срабатываний. Например, запустив алгоритм на 'clean-highfreq.wav', я нахожу только одно положительное и одно отрицательное экстремальное значение.

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

Вот код MATLAB, который я использовал:

function test20()
clc
clear all

y1 = wavread('dirty-sample-pictured.wav');
y2 = wavread('dirty-sample-other.wav');
y3 = wavread('clean-highfreq.wav');

data = y2;

logdata = log(1+data);
difflogdata = diff(logdata);

figure,plot(data),hold on,plot(data,'.')
figure,plot(difflogdata),hold on,plot(difflogdata,'.')

figure,plot(data),hold on,plot(data,'.'),xlim([68000,68200])
figure,plot(difflogdata),hold on,plot(difflogdata,'.'),xlim([68000,68200])

k = 6;
myData = difflogdata;
myPoints = findPoints(myData,k);

myData2 = -difflogdata;
myPoints2 = findPoints(myData2,k);

figure
plotterFunction(difflogdata,myPoints>=k,'or')
hold on
plotterFunction(difflogdata,myPoints2>=k,'*r')

figure
plotterFunction(data,myPoints>=k,'or')
hold on
plotterFunction(data,myPoints2>=k,'*r')

end

function myPoints = findPoints(myData,k)

iterationVector = k+1:length(myData);
myPoints = zeros(size(myData));
for i = iterationVector
    subVector = myData(i-k:i);
    meanSubVector = mean(subVector(subVector>min(subVector)));
    [maxSubVector, maxIndex] = max(subVector);
    if (sum(subVector>meanSubVector) == 1 && maxSubVector>2*meanSubVector)
        myPoints(i-k-1+maxIndex) = myPoints(i-k-1+maxIndex) +1;
    end
end

end

function plotterFunction(allPoints,extremeIndices,markerType)

extremePoints = NaN(size(allPoints));
extremePoints(extremeIndices) = allPoints(extremeIndices);
plot(extremePoints,markerType,'MarkerSize',15),
hold on
plot(allPoints,'.')
plot(allPoints)

end

Изменить - комментарии по восстановлению исходных данных

Ниже показан слегка увеличенный вид рисунка 3 выше: (помехи между 6.8 и 6.82)

Original data zommed out

Когда я исследую значения, ваша теория о зеркальном отражении данных к отрицательным значениям, похоже, точно не соответствует шаблону. Но в любом случае моя мысль об устранении различий, конечно, неверна. Поскольку окружающие точки, похоже, не изменяются из-за нарушения, я, вероятно, вернусь к первоначальной идее не доверять точкам в затронутом регионе и вместо этого использовать какую-то интерполяцию с использованием окружающих данных. Похоже, что простая линейная интерполяция в большинстве случаев будет неплохим приближением.

Ответ 2

Чтобы ответить на вопрос, почему это происходит -

Аудиоустройство и хост USB не синхронизированы по времени, то есть хост не может точно восстановить связь между локальными часами хоста и синхронизирующими сигналами АЦП/ЦАП на аудиоинтерфейсе. Различные методы существуют для восстановления часов с различной степенью эффективности. Чтобы добавить к проблеме, часы шины, вероятно, не связаны ни с одним из двух звуковых часов.

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

В промежутке находятся несколько наборов буферов, которые могут быть перегружены или запущены, что, как представляется, происходит здесь; промежуток между этим случается, конечно, о праве.

Возможно, вы обнаружите, что изменение аудиоустройства USB на один, построенный на другом чип-наборе (или просто другом локальном генераторе).

Как и в случае с IEEE1394 аудио и MPEG-транспортными потоками имеют одинаковое требование восстановления часов. Оба они решают эту проблему с помощью встраивания локального тактового сигнала опорного пакета в последовательный поток битов в очень предсказуемым способом, который позволяет точное восстановление синхронизации на другом конце.

Ответ 3

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

Во-первых, сканирование большого количества высокой частоты, либо с помощью FFT'ного звукового блока по блоку (возможно, 256 значений), либо путем подсчета последовательных образцов выше и ниже нуля. Последнее должно отслеживать максимальное последовательное значение выше нуля, максимальное последовательное значение ниже нуля, количество малых переходов вокруг нуля и текущий объем блока (0..1, когда Audacity отображает его). Затем, если максимальное последовательное значение меньше 5 (выборка на уровне 44100 и нули будут последовательными, а выборки выборочной выборки одиночные, 5 - частота 4410 Гц, что довольно высокое), или сумма длин малых переходов выше определенного значения в зависимости от максимального последовательного (я считаю, что первым приближением будет 3 * 5 * размер блока/расстояние между двумя максимумами, что примерно соответствует периоду самой громкой частоты FFT. Также он должен быть измерен как выше, так и ниже порога, поскольку мы можем закончить с вероятностью ошибки, которая, скорее всего, будет определяться разницей между основным темпом, измеренным на максимумах ниже нуля или выше нуля, также с помощью std-dev пиков. Если высокая частота является доминирующей, этот блок имеет право только на нулевое значение тестирование и специальные средства для восстановления данных. Если высокая частота является значительной, то есть обнаруживается доминирующая низкая частота, мы можем искать пики, превышающие объем громкости 3.0 *, а также аномальные нули в этот блок.

Кроме того, ваши пробелы, по-видимому, либо сильно расширяются, либо равны нулю, а высокие - одиночными, а нулевые ошибки - от 1 до 20. Таким образом, если существует нулевой диапазон со значениями под 0,02 абсолютного значения, который непосредственно окружен значениями 0,15 (переменная, подлежащая финализации) или более высоким абсолютным значением И того же знака, считайте эту точку ошибкой. Одиночные значения, которые выделяются, могут быть обнаружены, если вы вычисляете 2.0*(current sample)-(previous sample)-(next sample), и если он превышает определенный порог (0,1 + высокочастотный том или 3.0 * объем высокой частоты, в зависимости от того, что больше), считайте это ошибкой и средним значением.

Что делать с нулевыми пробелами - мы можем скопировать значения из 1 периода назад и 1 период вперед (усреднение), где "период" имеет самую значительную частоту БПФ блока. Если "период" меньше пробела (скажем, мы обнаружили разрыв нулей в высокой части звука), используйте два или более периодов, поэтому исходные данные будут действительны (в этом случае, усреднение не может быть сделано, поскольку возможно, что сигнал 2 периодов вперед от зазора и 2 периода назад будет находиться в противофазе). Если имеется более чем одна частота примерно равной амплитуды, мы можем просто пробовать их с правильными фазами, вообще сокращая остальные менее значимые частоты.

Выдающийся образец должен IMO просто усредняться по 2-4 окружающим образцам, так как, кажется, в ваших звуковых файлах встречается только один образец.

Ответ 4

Дискретное вейвлет-преобразование (DWT) может быть решением вашей проблемы.

Расчет FFT не очень полезен в вашем случае, поскольку он представляет собой среднее представление относительного частотного содержимого на протяжении всей продолжительности сигнала и, следовательно, невозможно обнаружить мгновенные изменения. Дискретное короткое временное преобразование частоты (STFT) пытается решить это путем вычисления ДПФ для коротких последовательных блоков времени сигнала, длина которого определяется длиной (и формой) окна, но поскольку разрешение DFT зависит от длины данных/длины блока, есть компромисс между разрешением по частоте ИЛИ во времени, и найти этот волшебный фиксированный размер окна может быть сложным!

Что вы хотите - это метод частотно-частотного анализа с хорошим временным разрешением для высокочастотных событий и хорошее частотное разрешение для низкочастотных событий... Введите дискретное вейвлет-преобразование!

Существует множество вейвлет-преобразований для разных приложений, и, как вы могли ожидать, это вычислительно тяжело. DWT не может быть практическим решением вашей проблемы, но это стоит рассмотреть. Удачи вам в вашей проблеме. Некоторые чтения в пятницу вечером:

http://klapetek.cz/wdwt.html

http://etd.lib.fsu.edu/theses/available/etd-11242003-185039/unrestricted/09_ds_chapter2.pdf

http://en.wikipedia.org/wiki/Wavelet_transform

http://en.wikipedia.org/wiki/Discrete_wavelet_transform

Ответ 5

Вы можете попробовать следующий сверхпростой подход (возможно, достаточно):

  • Возьмите каждую точку в своей волновой форме и вычтите ее предшественника (посмотрите на изменения от одной точки к следующей).
  • Посмотрите на распределение этих изменений и найдите их стандартное отклонение.
  • Если какое-либо заданное различие превышает X раз, это стандартное отклонение (выше или ниже) означает, что это проблема.
  • Определите наилучшее значение для X, играя с ним и видя, насколько хорошо он выполняет.
  • Большинство "проблем" должны возникать как пара двух различий за пределами вашего обрезания, один идет вверх, а один возвращается.

Чтобы придерживаться сверхпростого подхода, вы можете исправить данные, просто интерполируя линейно между последней хорошей точкой перед вашей проблемной секцией и первой хорошей точкой после. (Убедитесь, что вы не просто удаляете точки, так как это повлияет (повысит) высоту тона вашего звука.)