2012-08-05 10 views
5

में एकाधिक स्थिर तरंगों को मिलाकर मैं एक कक्षा बना रहा हूं जो आवृत्तियों के मूल्यों (यानी 440 हर्ट्ज, 880 हर्ट्ज, 1760 हर्ट्ज) की एक सरणी लेता है और यह दिखाता है कि वे एक ऑडियोट्रैक में कैसे मिलेंगे। मैं एक ध्वनि प्रोग्रामर नहीं हूं, इसलिए मेरे लिए खुद को लिखना मुश्किल है, जहां मेरा मानना ​​है कि यह एक अनुभवी ध्वनि प्रोग्रामर के लिए अपेक्षाकृत आसान समस्या है। यहाँ खेलने विधि में नीचे दिए गए कोड में से कुछ है:एंड्रॉइड - एक ही ऑडियोट्रैक

public void play() { 
    // Get array of frequencies with their relative strengths 
    double[][] soundData = getData(); 

    // TODO 
    // Perform a calculation to fill an array with the mixed sound - then play it in an infinite loop 
    // Need an AudioTrack that will play calculated loop 
    // Track sample info 
    int numOfSamples = DURATION * SAMPLE_RATE; 
    double sample[] = new double[numOfSamples]; 
    byte sound[] = new byte[2 * numOfSamples]; 

    // fill out the array 
    for (int i = 0; i < numOfSamples; ++i) { 
      sample[i] = Math.sin(2 * Math.PI * i/(SAMPLE_RATE/440)); 
    } 

    int i = 0; 
    for (double dVal : sample) { 
     // scale to maximum amplitude 
     final short val = (short) ((dVal * 32767)); 
     // in 16 bit wav PCM, first byte is the low order byte 
     sound[i++] = (byte) (val & 0x00ff); 
     sound[i++] = (byte) ((val & 0xff00) >>> 8); 
    } 

    // Obtain a minimum buffer size 
    int minBuffer = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 

    if (minBuffer > 0) { 
     // Create an AudioTrack 
     AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       AudioFormat.ENCODING_PCM_16BIT, numOfSamples, AudioTrack.MODE_STATIC); 

     // Write audio data to track 
     track.write(sound, 0, sound.length); 

     // Begin playing track 
     track.play(); 
    } 

    // Once everything has successfully begun, indicate such. 
    isPlaying = true; 
} 

अभी, इस कोड को बस एक संगीत कार्यक्रम के एक (440Hz) निभाता है। यह जांचना था कि यह कोड काम करता है या नहीं। अब, मुझे आवृत्तियों को एक गुच्छा लेने, किसी प्रकार की गणना करने और नमूना डेटा लिखने की आवश्यकता है।

+0

कोड के लिए हैलो धन्यवाद लेकिन मैं जानना चाहता हूं कि गेटडाटा फ़ंक्शन क्या कर रहा है – Nitin

उत्तर

2

ठीक है, तो उत्तर एक सरल सारांश लूप बन गया। अब

// fill out the array 
    for (int i = 0; i < numOfSamples; ++i) { 
      double valueSum = 0; 

      for (int j = 0; j < soundData.length; j++) { 
       valueSum += Math.sin(2 * Math.PI * i/(SAMPLE_RATE/soundData[j][0])); 
      } 

      sample[i] = valueSum/soundData.length; 
    } 

, क्या करता है बस सभी संभव आवृत्तियों लेते हैं, उन्हें चर, valueSum में एक साथ जोड़ने के लिए, और फिर विभाजित है कि की लंबाई से है: यहाँ यह, बस इस पाश के लिए मूल एक के साथ की जगह है आवृत्ति सरणी, soundData, जो एक साधारण औसत है। यह आवृत्तियों की मनमाने ढंग से लंबी सरणी का एक अच्छा साइन लहर मिश्रण पैदा करता है।

मैंने प्रदर्शन का परीक्षण नहीं किया है, लेकिन मेरे पास यह थ्रेड में चल रहा है, अन्यथा यह यूआई को क्रैश कर सकता है। इसलिए, उम्मीद है कि इससे मदद मिलती है - मैं इसे उत्तर के रूप में चिह्नित कर रहा हूं।

2

यदि आप एकाधिक तरंगों को एक में मिश्रण करना चाहते हैं, तो आप कई तरीकों से क्लिपिंग को रोक सकते हैं।

नमूना मानना ​​[i] एक आवाज़ है जो सभी ध्वनियों का योग दर्शाती है।

मुश्किल कतरन:

if (sample[i]> 1.0f) 
{ 
    sample[i]= 1.0f; 
} 
if (sample[i]< -1.0f) 
{ 
    sample[i]= -1.0f; 
} 

हेडरूम (y = 1.1X - 0.2X^3 वक्र, के लिए न्यूनतम और अधिकतम टोपी 1.0f तहत slighty)

if (sample[i] <= -1.25f) 
{ 
    sample[i] = -0.987654f; 
} 
else if (sample[i] >= 1.25f) 
{ 
    sample[i] = 0.987654f; 
} 
else 
{ 
    sample[i] = 1.1f * sample[i] - 0.2f * sample[i] * sample[i] * sample[i]; 
} 

एक तीसरे बहुपद waveshapper (कम चिकनी) के लिए, ऊपर की अंतिम पंक्ति को प्रतिस्थापित करें:

sample[i]= 1.1f * sample[i]- 0.2f * sample[i] * sample[i] * sample[i]; 
संबंधित मुद्दे