2016-03-24 7 views
16

का उपयोग कर मैं ऐसे छोटे अंतर है कि पाशन पटरियों के बीच प्रकट होता है के रूप में MediaPlayer के साथ कुछ अच्छी तरह से ज्ञात कीड़े, की वजह से एक सुविधा मैं Androids AudioTrack बजाय MediaPlayer, उपयोग करने के लिए अधिक संक्रमण के लिए चाहते हैं।प्ले पाशन ऑडियो audiotrack

मुझे AudioTrack का उपयोग करने की अनुशंसा की गई है लेकिन इसका उपयोग इसके कई उदाहरणों में नहीं मिला है। मैं इतना AudioTrack के बारे में एक प्रश्न मिला और उस कोड के कुछ प्रयोग किया जाता है कुछ एक साथ हैक करने:

public class TestActivity extends Activity implements Runnable { 

    Button playButton; 
    byte[] byteData = null; 
    int bufSize; 
    AudioTrack myAT = null; 
    Thread playThread = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_test); 

     playButton = (Button) findViewById(R.id.testButton); 

     InputStream inputStream = getResources().openRawResource(R.raw.whitenoise_wav); 
     try { 
      byteData = new byte[ inputStream.available()]; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     try { 
      inputStream.read(byteData); 
      inputStream.close(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     initialize(); 

     playButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 

       playThread.start(); 
      } 
     }); 
    } 

    void initialize() { 

     bufSize = android.media.AudioTrack.getMinBufferSize(44100, 
       AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT); 

     myAT = new AudioTrack(AudioManager.STREAM_MUSIC, 
       44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT, bufSize, 
       AudioTrack.MODE_STREAM); 
     myAT.setVolume(.2f); 

     playThread = new Thread(this); 
    } 

    public void run() { 
     if (myAT != null) { 
      myAT.play(); 
      myAT.setLoopPoints(0, byteData.length, 6); 
      myAT.write(byteData, 0, byteData.length); 
     } 
    } 
} 

तो इस पूरे ऑडियो ट्रैक खेलने के लिए प्रतीत होता है (~ 1: 00 मिनट) और उसके बाद बंद हो जाता है। अब यहां अंतिम लक्ष्य दो में दो अलग-अलग ऑडियो ट्रैक चल रहे हैं और एक ही समय में लूपिंग कर रहे हैं। मेरे पास वर्तमान में /res/raw/ निर्देशिका में ऑडियो ट्रैक हैं, लेकिन यदि यह बेहतर होगा तो मैं उन्हें एक साधारण assets फ़ोल्डर में ले जा सकता हूं। क्या मेरा वर्तमान कार्यान्वयन AudioTrack सही है? यदि हां, तो मैं इसे लूप कैसे प्राप्त करूं?

संक्षेप में: AudioTrack का उपयोग करके आप अंतराल के बिना लूपिंग ऑडियो कैसे खेल सकते हैं?

तीसरे पक्ष के पुस्तकालयों जैसे लूपिंग ऑडियो प्राप्त करने के वैकल्पिक तरीकों के सुझावों का स्वागत है।

+0

क्या आप एक ही समय में दोनों ट्रैक खेलना चाहते हैं और यह भी लूप कि एक बार ऑडियो समाप्त हो जाए? –

+0

यह सही है। – Orbit

+0

इसे जांचें: http://developer.android.com/reference/android/media/SoundPool।एचटीएमएल –

उत्तर

5

आप AudioTrack.MODE_STREAM के साथ कॉन्फ़िगर किए गए ऑडियोट्रैक का उपयोग करके लूप नहीं कर सकते हैं। यदि आप MODE_STREAM का उपयोग करते हैं तो ऑडियोट्रैक को लगातार नए नमूने से भरने की आवश्यकता होती है।

लेकिन आप इसे AudioTrack.MODE_STATIC के साथ कॉन्फ़िगर कर सकते हैं और पूरे बफर को खेलने के लिए पास कर सकते हैं (मेरा मतलब है: यदि आपको दो नमूने मिश्रण करने की आवश्यकता है, तो आपको मिश्रित नमूने पास करना होगा)।

सेट लूप पॉइंट्स: लूप पॉइंट्स और लूप गिनती सेट करता है। लूप अनंत हो सकता है। इसी प्रकार सेट प्लेबैकहेडपोजिशन के लिए, लूप पॉइंट्स को बदलने के लिए ट्रैक को रोका या रोका जाना चाहिए, और MODE_STATIC मोड का उपयोग करना चाहिए।

कृपया ध्यान दें कि ऑडियोट्रैक कच्चे पीसीएम नमूने बजाता है, डब्ल्यूएवी, एमपी 3 या अन्य कंटेनर के लिए कोई समर्थन नहीं है।

+0

यदि फ़ाइल आपके कच्चे संसाधनों में संग्रहीत है, तो संसाधन प्राप्त करने और 'ऑडियोट्रैक' में फ़ीड करने पर आप 'इनपुटस्ट्रीम' वापस कर सकते हैं। लूपिंग करके, मेरा मतलब यह है कि इसे ठीक से लूप करने का कोई तरीका है, चाहे वह लगातार डेटा खिला रहा हो या इसे एक बार और ऑटो लूपिंग खिला रहा हो, तो इसमें कोई अंतर नहीं हो सकता है। – Orbit

+0

मैं समझता हूं कि आपकी कहानियां क्या है, मुझे पता है कि'setLoopingPoints() 'के साथ ऑटो लूपिंग केवल स्थिर मोड में ही किया जा सकता है। मैं या तो 'MODE_STATIC' और/या' MODE_STREAM' के साथ अंतराल लूपिंग का एक उदाहरण ढूंढ रहा था क्योंकि अधिकांश उदाहरण मैं वास्तव में काम नहीं कर रहा था। मैंने इसके साथ थोड़ा सा खेला और स्थिर मोड और '.setLoopingPoints' का उपयोग करके एक कार्यान्वयन कार्यान्वयन मिला, हालांकि कभी-कभी प्लेबैक के दौरान स्टडर्ड होता है। मैंने यह भी देखा कि यदि यह एक नए धागे में नहीं खेला जाता है, तो यह स्टार्टअप पर जोर से शुरू होने वाली ध्वनि उत्पन्न करेगा, और फिर चुप हो जाएगा। मुख्य धागे पर एक मुद्दा खेल रहा है? – Orbit

1

this उदाहरण पर देखें, यह एक समान समस्या प्रतीत होता है, लगातार AudioTrack खिला रहा है।

class ToneGenerator { 
    int sampleRate = 8000; 
    double sample[] = null; 
    byte generatedSnd[] = null; 
    int m_ifreq = 400; 
    Thread m_PlayThread = null; 
    boolean m_bStop = false; 
    AudioTrack m_audioTrack = null; 
    int m_play_length = 1000;//in seconds 

    static public void PlayTone(int freq, int play_length) { 
     ToneGenerator player = new ToneGenerator(); 
     player.m_ifreq = freq; 
     player.m_play_length = play_length; 
     player.play(); 
    } 

    synchronized void stop() { 
     m_bStop = true; 
     if (m_PlayThread != null) { 
      try { 
       m_PlayThread.interrupt(); 
       m_PlayThread.join(); 
       m_PlayThread = null; 
      } catch (Exception e) { 

      } 
     } 
     if (m_audioTrack != null) { 
      m_audioTrack.stop(); 
      m_audioTrack.release(); 
      m_audioTrack = null; 
     } 
    } 

    synchronized void play() { 
     m_bStop = false; 
     m_PlayThread = new Thread() { 
      public void run() { 
       try { 
        int iToneStep = 0; 

        m_audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
          sampleRate, AudioFormat.CHANNEL_OUT_MONO, 
          AudioFormat.ENCODING_PCM_16BIT, 2 * sampleRate, 
          AudioTrack.MODE_STREAM); 

        while (!m_bStop && m_play_length-- > 0) { 
         genTone(iToneStep++); 

         m_audioTrack.write(generatedSnd, 0, generatedSnd.length); 
         if (iToneStep == 1) { 
          m_audioTrack.play(); 
         } 
        } 
       } catch (Exception e) { 
        Log.e("Tone", e.toString()); 
       } catch (OutOfMemoryError e) { 
        Log.e("Tone", e.toString()); 
       } 

      } 
     }; 
     m_PlayThread.start(); 
    } 

    //Generate tone data for 1 seconds 
    synchronized void genTone(int iStep) { 
     sample = new double[sampleRate]; 

     for (int i = 0; i < sampleRate; ++i) { 
      sample[i] = Math.sin(2 * Math.PI * (i + iStep * sampleRate)/(sampleRate/m_ifreq)); 
     } 

     // convert to 16 bit pcm sound array 
     // assumes the sample buffer is normalised. 
     generatedSnd = new byte[2 * sampleRate]; 
     int idx = 0; 
     for (final 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 
      generatedSnd[idx++] = (byte) (val & 0x00ff); 
      generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8); 
     } 
    } 

} 
+0

क्यों 2 * sampleRate? – Coco

+0

16 बिट नमूनाकरण के कारण, तो आप 8 * 2 करते हैं – loretoparisi

0

आप स्ट्रीम की बाइट लंबाई में गुजर रहे हैं। setLoopPoints() स्ट्रीम में ऑडियो ब्लॉक की संख्या की अपेक्षा करता है। प्रलेखन में getBufferSizeInFrames() देखें।

हालांकि। मैं आपको सावधानी बरतता हूं कि सबसे विशेष ऑडियो प्रारूप ब्लॉक आधारित नहीं हैं; वे नमूना आधारित हैं। एमपी 3 एकमात्र अपवाद है; यह 1152 बाइट सीमाओं पर गठबंधन है। यदि स्रोत सामग्री एमपी 3 है और स्पष्ट रूप से गठबंधन ब्लॉक के लिए लिखा नहीं गया है, तो निर्बाध लूपिंग असंभव है। आप अपने ऑडियो स्रोत के रूप में "whitenoise.wav" का उपयोग कर रहे प्रतीत होते हैं। जब तक कि इस फ़ाइल की लंबाई ब्लॉक आकार के लिए स्पष्ट रूप से गठबंधन नहीं की जाती है, तब तक आपके पास लूपिंग होने पर ऑडियो कलाकृतियां हो सकती हैं।

इसके लिए कामकाज शुरुआत और अंतिम फ्रेम ब्लॉक को पार करने के लिए है, जब आप लूप करते हैं, और सभी बफरिंग को स्वयं संभालते हैं, लेकिन आपको इसे स्वयं करने के लिए कोड लिखना होगा।

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