2017-12-03 29 views
3

나는 사운드 파일 (.m4a)을 분석하여 시간 경과에 따른 진폭을 얻고 그래프를 작성하려고합니다. 나는 훌륭한 코드 (아래)를 온라인에서 발견했다. 그러나, 나는 또한 목표 주파수 범위에없는 모든 소리를 걸러 내고 싶습니다. 예 : 나는 1900-2100 Hz 사이의 소리만을 그래프로 나타내기를 원합니다. 어떻게해야합니까?.m4a 데이터의 주파수 필터링

var processingBuffer = [Float](repeating: 0.0, count: Int(readFile.arrayFloatValues.count)) 
    let sampleCount = vDSP_Length(readFile.arrayFloatValues.count) 

    vDSP_vabs(readFile.arrayFloatValues, 1, &processingBuffer, 1, sampleCount); 

    let samplesPerPixel = 1 
    let filter = [Float](repeating: 1.0/Float(samplesPerPixel), count: Int(samplesPerPixel)) 
    let downSampledLength = Int(readFile.arrayFloatValues.count/samplesPerPixel) 
    var downSampledData = [Float](repeating:0.0, count:downSampledLength) 

    vDSP_desamp(processingBuffer, 
       vDSP_Stride(samplesPerPixel), 
       filter, &downSampledData, 
       vDSP_Length(downSampledLength), 
       vDSP_Length(samplesPerPixel)) 

    readFile.points = downSampledData.map{CGFloat($0)} 

편집은

기록 실제로 이전 시점의 기기의 마이크에서 기록된다. 녹음 단계에서 필터를 적용하는 것이 더 쉬운가요?

+0

주파수 도메인에있는 진폭/시간 데이터를 변환하고 편집 한 다음 다시 시간 도메인으로 변환합니다. FFT가 작동합니다. – meggar

+0

그 방법에 대한 힌트가 있습니까? 저는 Accelerate 프레임 워크를 사용하고있는 것처럼 보입니다. 아마도 도움이 될 것입니다. https://developer.apple.com/library/content/documentation/Performance/Conceptual/vDSP_Programming_Guide/Introduction/Introduction (영문) –

+0

.html – meggar

답변

2

가능한 방법은 샘플링 된 파일에 이산 푸리에 변환을 적용하는 것입니다. 푸리에 변환은 오디오 데이터를 시간 영역에서 주파수 영역으로 전송합니다. 주파수 도메인에 해당 데이터가 있으면 원하지 않는 빈도를 "잘라내어"축소 된 데이터로 역 푸리에 변환을 수행하여 다시 시간 도메인에서 사용할 수 있습니다. 코드. https://github.com/christopherhelf/Swift-FFT-Example을 살펴보면, 신속하고 빠른 푸리에 변환 (FFT)을 처리하는 방법을 예제 코드로 제공합니다. 희망 사항은 당신에게 방향을 제시합니다.

+0

이것은 실제로 끔찍한 접근법입니다. i) 시간 영역의 FIR 또는 IIR 필터가 FFT와 IFFT보다 훨씬 저렴합니다. ii) 끔찍한 소리입니다 (https://en.wikipedia.org/wiki/ 참조). Gibbs_phenomenon) 그리고 iii) 통과 대역이 원하는 것보다 훨씬 넓어지기 때문에 (실제로 메모리가 작동하면 6dB/octave이기 때문에) 정말 엉성한 필터를 만듭니다. iv) BTW - 모든 손실 코덱은 주파수 영역에서 작동하여 시작합니다. 왜베이스 밴드로 변환 한 다음 FFT를 다시 계산합니까? 정상적인 접근 방식은 IIR 대역 통과 필터입니다. – marko