2016-10-13 10 views
2

나는 신호 처리에 대한 지식이 거의 없으며 현재는 인간이 비명을지를 때 (예 : sound pressure level) 증가 할 때 이벤트를 트리거하는 Swift에서 기능을 구현하려고합니다.). 난 그냥 평균을 계산하여 음압 레벨의 대략적인 추정을 받고 시도 float 배열로를 켠 후AVAudioPCMBuffer에서 음압 레벨을 추출 할 때

let recordingFormat = inputNode.outputFormat(forBus: 0) 
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat){ 
(buffer : AVAudioPCMBuffer?, when : AVAudioTime) in 
    let arraySize = Int(buffer.frameLength) 
    let samples = Array(UnsafeBufferPointer(start: buffer.floatChannelData![0], count:arraySize)) 

    //do something with samples 
    let volume = 20 * log10(floatArray.reduce(0){ $0 + $1}/Float(arraySize)) 
    if(!volume.isNaN){ 
     print("this is the current volume: \(volume)") 
    } 
} 

:

이 같은 콜백와 함께 AVAudioEngine의 입력 노드을 활용하고 .

그러나 이것은 나에게 아이 패드 그냥 아주 방에 앉아있는 경우에도 많은 변동 값 제공 : 나는 마이크 근처에 박수 경우 실제로이 값에 상당한 증가가

this is the current volume: -123.971 
this is the current volume: -119.698 
this is the current volume: -147.053 
this is the current volume: -119.749 
this is the current volume: -118.815 
this is the current volume: -123.26 
this is the current volume: -118.953 
this is the current volume: -117.273 
this is the current volume: -116.869 
this is the current volume: -110.633 
this is the current volume: -130.988 
this is the current volume: -119.475 
this is the current volume: -116.422 
this is the current volume: -158.268 
this is the current volume: -118.933 

합니다.

if(!volume.isNaN){ 
    if(isInThePreparingPhase){ 
     print("this is the current volume: \(volume)") 
     volumeSum += volume 
     volumeCount += 1 
    }else if(isInTheEventTriggeringPhase){ 
     if(volume > meanVolume){ 
      //triggers an event 
     } 
     } 
} 

이 averageVolume입니다 : 이벤트 트리거링 단계에서의 차이의 상당한 증가가있는 경우

그래서 내가 먼저 준비 단계에서 이러한 볼륨의 평균을 계산하고 비교처럼 뭔가를 할 수 트리거 이벤트 단계로 준비 단계에서 전환하는 동안 계산 : meanVolume = volumeSum/Float(volumeCount)

.... 그러나

, 내가 외에 큰 소리로 음악을 재생할 경우 유의 한 증가를 할 수없는 것으로 나타납니다 마이크. 드문 경우이지만 환경에 볼륨이 크게 증가하지 않더라도 (사람의 귀에 들릴 수 있음) volumemeanVolume보다 큽니다.

그렇다면 AVAudioPCMBuffer에서 음압 레벨을 추출하는 올바른 방법은 무엇입니까?

는 위키 루트가 기준 음압 인 정사각형 음압 P0 의미 인 (P)이

math!

같은 식을 제공한다.

그러나 float 값이 AVAudioPCMBuffer.floatChannelData 인 것을 나타내지는 않습니다. The apple page에만 표시됩니다.

버퍼의 오디오 샘플을 부동 소수점 값으로 사용합니다.

어떻게 처리해야합니까?

+0

안녕하세요 아치,이 질문에 대한 답변을 알아 냈을까요? 당신이 제공 할 수있는 코드가 있습니까? – Logan

답변

1

첫 번째 단계는 소리의 envelope을 얻는 것입니다. 간단한 평균을 사용하여 엔벨로프를 계산할 수 있지만 정정 단계를 추가해야합니다 (보통 abs() 또는 square()를 사용하여 모든 샘플을 양수로 지정해야 함)

보다 일반적으로 간단한 iir- 필터가 사용됩니다. 공격 및 감쇠에 대한 다른 상수와 함께 평균화하면 lab입니다.이러한 상수는 샘플링 주파수에 의존한다는에는 상수를 계산하는 공식을 사용하여 참고 :

1 - exp(-timePerSample*2/smoothingTime) 

2 단계

는 포락선이 때 추가 필터를 부드럽게하고있다 2 개의 봉투를 비교하여베이스 레벨보다 큰 소리를 찾으십시오. 여기는 complete lab입니다.

오디오 "이벤트"감지는 매우 까다로울 수 있으며 예측하기가 어렵다는 점을 유의하십시오.

+0

실험실 데모에 감사드립니다! 슈퍼 도움이 : D 조 –