포락선 구하기
저번 글에서는 오디오 신호의 변화 특성 그리고 시정수를 이용하서 포락선을 구하는 개요를 알아 봤습니다. 이번 글에서는 실제 다이내믹 선호처리에서 사용하난 실효치를 이용한 포락선 검출과 피크 발생을 고려한 포락선을 구하는 두가지 방법을 알아보겠습니다.
실효치 포락선 구하기
실효치(rms)는 아래의 글과 같이 특정 구간의 신호들에 대해 평균을 먼저 계산해야지만 구해지는 값입니다. 그런데 신호처리 과정에서 실효치를 구하기 위한 연산을 할당할 정도로 DSP가 한가한 경우는 드물 것입니다.
굳이 실효치가 매우 중요한 역할을 하지 않는 한 입력 신호에 대해 곧바로 근삿값이라도 실효치를 계산해 준다면 좋을 것입니다.
또 신호처리 과정에서 레벨 미터 정보를 만들 필요가 있는데 근사 실효치는 아날로그식 VU 미터와 거의 같은 특성으로 오디오 신호 정보를 제공해 주는 데 사용됩니다.
아래의 스크립트는 신호가 위에서 사용한 스크립트를 이용해서 한 개의 입력 신호가 들어올 때마다 실효치를 구해서 이를 포락선으로 보여주는 내용입니다. 실제로 다이내믹 프로세서의 대부분은 이 방식을 조금 변형해서 사용합니다.
clear all
file_name = 'test.wav';
[xx,fs]=audioread(file_name);
fs = 44100;
alpha = 1 * 10^-3;
tau = exp(-1/ alpha/fs);
start_x = 35000;
gap = 10000;
end_x = start_x + (gap-1);
x = xx(start_x:end_x,1);
rms = abs(x(1,1));
for i = 1 : gap
tmp = x(i) * x(i);
rms = tmp + (tau*(rms-tmp));
y(i,1) = sqrt(rms);
endfor
clf
plot(x,'g');
hold on
plot(y,'r');
ylim([-0.3 0.3]);
grid on;
아래 그림은 $\alpha = 1m$sec인 조건에서 얻어진 rms 포락선입니다. 좀 더 정보를 부드럽게 만들어 보겠습니다.
아래 그림은 $\alpha = 10m$sec인 조건에서 얻어진 rms 포락선입니다. 처음의 포락선 추출 방법보다 rms 방식에 신호 흐름을 잘 반영하는 것 같습니다.
아래 그림은 $\alpha = 100m$sec인 조건에서 얻어진 rms 포락선으로 과도한 조건으로 신호 흐름의 반영이 되지 않은 것으로 보입니다.
이와 같은 방법을 사용하면 다이내믹 신호 처리를 위한 포락선 검출에 많은 연산을 사용하지 않고도 실시간으로 실효치 정보를 얻을 수 있습니다.
피크 포락선 검출
오디오 신호는 시간에 따라 변화가 많을 뿐만이 아니라 피크(peak) 신호의 발생도 빈번하며 오디오 신호의 특징을 만듭니다. 이 피크 신호 특성을 이용해서 다이내믹 처리와 오디오 레벨 미터가 동작됩니다.
다이내믹 신호처리를 위해선 피크 포락선과 같은 포락선 검출이 선행되어야 하는 매우 중요한 내용입니다.
이 글에서는 피크 신호를 검출하여 표시하는 방법을 다뤄보겠습니다.
피크 신호
피크(peak) 신호는 주변보다 신호의 절대적인 크기가 큰 부분을 의미합니다. 오디오 신호는 다수의 피크 신호가 계속해서 발생하며 오디오 신호 특성에 영향을 줍니다. 그래서 피크 신호가 언제 발생했는지 검출하는 방법이 필요합니다.
피크 포락선
피크 포락선은 피크가 발생한 위치를 이용해서 만드는 또다른 포락선 방법입니다.
피크 포락선은 크게 보면 피크 검출 -> 피크 유지 -> 피크 해지 또는 피크 검출 -> 피크 유지 -> 피크 갱신 -> 피크 해지 순서로 진행됩니다.
- 피크 검출 : 과거 입력 신호보다 큰 신호가 수신되면 피크 검출로 판단합니다.
- 피크 유지(peak hold) : 피크가 발생한 후에 더 큰 신호가 입력되기 전까지 피크가 발생했음을 유지합니다. 유지 시간은 임의로 결정할 수 있습니다.
- 피크 갱신 : 피크 유지 상태에서 또 다른 피크가 발생하면 과거 상태를 버리고, 피크 검출과 피크 유지 단계로 변경합니다.
- 피크 해지 : 피크 유지가 완료되면 피크 상태를 해지하고 다시 피크를 검출합니다.
피크 검출기
다음의 GNU Octave 스크립트는 위의 포락선 내용을 만들어주는 피크 검출기(peak detector) 내용입니다. 여기서 peak_hold_time이 피크 검출하고 유지하는 시간입니다.
피크 검출 시간이 특정 조건 이상이거나 현재 신호가 새로운 피크 신호이며 조건을 갱신하는 내용입니다.
clear all
file_name = 'test.wav';
[xx,fs]=audioread(file_name);
peak_hold_time = 1.0*10^-3;
peak_max = peak_hold_time * fs;
peak_hold_cnt =0;
start_x = 35000;
gap = 10000;
end_x = start_x + (gap-1);
x = xx(start_x:end_x,1);
peak = abs(x(1,1));
for i = 1 : gap
tmp = abs(x(i,1));
if((tmp>=peak)||((peak_hold_cnt > peak_max)))
peak_hold_cnt=0;
else
peak_hold_cnt++;
endif
if(peak_hold_cnt ==0)
peak = tmp;
endif
y(i,1) = peak;
endfor
clf
plot(x,'g');
hold on
plot(y,'r');
ylim([-0.5 0.5]);
grid on;
아래 그림은 peak_hold_time=1ms에 대해 검출한 피크 포락선입니다. 피크가 검출되고 짧은 시간 동안 붉은색으로 피크를 유지하고 있습니다.
아래 그림은 peak_hold_time=10ms에 대해 검출한 피크 포락선입니다. 세세한 피크 상태를 모두 반영하지 않으면서 신호의 크기 변화도 잘 반영하면서 피크를 유지하고 있습니다.
아래 그림은 peak_hold_time=100ms에 대해 검출한 피크 포락선입니다. 과도한 피크 유지 시간으로 신호 크기 변화는 잘 반영되지 않고 있습니다.
앞서 설명한 것과 같이 피크 포락선 검출은 다이내믹 처리에서도 많이 사용되고, 레벨 미터의 피크 검출 정보를 제공할 때도 사용됩니다. 이 방식은 매우 간결한 내용으로 신호처리 과정에서 연산량도 작아서 실용성도 높습니다. 사실 위의 코드도 좀더 효과적으로 구동되도록 더 최적화가능합니다만, 좀 읽기 편하게 내용을 풀어서 작성했습니다.
광고좀 꾹 눌러주시면 고맙겠습니다.
위의 내용을 참조용으로만 사용해주세요. 무단 도용이나 무단 복제는 불허합니다.
기타 문의 사항은 gigasound@naver.com에 남겨 주시면 고맙겠습니다.
'Audio Processing' 카테고리의 다른 글
다이내믹 신호처리(5)-실효치 컴프레서, 리미터 (0) | 2021.10.21 |
---|---|
다이내믹 신호처리(4)-어택과 릴리즈를 고려한 포락선 검출 (0) | 2021.10.21 |
다이내믹 신호처리(2)- 오디오 신호변화 특성과 포락선 (0) | 2021.10.21 |
다이내믹 신호처리(1)-개요 (0) | 2021.10.21 |
Python의 FFT, 평균화(averaging), 평활화(Smooth) (1) | 2021.09.28 |