문제

파이썬에서 그래픽 스펙트럼 분석기를 만들려고합니다.

현재 16 비트 듀얼 채널 44,100 Hz 샘플 속도 오디오 스트림의 1024 바이트를 읽고 2 채널의 진폭을 평균화하고 있습니다. 이제 256 개의 서명 반바지가 있습니다. 이제 Numpy와 같은 모듈을 사용하여 해당 배열에서 FFT를 사전 형성하고 결과를 사용하여 그래픽 스펙트럼 분석기를 작성하여 시작하여 시작하기 위해서는 32 개의 막대가됩니다.

나는 빠른 푸리에 변환 및 이산 푸리에 변환에 대한 위키 백과 기사를 읽었지만 결과 배열이 무엇을 나타내는 지 여전히 확실하지 않습니다. 이것은 Numpy를 사용하여 배열에서 FFT를 미리 형성 한 후 배열의 모습입니다.

   [ -3.37260500e+05 +0.00000000e+00j   7.11787022e+05 +1.70667403e+04j
   4.10040193e+05 +3.28653370e+05j   9.90933073e+04 +1.60555003e+05j
   2.28787050e+05 +3.24141951e+05j   2.09781047e+04 +2.31063376e+05j
  -2.15941453e+05 +1.63773851e+05j  -7.07833051e+04 +1.52467334e+05j
  -1.37440802e+05 +6.28107674e+04j  -7.07536614e+03 +5.55634993e+03j
  -4.31009964e+04 -1.74891657e+05j   1.39384348e+05 +1.95956947e+04j
   1.73613033e+05 +1.16883207e+05j   1.15610357e+05 -2.62619884e+04j
  -2.05469722e+05 +1.71343186e+05j  -1.56779748e+04 +1.51258101e+05j
  -2.08639913e+05 +6.07372799e+04j  -2.90623668e+05 -2.79550838e+05j
  -1.68112214e+05 +4.47877871e+04j  -1.21289916e+03 +1.18397979e+05j
  -1.55779104e+05 +5.06852464e+04j   1.95309737e+05 +1.93876325e+04j
  -2.80400414e+05 +6.90079265e+04j   1.25892113e+04 -1.39293422e+05j
   3.10709174e+04 -1.35248953e+05j   1.31003438e+05 +1.90799303e+05j...

이 숫자가 정확히 무엇을 나타내고 어떻게이 숫자가 32 개의 막대 각각에 대해 높이의 비율로 변환 할 것인지 궁금합니다. 또한 2 개의 채널을 함께 평균해야합니까?

도움이 되었습니까?

해결책

당신이 보여주는 배열은 오디오 신호의 푸리에 변환 계수입니다. 이러한 계수는 오디오의 주파수 내용을 얻는 데 사용될 수 있습니다. FFT는 복잡한 값의 입력 함수에 대해 정의되므로 입력이 모두 실제 값이더라도 꺼내는 계수는 상상의 숫자가됩니다. 각 주파수에서 전력량을 얻으려면 각 주파수에 대한 FFT 계수의 크기를 계산해야합니다. 이것은 ~ 아니다 계수의 실제 구성 요소 만 있으면 실제 및 가상 구성 요소의 제곱 합의 제곱근을 계산해야합니다. 즉, 계수가 a + b*j 인 경우 그 크기는 sqrt (a^2 + b^2)입니다.

각 FFT 계수의 크기를 계산하면 각 FFT 계수가 속한 오디오 주파수를 파악해야합니다. N Point FFT는 0에서 시작하여 균등 한 간격 주파수에서 신호의 주파수 함량을 제공합니다. 샘플링 주파수는 44100 샘플 / 초이기 때문입니다. FFT의 점수는 256이고 주파수 간격은 44100 / 256 = 172Hz (대략)입니다.

배열의 첫 번째 계수는 0 주파수 계수입니다. 이는 기본적으로 모든 주파수의 평균 전력 수준입니다. 나머지 계수는 128에 도달 할 때까지 0에서 172Hz의 배수로 0에서 카운트됩니다. FFT에서는 샘플 포인트의 절반까지 주파수를 측정 할 수 있습니다. 이 링크를 읽으십시오 NYQUIST 주파수 그리고 Nyquist-Shannon 샘플링 정리 당신이 처벌에 대한 글루튼이고 이유를 알아야한다면, 기본 결과는 낮은 주파수가 복제되거나 별명 더 높은 주파수 버킷에서. 따라서 주파수는 0에서 시작하여 각 계수에 대해 N/2 계수까지 172Hz 증가한 다음 N -1 계수까지 172Hz 감소합니다.

그것은 당신을 시작하기에 충분한 정보가되어야합니다. Wikipedia에 제공되는 것보다 FFT에 대한 훨씬 더 접근 가능한 소개를 원한다면 시도해 볼 수 있습니다. 디지털 신호 처리 이해 : 2nd ed.. 그것은 나에게 매우 도움이되었습니다.

그것이 바로 그 숫자가 나타내는 것입니다. 각 주파수 성분 크기를 모든 구성 요소 크기의 합으로 스케일링하여 높이의 백분율로 변환 할 수 있습니다. 그러나 그것은 당신에게 상대 주파수 분포를 표현할뿐만 아니라 각 주파수에 대한 실제 전력은 아닙니다. 주파수 구성 요소의 경우 가능한 최대 크기로 스케일링을 시도 할 수 있지만, 그것이 잘 표시되는지 확실하지 않습니다. 실행 가능한 스케일링 계수를 찾는 가장 빠른 방법은 시끄럽고 부드러운 오디오 신호를 실험하여 올바른 설정을 찾는 것입니다.

마지막으로 전체 오디오 신호의 주파수 내용을 전체적으로 표시하려면 두 채널을 함께 평균해야합니다. 스테레오 오디오를 모노 오디오에 혼합하고 결합 된 주파수를 보여줍니다. 오른쪽 및 왼쪽 주파수에 대해 두 개의 별도 디스플레이를 원한다면 각 채널에서 푸리에 변환을 개별적으로 수행해야합니다.

다른 팁

이 스레드는 오래되었지만 매우 도움이된다는 것을 알았습니다. 나는 단지 이것을 발견하고 비슷한 것을 만들려고하는 사람에게 내 의견을주고 싶었습니다.

막대로의 분할은 바의 수를 기준으로 데이터를 동일하게 나누어 Antti가 제안한대로 수행해서는 안됩니다. 가장 유용한 것은 데이터를 옥타브 부품으로 나누는 것입니다. 각 옥타브는 이전의 주파수의 두 배입니다. (예 : 100Hz는 50Hz 이상의 옥타브이며, 이는 25Hz 이상의 옥타브입니다).

원하는 막대 수에 따라 전체 범위를 1/x 옥타브 범위로 나눕니다. 막대에서 주어진 중심 주파수를 기준으로, 막대의 상한 및 하한을 얻을 수 있습니다.

upper limit = A * 2 ^ ( 1 / 2X )
lower limit = A / 2 ^ ( 1 / 2X )

다음 인접한 중심 주파수를 계산하려면 유사한 계산을 사용합니다.

next lower =  A / 2 ^ ( 1 / X )
next higher = A * 2 ^ ( 1 / X )

그런 다음 각 막대의 진폭을 얻기 위해 이러한 범위에 맞는 데이터를 평균화합니다.

예를 들어 : 우리는 1/3 옥타브 범위로 나누고 싶고 1kHz의 중심 주파수로 시작합니다.

Upper limit = 1000 * 2 ^ ( 1 / ( 2 * 3 ) ) = 1122.5
Lower limit = 1000 / 2 ^ ( 1 / ( 2 * 3 ) ) =  890.9

44100Hz 및 1024 샘플 (각 데이터 포인트 사이의 43Hz)이 주어진 값은 평균 21-26 값을 내야합니다. (890.9 / 43 = 20.72 ~ 21 및 1122.5 / 43 = 26.10 ~ 26)

(1/3 옥타브 바는 ~ 40Hz에서 ~ 20kHz 사이에서 약 30 개의 바를 얻을 수 있습니다). 당신이 지금까지 알아낼 수 있듯이, 우리는 더 높이 갈수록 평균 범위의 숫자를 평균화 할 것입니다. 낮은 막대에는 일반적으로 1 개 또는 적은 수의 데이터 포인트 만 포함됩니다. 더 높은 막대는 평균 수백 포인트가 될 수 있습니다. 86Hz가 43Hz 이상의 옥타브이기 때문입니다. 10086Hz는 10043Hz와 거의 동일하게 들립니다.

당신이 가진 것은 시간의 길이가 256/44100 = 0.00580499 초인 샘플입니다. 이는 주파수 분해능이 1 / 0.00580499 = 172Hz임을 의미합니다. 파이썬에서 나오는 256 값은 기본적으로 86Hz ~ 255*172+86 Hz = 43946 Hz의 주파수에 해당합니다. 나가는 숫자는 복소수입니다 (따라서 매번 "j"는 매번 숫자가 끝날 때마다 "J").

편집 : 잘못된 정보를 수정했습니다

sqrt를 계산하여 복소수를 진폭으로 변환해야합니다 (i2 + j2) 여기서 I와 J는 실제적이고 상상의 부분입니다.

32 개의 막대를 갖고 싶다면 평균 4 개의 연속 진폭을 가져 와서 원하는대로 256 / 4 = 32 개의 막대를 얻습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top