19

iOS には、一部の USB オーディオ デバイスを介した録音に問題があります。確実に再現することはできません (バッチで約 2000 ~ 3000 レコードに 1 つずつ発生し、静かに消えます)。現在、音声に録音の問題がないか手動でチェックしています。これにより、少数のサンプル (1 ~ 20) が、一種の「パチパチ」のように聞こえる少数だけシフトされます。

それらは次のようになります。

異常波形

クローザー:

ここに画像の説明を入力

クローザー:

ここに画像の説明を入力

同じ音声ファイルの別の場所にある別の単一のサンプル エラー:

ここに画像の説明を入力

問題は、次のような波形を持つ高周波オーディオで誤検知をトリガーせずに、これらをアルゴリズムで検出する方法 (サンプルへの直接アクセスを想定) です。

ここに画像の説明を入力

ボーナス ポイント: できるだけ多くのエラーを特定した後、オーディオを「修正」するにはどうすればよいでしょうか?

その他のボーナス ポイント: iOS USB オーディオ ドライバー/ハードウェアでこの問題を引き起こしている可能性があるもの (そこにあると仮定)。

4

5 に答える 5

14

障害を見つけるためのすぐに使える解決策はないと思いますが、問題に取り組む 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);

したがって、元のデータのこのプロットの代わりに:

元データ

我々が得る:

差分ログデータ

ここで、探している間隔は正と負のスパイクとして際立っています。たとえば、対数差のプロットで最大の正の値を拡大すると、次の 2 つの図が得られます。元のデータ用の 1 つ:

元のデータをズーム

1 つは対数の差です。

ズームされた差分ログ データ

このプロットは、領域を手動で見つけるのに役立ちますが、理想的には、アルゴリズムを使用してそれらを見つけたいと考えています。私がこれを行った方法は、サイズ 6 の移動ウィンドウを取得し、ウィンドウの平均値 (最小値を除くすべてのポイント) を計算し、これを最大値と比較することでした。最大点が平均値を超え、平均値の少なくとも 2 倍の大きさの唯一の点である場合、それは正の極値としてカウントされます。

次に、カウントのしきい値を使用しました。値を超えて移動するウィンドウの少なくとも半分は、それを受け入れるために極値として検出する必要があります。

すべてのポイントに (-1) を掛けると、このアルゴリズムが再度実行され、最小値が検出されます。

正の極値を「o」で、負の極値を「*」でマークすると、次の 2 つのプロットが得られます。対数の差の 1 つ:

検出された極値を含む diff-log-data

もう 1 つは元のデータ用です。

極値が見つかった元のデータ

対数差を示す図の左側を拡大すると、ほとんどの極端な値が見つかっていることがわかります。

見つかった極値をズームした diff-log-data

ほとんどの間隔が見つかったようで、誤検知はごくわずかです。たとえば、アルゴリズムを実行する'clean-highfreq.wav'と、1 つの正の極値と 1 つの負の極値しか見つかりません。

極端な値として誤って分類された単一の値は、開始点と終了点を一致させることによって除外される可能性があります。また、失われたデータを置き換えたい場合は、周囲のデータポイントを使用してある種の補間を使用できます。おそらく、線形補間でも十分です。

私が使用した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 の間です)。

元のデータが縮小されました

値を調べると、データが負の値にミラーリングされているというあなたの理論は、パターンに正確に適合していないようです。しかし、いずれにせよ、単に違いを取り除くという私の考えは確かに正しくありません。周囲のポイントは外乱によって変更されていないように見えるので、影響を受けた領域内のポイントを信頼せず、代わりに周囲のデータを使用して何らかの補間を使用するという元のアイデアにおそらく戻るでしょう。ほとんどの場合、単純な線形補間が非常に良い近似になるようです。

于 2013-03-14T13:51:36.187 に答える
9

なぜそれが起こるのかという質問に答えるために -

USB オーディオ デバイスとホストはクロック同期していません。つまり、ホストは、ホストのローカル クロックとオーディオ インターフェイスの ADC/DAC のワードクロックとの関係を正確に復元できません。さまざまな程度の有効性を持つクロック回復のためのさまざまな手法が存在します。さらに、バス クロックは 2 つのオーディオ クロックのいずれとも無関係である可能性があります。

これはオーディオ受信にとってあまり問題ではないと想像するかもしれませんが、データがある場合にオーディオ キャプチャ コールバックが発生する可能性があります。通常、オーディオ インターフェイスは双方向であり、ホストは一定の間隔でオーディオをレンダリングします。わずかに異なる速度で消費する可能性があります。

その間にいくつかのバッファ セットがあり、オーバーランまたはアンダーランする可能性があります。これがここで発生しているように見えます。それが起こる間隔は確かに正しいようです。

USB オーディオ デバイスを、別のチップ セット (または単に別のローカル オシレーター) を中心に構築されたものに変更すると、問題が解決する場合があります。

余談ですが、IEEE1394 オーディオと MPEG トランスポート ストリームには、同じクロック リカバリ要件があります。どちらも、非常に予測可能な方法でローカル クロック リファレンス パケットをシリアル ビットストリームに埋め込むことで問題を解決し、相手側で正確なクロック リカバリを可能にします。

于 2013-03-08T19:57:13.650 に答える
2

潜在的な偽陽性を判断するために、次のアルゴリズムをサンプルに適用できると思います。

最初に、ブロックごとにサウンドブロックをFFTするか(おそらく256値)、またはゼロより上と下の連続サンプルをカウントすることにより、大量の高周波をスキャンします。後者は、ゼロより上の最大連続値、ゼロより下の最大連続値、ゼロ付近の小さな遷移の量、およびブロックの現在のボリューム (Audacity が表示するように 0..1) を追跡する必要があります。次に、連続する最大値が 5 未満の場合 (44100 でサンプリングし、0 が連続している場合、サンプルが 1 つの場合、5 は 4410Hz の周波数に応答します。これはかなり高い値です)、または小さな遷移の長さの合計が特定の値を超えている場合。連続する最大値に応じて (最初の概算は 3*5* ブロック サイズ/2 つの最大値間の距離になると思います。これは、最も大きな FFT 周波数の周期にほぼ相当します。また、誤ったピークが発生する可能性があるため、しきい値の上と下の両方で測定する必要があります。これは、ゼロ未満またはゼロを超える最大値で測定されたメインテンポの差、およびピークの標準偏差によって検出される可能性があります。高周波が支配的な場合、このブロックはゼロ値テストにのみ適しており、データを修復する特別な手段が必要になります。高周波数が重要な場合、つまり支配的な低周波数が検出された場合、3.0*高周波数ボリュームより大きいピークと、このブロック内の異常なゼロを検索できます。データを修復するための特別な手段が必要になります。高周波数が重要な場合、つまり支配的な低周波数が検出された場合、3.0*高周波数ボリュームより大きいピークと、このブロック内の異常なゼロを検索できます。データを修復するための特別な手段が必要になります。高周波数が重要な場合、つまり支配的な低周波数が検出された場合、3.0*高周波数ボリュームより大きいピークと、このブロック内の異常なゼロを検索できます。

また、ギャップは高度に拡張されているか、単純にゼロであるように見えます。高度に拡張された場合は単一のエラーになり、ゼロエラーの範囲は 1 ~ 20 です。したがって、0.15 (微調整する変数) 以上の絶対値と同じ符号の値で直接囲まれている絶対値 0.02 未満の値を持つゼロ範囲がある場合、この点をエラーとしてカウントします。計算すると、際立った単一の値を検出できます2.0*(current sample)-(previous sample)-(next sample)。特定のしきい値 (0.1 + 高周波数ボリューム、または 3.0 * 高周波数ボリュームのいずれか大きい方) を超えている場合は、これをエラーとしてカウントし、平均します。

検出されたゼロ ギャップをどうするか - 1 周期後方および 1 周期前方 (平均化) から値をコピーできます。ここで、「周期」はブロックの FFT の最も重要な周波数です。「期間」がギャップよりも小さい場合 (サウンドの高音部分でゼロのギャップを検出したとします)、2 つ以上の期間を使用して、ソース データがすべて有効になるようにします (この場合、ギャップから 2 周期前の信号と 2 周期前の信号が逆位相になる可能性があるため、平均化はできません)。ほぼ等しい振幅の周波数が複数ある場合は、これらを正しい位相で単純にサンプリングして、重要度の低い残りの周波数を完全にカットできます。

優れたサンプルは、サウンド ファイルでこれまでに遭遇したサンプルが 1 つしかないように見えるため、IMO を 2 ~ 4 の周囲のサンプルで平均化する必要があります。

于 2013-03-14T12:02:33.573 に答える
2

離散ウェーブレット変換 (DWT) が問題の解決策になる場合があります。

FFT計算は、信号の全期間にわたる相対周波数コンテンツの平均表現であり、瞬間的な変化を検出できないため、あなたの場合にはあまり役に立ちません。離散短時間周波数変換 (STFT) は、信号の連続する短い時間ブロックの DFT を計算することでこれに対処しようとします。その長さはウィンドウの長さ (および形状) によって決まりますが、 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

于 2013-03-15T13:10:43.447 に答える
1

次の非常に単純なアプローチを試すことができます(多分それで十分です):

  1. 波形の各ポイントを取り、その前のポイントを引きます(あるポイントから次のポイントへの変化を見てください)。
  2. これらの変化の分布を見て、それらの標準偏差を見つけます。
  3. 与えられた差がこの標準偏差のX倍(上または下)を超えている場合は、問題としてフラグを立てます。
  4. Xを試して、Xのパフォーマンスを確認することにより、Xの最適な値を決定します。
  5. ほとんどの「問題」は、カットオフを超えた2つの違いのペアとして発生するはずです。1つは上昇し、もう1つは下降します。

超単純なアプローチに固執するために、問題セクションの前の最後の良い点と後の最初の良い点の間を線形補間するだけでデータを修正できます。(ポイントを削除すると、オーディオのピッチに影響(上昇)するため、削除しないでください。)

于 2013-03-15T01:08:22.373 に答える