2011-07-03 16 views
5

मैं हाल ही में एक हरा पता लगाने कोड लागू करने की कोशिश की यहां पाया, अर्थात् व्युत्पत्ति और Combfilter एल्गोरिथ्म # 1 :: http://archive.gamedev.net/reference/programming/features/beatdetection/page2.aspइस बीट-डिटेक्शन एल्गोरिदम को लागू करने में सहायता करें?

इम भी यकीन नहीं अगर मैं इसे सफलतापूर्वक लागू के रूप में मैं अच्छे परिणाम नहीं मिल रहा है। मैं सोच रहा था कि अगर किसी ने इसे सफलतापूर्वक या केवल उन अच्छे लोगों के लिए लागू किया है जो सामान्य रूप से मदद करना चाहते हैं। यहाँ मेरी दिया गया है:

//Cycle through Tempo's (60 to 200) incrementing each time by 10 
for (int i = (int)mintempo; i <= maxtempo; i += 10) 
{ 
    //Clear variables to be used 
    curtempo = i; 
    fftPulse.Clear(); 
    offset = 0; 
    energy = 0; 
    short[] prevBuffer = null; 

    //Calculate ti 
    ti = (60/curtempo) * 44100; 
    ti = Math.Round(ti, 0); 

    //Generate pulse train 
    for (int j = 0; j < pulseTrain.Length; j++) 
    { 
     if ((j % ti) == 0) 
      pulseTrain[j] = short.MaxValue; 
     else 
      pulseTrain[j] = 0; 
    } 

    //Compute FFT of the pulseTrain array 
    while (offset < pulseTrain.Length) 
    { 
     //Generate block samples (1024 is my blocksize) 
     short[] fftPulseBuffer = new short[po.blocksize/2]; 

     //Store samples from pulseTrain in a 1024 block buffer for passing to the FFT algorithm 
     index = 0; 
     for (int j = offset; j < (offset + (po.blocksize/2)) && j < pulseTrain.Length; j++) 
     { 
      fftPulseBuffer[index] = pulseTrain[j]; 
      index++; 
     } 

     //Initialize prevBuffer, which contains samples from the previous block, used in conjunction with the current block for the FFT 
     if (prevBuffer == null) 
      prevBuffer = new short[po.blocksize/2]; 

     //Calculate the FFT using the current and previous blocks 
     fftPulse.Add(CalculateFFT(fftPulseBuffer,prevBuffer)); 

     //Set prevBuffer and increment to next block start position 
     prevBuffer = fftPulseBuffer; 
     offset += (po.blocksize/2); 
    } 

//Calculate energy 
    for (int j = 0; j < intendomainarr.Count; j++) 
    { 
     double[] signalarr = intendomainarr[j]; 
     double[] pulsearr = fftPulse[j]; 
     for (int x = 0; x < signalarr.Length; x++) 
     { 
      energy += Math.Abs(signalarr[x] * pulsearr[x]); 
     } 
    } 

    //Get current best tempo match 
    if (energy > maxenergy) 
    { 
     chosentempo = curtempo; 
     maxenergy = energy; 
    } 
} 

परिणाम है कि मैं हो रही है हमेशा बहुत अधिक है, आमतौर पर लगभग 190 और 200BPM, जो नहीं मामला होना चाहिए, के रूप में मेरे .wav फ़ाइलें केवल 60-120BPM के बीच टेम्पो की है।

ध्यान दें कि मैं एक .WAV फ़ाइल (44.1Khz, 16-bit, मोनो) का उपयोग कर रहा हूं, ताकि कुछ सूत्र केवल एक चैनल के साथ काम करने के लिए थोड़ा संशोधित (यानी ऊर्जा की गणना कर रहे हों)। मैं पुष्टि करना चाहता हूं कि मेरे कार्यान्वयन में कोई विसंगति है या नहीं? मैं एफएफटी भाग के बारे में चिंता नहीं कर रहा हूं क्योंकि मैं इसके लिए पुस्तकालय का उपयोग कर रहा हूं।

बहुत बहुत धन्यवाद!

उत्तर

3

ऊर्जा बनाम आवृत्ति का एक साजिश बनाएं।

मुझे लगता है कि आप पाएंगे कि हार्मोनिक्स में बेस सिग्नल के लिए लगभग समान ऊर्जा है, और यदि वास्तविक आवृत्ति आवृत्ति डिब्बे के बीच आधे रास्ते में आती है, तो दूसरा हार्मोनिक शिखर नमूना होता है और आसानी से दो नमूने को दोनों तरफ धड़कता है असली आवृत्ति।

आपको इस प्रभाव को दूर करने के लिए थोड़ा आवृत्तियों को दंडित करने की आवश्यकता होगी।


कृपया ध्यान दें, जबकि सी # वास्तविक समय में या थोक बैच प्रोसेसिंग के लिए इस तरह के एक एल्गोरिथ्म के कार्यान्वयन के लिए एक अनुचित पसंद नहीं है, यह एल्गोरिथ्म विकास और फेरबदल के लिए भयानक है। मैं एल्गोरिदम सही पाने के लिए मैटलैब (या फ्री क्लोन, ऑक्टेव) का उपयोग करने की अनुशंसा करता हूं, और केवल कुछ परीक्षण मामलों पर काम करने के बाद, कोड को C# (या C++) में परिवर्तित करें।

0

मैं इस तलाश है, तो काफी यकीन नहीं है लेकिन इस ब्लॉक में टिप्पणी कोड फिट नहीं है: पहली टिप्पणी की वजह से कोड fftPulseBuffer को आकार 512 है मुताबिक

//Generate block samples (1024 is my blocksize) 
    short[] fftPulseBuffer = new short[po.blocksize/2]; 

    //Store samples from pulseTrain in a 1024 block buffer for passing to the FFT algorithm 
    index = 0; 
    for (int j = offset; j < (offset + (po.blocksize/2)) && j < pulseTrain.Length; j++) 
    { 
     fftPulseBuffer[index] = pulseTrain[j]; 
     index++; 
    } 

, और उसके बाद जो 1024 का कहना है

+0

ओह, हाँ क्षमा करें कि टिप्पणी में केवल त्रुटि थी। आकार वास्तव में 512 है। लेकिन मैं उस भाग पर प्रयोग करने की कोशिश करूंगा। – dspboy

संबंधित मुद्दे