2014-03-05 4 views
0

의 단일 악기의 화음을 찾을 내가내가 단일 악기의 화음을 찾기 위해 노력하고 어떻게 안드로이드

private AnalyzedSound getFrequency() { 

    //audioData has the audio array of recored. 
    elementsRead = 
     audioData.getElements(audioDataAnalyzis,0,audioDataSize); 

    double loudness = 0.0; 
    for(int i=0; i<elementsRead; ++i) 
     loudness+=Math.abs(audioDataAnalyzis[i]); 

    //loudness of the data is divided by the elementsRead 
    loudness/=elementsRead; 
    // Check loudness first - it's root of all evil. loudnessThreshold = 30.0 
    if(loudness<loudnessThreshold) 
     return new AnalyzedSound(loudness,ReadingType.TOO_QUIET); 

    //FFT computation analyzed data is in audioDataAnalyzis 
    computeAutocorrelation(); 

    //chopOffEdges(0.2); 

    double maximum=0; 
    for(int i=1; i<elementsRead; ++i) 
     maximum = Math.max(audioDataAnalyzis[i], maximum); 

    int lastStart = -1; 
    wavelengths = 0; 
    boolean passedZero = true; 
    for(int i=0; i<elementsRead; ++i) { 
     if(audioDataAnalyzis[i]*audioDataAnalyzis[i+1] <=0) passedZero = true; 
     if(passedZero && audioDataAnalyzis[i] > MPM*maximum && 
       audioDataAnalyzis[i] > audioDataAnalyzis[i+1]) { 
      if(lastStart != -1) 
       wavelength[wavelengths++]=i-lastStart; 
      lastStart=i; passedZero = false; 
      maximum = audioDataAnalyzis[i]; 
     } 
    } 
    if(wavelengths <2) 
     return new AnalyzedSound(loudness,ReadingType.ZERO_SAMPLES); 

    removeFalseSamples(); 

    double mean = getMeanWavelength(), stdv=getStDevOnWavelength(); 

    double calculatedFrequency = (double)AUDIO_SAMPLING_RATE/mean; 

    //Log.d(TAG, "MEAN: " + mean + " STDV: " + stdv);  
    //Log.d(TAG, "Frequency:" + calculatedFrequency); 

    if(stdv >= maxStDevOfMeanFrequency) 
     return new AnalyzedSound(loudness,ReadingType.BIG_VARIANCE); 
    else if(calculatedFrequency>MaxPossibleFrequency) 
     return new AnalyzedSound(loudness,ReadingType.BIG_FREQUENCY); 
    else 
     return new AnalyzedSound(loudness, calculatedFrequency); 

} 

하지만 평균 값을 찾을 수 없습니다입니다 찾을 수있는 방법을했다. 이 코드는 실시간 녹음에 ​​문제가 없지만 저장된 wav 파일을 분석하고 싶습니다. 나는 평균값을 정확하게 얻을 수 없다. 어떻게 오디오 데이터를 분할하여 입력 할 수 있습니까?

답변

2

달성하려는 것으로 보이는 부분은 다성 음악 피치 감지입니다. 근사한 과정이기 때문에 일반적으로 어렵고 일하기가 어렵습니다.

근본적인 문제는 실제 악기 사운드에 고조파가 중첩되어 있다는 것입니다. 근본적인 수준에서, 화음의 구성 음표의 고조파가 정렬되기 때문에 조화가 작동합니다. 이것들은 화음의 음표 중 하나의 기본이 아닌 주파수에서 스펙트럼 피크를 초래할 수 있습니다.

당신이 다루어야 할 추가 문제는 스펙트럼 피크가 근본적인 것이 아닌 악기입니다. 즉, 스펙트럼이 잡음과 비슷해 보이는 시작 부분에서 퍼커션 사운드입니다.

아마도 노트의 중첩을 제거하기 위해 통계적 접근이 필요하며, 아마도 해당 악기의 스펙트럼 특성에 대한 사전 지식이 필요할 수 있습니다.

/FFT computation analyzed data is in audioDataAnalyzis 
computeAutocorrelation(); 

이 의견으로 약간 혼란 스러웠습니다. 자기 상관은 FFT가 아닙니다. 일반적으로, 자기 상관은 실제 오디오 신호에서 주파수를 탐지하는 알고리즘의 부적절한 선택으로 간주됩니다.
대위법 피치 탐지의 경우 FFT 접근법을 사용하는 것이 더 좋을 수 있습니다. 그러나 이것은 특히 간단하지 않습니다.

마지막으로,이 문제 공간에 대한 연구가 많습니다. 보통 오디오 파일 추출의 컨텍스트에서 이루어집니다. Sonic Visualiser - 오픈 소스 피치 분석 플러그인이있는 것이 좋습니다.

관련 문제