문제

느린 CPU, 코드 크기 및 RAM과 같은 제한된 리소스를 사용하면 전자 또는 소프트웨어 튜너가 수행하는 것과 비슷한 악보의 피치를 가장 잘 감지하는 방법은 무엇입니까?

내가 사용해야하나요 :

  • 키스 FFT
  • fftw
  • 이산 웨이블릿 변환
  • 자기 상관
  • 제로 교차 분석
  • 옥타브 간격 필터

다른?

간단히 말해서, 내가하려고하는 것은 위의 중간 C에서 2 옥타브 아래 2 개의 옥타브가 (합리적인) 악기에서 연주되는 단일 악기를 인식하는 것입니다. 다시 말해서, 사용자가 너무 평평하거나 너무 날카 로워지면 그것을 구별해야합니다. 그러나 튜닝에 필요한 정확도가 필요하지 않습니다.

도움이 되었습니까?

해결책

그다지 정확도가 필요하지 않으면 FFT만으로도 충분할 수 있습니다. 창문 오디오 덩어리를 먼저, 정의 된 피크를 얻을 수 있도록 첫 번째 중요한 피크를 찾으십시오.

빈 너비 = 샘플링 속도 / FFT 크기 :

기본 범위 20Hz ~ 7kHz이므로 14kHz의 샘플링 속도로 충분합니다. 다음 "표준"샘플링 속도는 22050Hz입니다.

그런 다음 FFT 크기는 원하는 정밀도에 의해 결정됩니다. FFT 출력은 주파수가 선형이며 음악 톤은 주파수의 로그이므로 최악의 사례 정밀도는 저주파수입니다. 20Hz에서 세미 톤의 20%의 경우 너비가 필요합니다. 1.2 Hz, 이는 FFT 길이를 의미합니다 18545. 두 가지 힘은 2입니다15 = 32768. 이것은 1.5 초의 데이터이며, 랩톱의 프로세서를 3ms에 가져가 계산합니다.

이것은 ""신호와 함께 작동하지 않습니다.기본이 누락되었습니다"그리고"첫 번째 중요한 "피크를 찾는 것은 다소 어렵습니다 (이후 고조파는 종종 기본보다 높습니다), 그러나 당신은 당신의 상황에 맞는 방법을 알아낼 수 있습니다.

자기 상관 및 고조파 제품 스펙트럼 고조파 중 하나 대신 파도의 진정한 기본을 찾는 것이 더 낫지 만 억제, 피아노 나 기타와 같은 대부분의 악기는 불완전합니다 (고조파는 자신이해야 할 것보다 약간 선명합니다). 그러나 그것은 당신의 상황에 달려 있습니다.

또한 관심있는 특정 주파수 대역 내에서만 컴퓨팅하여 더 많은 프로세서 사이클을 절약 할 수 있습니다. Chirp-Z 변환.

나는 썼다 파이썬에서 몇 가지 다른 방법 비교 목적.

다른 팁

실시간으로 (그리고 반음의 1/100 이내에 정확한) 피치 인식을 원한다면, 유일한 희망은 제로 교차 접근법입니다. 그리고 그것은 희미한 희망입니다. 죄송합니다. 제로 교차는 몇 파일의 데이터에서 피치를 추정 할 수 있으며 스마트 폰의 처리 능력으로 수행 할 수 있지만 파장을 측정하는 데 작은 오류가 예상 빈도에서 큰 오류를 초래하기 때문에 특히 정확하지 않습니다. 기타 신디사이저와 같은 장치 (단지 몇 파장으로 기타 문자열의 피치를 추론)는 측정 값을 스케일의 메모로 정량화하여 작동합니다. 이것은 귀하의 목적에 효과가있을 수 있지만, 제로 크로싱은 간단한 파형으로 훌륭하게 작동하지만 더 복잡한 악기 사운드와는 잘 어울리는 경향이 있습니다.

내 응용 프로그램 (스마트 폰에서 실행되는 소프트웨어 신시사이저)에서는 단일 계기 노트를 웨이브 가능한 합성을위한 원료로 사용하고 특정 피치에서 메모를 생성하려면 녹음의 기본 피치를 알아야합니다. 반음의 1/1000 이내에 (실제로 1/100 정확도 만 필요하지만 이에 대해 OCD). 제로 교차 접근법은 다음과 같습니다 많이 이것에 대해 너무 부정확하고 FFT 기반 접근법은 너무 부정확하거나 너무 느리게 (또는 때로는 둘 다)입니다.

이 경우 내가 찾은 가장 좋은 방법은 자기 상관을 사용하는 것입니다. 자기 상관을 사용하면 기본적으로 피치를 추측 한 다음 해당 파장에서 샘플의 자기 상관을 측정합니다. 반 톤에 의해 그럴듯한 피치의 범위 (예 : A = 880Hz)를 통해 스캔함으로써 가장 상관 된 피치를 찾은 다음 해당 피치 인근에서 더 세밀한 스캔을 수행하여 더 정확한 가치.

당신에게 가장 적합한 접근 방식은 전적으로 당신이 이것을 사용하려는 것에 달려 있습니다.

나는 당신이 언급 한 모든 방법에 익숙하지 않지만 당신이 선택한 것은 주로 입력 데이터의 특성에 따라야합니다. 순수한 톤을 분석하고 있습니까, 아니면 입력 소스에 여러 음표가 있습니까? 음성은 입력의 특징입니까? 입력을 샘플링 해야하는 시간에 제한이 있습니까? 속도에 대한 정확성을 트레이드 할 수 있습니까?

어느 정도까지 선택한 것은 계산을 수행할지 여부에 따라 다릅니다. 시각 또는에서 주파수 공간. 변환 a 시계열 주파수 표현에는 시간이 걸리지 만 내 경험상 더 나은 결과를 제공하는 경향이 있습니다.

자기 상관 시간 영역에서 두 가지 신호를 비교합니다. 순진한 구현은 원래와 시간 이동 신호의 모든 지점간에 쌍별 차이가 필요하기 때문에 순진한 구현은 계산에 상대적으로 비싸다. 다음에 차별화 된 다음 자기 상관 함수의 전환점을 식별 한 다음 해당 최소의 선택을 선택합니다. 기본 주파수. 대체 방법이 있습니다. 예를 들어, 평균 크기 차이 매우 저렴한 형태의 자기 상관이지만 정확도는 어려움을 겪습니다. 모든 자기 상관 기술은 기능에 기본 이외의 피크가 존재하기 때문에 옥타브 오류의 위험을 실행합니다.

자질 제로 크로스 포인트 간단하고 간단하지만 신호에 여러 파형이있는 경우 문제가 발생합니다.

주파수 공간에서 기준 기술 FFT 목적을 위해 충분히 효율적일 수 있습니다. 한 가지 예는 신호의 전력 스펙트럼을 각 고조파에서 다운 샘플링 된 버전과 비교하고 스펙트럼을 곱하여 피치를 식별하여 투명한 피크를 생성함으로써 피치를 식별하는 고조파 제품 스펙트럼 기술입니다.

그 어느 때보 다 몇 가지 기술을 테스트하고 프로파일 링하는 대체물이 없으며, 문제와 제약에 가장 적합한 것이 무엇인지 경험적으로 결정합니다.

이와 같은 대답은이 주제의 표면 만 긁을 수 있습니다. 이전 링크뿐만 아니라 다음은 추가 읽기에 대한 관련 참조가 있습니다.

내 프로젝트에서 Danstuner, 나는 코드를 가져 왔습니다 대담. 그것은 본질적으로 FFT를 가져간 다음 FFT에 입방 곡선을 넣고 그 곡선의 피크를 찾아 피크 파워를 발견했습니다. 옥타브 점프를 막아야했지만 잘 작동합니다.

보다 Spectrum.cpp.

전형적인 사운드에는 기본 주파수보다 훨씬 더 고조파와 제로 교차가 있기 때문에 제로 교차로가 작동하지 않습니다.

내가 홈 사이드 프로젝트로서 실험 한 것은 다음과 같습니다.

  1. 필요한 샘플 속도로 ADC로 사운드를 샘플링하십시오.
  2. 파형의 단기 양성 및 음의 피크의 레벨을 감지합니다 (슬라이딩 윈도우 또는 이와 유사). 즉 봉투 검출기.
  3. 파형이 양의 봉투의 90% (또는 그대로) 이내에있을 때 높은 사각형 파를 만들고 파형이 네거티브 엔벨로프의 90% 이내에있을 때 낮아집니다. 즉, 히스테리시스가있는 추적 정사각형.
  4. 필요한 정확도를 얻는 데 필요한만큼 많은 샘플을 사용하여 간단한 카운트/시간 계산으로 사각형 파의 주파수를 측정하십시오.

그러나 전자 키보드의 입력으로 일부 악기 사운드의 경우 기본 주파수 (다음 옥타브)가 2x를 픽업 할 수 있음을 알았습니다. 이것은 부수적 인 프로젝트였으며 다른 것들로 넘어 가기 전에 솔루션을 구현 한 적이 없습니다. 그러나 나는 그것이 FFT보다 CPU 부하가 훨씬 적다는 약속이 있다고 생각했다.

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