2016-10-05 14 views
8

는 내가이 타임 스탬프의 두 배열 사이의 오프셋을 찾고 싶어요. 두 개의 오디오 트랙에서 경고음이 발생한다고 가정 해 보겠습니다.타임 스탬프 배열에 상호 상관을 사용하는 것이 합리적입니까?

참고 : 두 트랙 중 하나에 여분 또는 부족한 온셋이있을 수 있습니다.

나는 유망 보았다 상호 상관 (예를 들어, https://dsp.stackexchange.com/questions/736/how-do-i-implement-cross-correlation-to-prove-two-audio-files-are-similar)에 대한 정보를 발견했다.

I는 각 오디오 트랙의 지속 기간 10 초라고 가정하고, 44.1 kHz의 샘플링 속도는 "구형파"의 피크와 경고음 온셋을 표현 :

import numpy as np 

rfft = np.fft.rfft 
irfft = np.fft.irfft 

track_1 = np.array([..., 5.2, 5.5, 7.0, ...]) 
# The onset in track_2 at 8.0 is "extra," it has no 
# corresponding onset in track_1 
track_2 = np.array([..., 7.2, 7.45, 8.0, 9.0, ...]) 
frequency = 44100 
num_samples = 10 * frequency 
wave_1 = np.zeros(num_samples) 
wave_1[(track_1 * frequency).astype(int)] = 1 
wave_2 = np.zeros(num_samples) 
wave_2[(track_2 * frequency).astype(int)] = 1 
xcor = irfft(rfft(wave_1) * np.conj(rfft(wave_2))) 
offset = xcor.argmax() 

이 방법은 아니다 특히 빠르지 만 상당히 낮은 주파수에서도 상당히 일관된 결과를 얻을 수있었습니다. 그러나 ... 나는 이것이 좋은 생각인지 전혀 모른다! 상호 상관보다이 오프셋을 찾는 더 좋은 방법이 있습니까?

편집는 : 누락 추가 온셋에 대한 메모를 추가했다.

+0

당신은'track_1'하고 불규칙한 간격, 다음 frequency''곱해'track_2'을 보여줍니다. 당신이 상관 관계를 위해 노력하고 타임 스탬프 있어야'track_1'와'track_2'가, 아니면 그들은 경고음이 추가없이 오디오 파형 있어야된다? 또는 그들이 "삐"의 발병시기입니까? – Brian

+0

'track_1'과'track_2'는 각 경고음의 시작 시간입니다. 'wave_1'과'wave_2'는 교차 상관 관계를 찾는 목적으로 Dirac 델타 함수를 합한 것입니다. – user1475412

답변

3

track_1track_2이 경고음의 타임 스탬프이고 둘 다 경고음을 모두 수신하면 파형을 작성하고 상호 상관을 수행 할 필요가 없습니다. 그냥 삐 타임 스탬프의 두 배열 사이의 평균 지연을 찾을 :

import numpy as np 

frequency = 44100 
num_samples = 10 * frequency 
actual_time_delay = 0.020 
timestamp_noise = 0.001 

# Assumes track_1 and track_2 are timestamps of beeps, with a delay and noise added 
track_1 = np.array([1,2,10000]) 
track_2 = np.array([1,2,10000]) + actual_time_delay*frequency + 
      frequency*np.random.uniform(-timestamp_noise,timestamp_noise,len(track_1)) 

calculated_time_delay = np.mean(track_2 - track_1)/frequency 
print('Calculated time delay (s):',calculated_time_delay) 

이 도입 임의의 오류에 따라 약 0.020의를 산출 약 한 빨리이수록입니다.

EDIT : 추가 또는 누락 된 시간 소인을 처리해야하는 경우 코드를 다음과 같이 수정할 수 있습니다. 본질적으로, 타임 스탬프 무작위성의 오류가 제한되면 모든 값 사이의 지연에 대해 통계적 "모드"기능을 수행하십시오. 시간 소인 임의성 범위 내의 모든 항목이 함께 클러스터되고 식별 된 다음 원래 식별 된 지연이 평균됩니다. 너무 많은 경고음이 누락 또는 추가 신호음이 존재하는 경우

import numpy as np 
from scipy.stats import mode 

frequency = 44100 
num_samples = 10 * frequency 
actual_time_delay = 0.020 

# Assumes track_1 and track_2 are timestamps of beeps, with a delay, noise added, 
# and extra/missing beeps 
timestamp_noise = 0.001 
timestamp_noise_threshold = 0.002 
track_1 = np.array([1,2,5,10000,100000,200000]) 
track_2 = np.array([1,2,44,10000,30000]) + actual_time_delay*frequency 
track_2 = track_2 + frequency*np.random.uniform(-timestamp_noise,timestamp_noise,len(track_2)) 

deltas = [] 
for t1 in track_1: 
    for t2 in track_2: 
     deltas.append(t2 - t1) 
sorted_deltas = np.sort(deltas)/frequency 
truncated_deltas = np.array(sorted_deltas/(timestamp_noise_threshold)+0.5, 
dtype=int)*timestamp_noise_threshold 

truncated_time_delay = min(mode(truncated_deltas).mode,key=abs) 
calculated_time_delay = np.mean(sorted_deltas[truncated_deltas == truncated_time_delay]) 

print('Calculated time delay (s):',calculated_time_delay) 

은 물론, 다음 코드는 어떤 점에서 실패하기 시작하지만, 일반적으로는 잘 작동하고 전체 파형을 생성하기 위해 노력하고 상관 관계를 수행하는 것보다 빠른 방법이어야한다 . `wave_1`와`wave_2`을 구축 할 때

+0

나는이 순간을 더 자세히 조사 할 수는 없지만, 값이나 누락 된 값과 같은 다른 종류의 "노이즈"를 트랙에 남겨 두지 않는 것처럼 보입니다. 그게 맞습니까? – user1475412

+0

누락/추가 경고음도 처리해야합니다. 당신 말이 맞아요, 그걸 처리하지 못할 겁니다. – Brian

+0

예, 죄송합니다. 나는 그 정면을 분명히해야했다. 나는 그 질문을 편집 할 것이다. – user1475412

3

네, 그것은 의미가 없습니다. 이것은 일반적으로 MATLAB에서 이루어집니다. 문제의 신호가 너무 많은 소음이있는 경우

간 상관 관계가 일반적으로 시간에 사용되는

http://www.mathworks.com/help/signal/ug/cross-correlation-of-delayed-signal-in-noise.html

몇 가지 고려 사항 : 다음은 유사한 응용 프로그램에 대한 링크입니다. 걱정할 소음이 없다면 다른 방법을 쓰겠습니다.

+0

글쎄, 내 관심사는 그것의 "사각형 파도"부분입니다. onset 배열'track_1'이'[1, 2, 1000000]'이면, 둘 다 3 개의 원소를 가지고 있더라도'[1, 2, 3] '보다 훨씬 더 큰 입력 ('wave_1') 배열을 생성합니다. – user1475412

+0

"걱정할 소음이 없으면 다른 방법을 쓰겠습니다."다른 방법을 권할 수 있습니까? – user1475412

+0

'f1()'과'g()'의 두 함수가 있다고 가정합니다. 여기서'g()'는 노이즈없는 알려진 패턴이고 f1()은 오디오 샘플입니다. 나는 f1()에 대해 g()를 슬라이드시키고 샘플 h1 (s) = integral [f1 (s) -g (s-S) ds]'라고 표기한다. 그렇다면 모든 최대 값을 찾을 수 있습니다. 그것들은 기능이 존재하는 장소입니다. 'h2 (s) = integral [f2 (s) -g (s-S) ds]'에 대해서도 같은 일을한다. 그런 다음 로컬 최대 값과 가장 낮은 수평 차이가 나올 때까지 h2_max()를 h1_max() 위로 이동하십시오. –