मैं ओपनएसएल ईएस फाइलडिस्क्रिप्टर ऑब्जेक्ट का उपयोग करके एक ऑडियो एसेट से एक बाइट बफर प्राप्त करना चाहता हूं, इसलिए मैं फ़ाइल को चलाने/बंद/ढूंढने के लिए एसएल इंटरफेस का उपयोग करने के बजाय इसे सरलबफरक्यूयू में बार-बार एनक्यू्यू कर सकता हूं।क्या ओपनएसएल ईएस (एंड्रॉइड के लिए) में ऑडियो एसेट से सीधे बाइट बफर प्राप्त करना संभव है?
वहाँ तीन मुख्य कारणों क्यों मैं सीधे नमूना बाइट्स प्रबंधित करना चाहते हैं कर रहे हैं:
- OpenSL प्लेयर वस्तुओं के लिए/बंद/आदि खेलने के लिए एक audiotrack परत का उपयोग करता है। यह न केवल अवांछित ओवरहेड पेश करता है, बल्कि इसमें कई कीड़े भी हैं, और खिलाड़ी की तेज़ी से शुरू/बंद होने से कई समस्याएं होती हैं।
- मुझे सीधे कस्टम डीएसपी प्रभावों के लिए बाइट बफर में हेरफेर करने की आवश्यकता है।
- जिन क्लिप्सों को मैं खेलना चाहता हूं वे छोटे हैं, और फ़ाइल I/O ओवरहेड से बचने के लिए सभी को स्मृति में लोड किया जा सकता है। इसके अलावा, मेरे अपने बफर को एनक्यूइंग करने से मुझे आउटपुट सिंक में 0 लिखकर विलंबता कम हो जाएगी, और स्टॉपिंग, पोजिंग और ऑडियोट्रैक चलाने के बजाए, जब वे खेल रहे हों तो नमूना बाइट्स पर स्विच कर सकते हैं।
ठीक है, तो पूरा औचित्य - यहाँ है कि मैं क्या कोशिश की है - मैं एक नमूना struct जो होता है, अनिवार्य रूप से, एक इनपुट और आउटपुट ट्रैक, और एक बाइट सरणी नमूने धारण करने के लिए है। इनपुट मेरा फ़ाइलडिस्क्रिप्टर प्लेयर है, और आउटपुट एक SimpleBufferQueue ऑब्जेक्ट है। यहाँ मेरी struct है: एक फ़ाइल खिलाड़ी आरंभ fdPlayerObject के बाद
typedef struct Sample_ {
// buffer to hold all samples
short *buffer;
int totalSamples;
SLObjectItf fdPlayerObject;
// file descriptor player interfaces
SLPlayItf fdPlayerPlay;
SLSeekItf fdPlayerSeek;
SLMuteSoloItf fdPlayerMuteSolo;
SLVolumeItf fdPlayerVolume;
SLAndroidSimpleBufferQueueItf fdBufferQueue;
SLObjectItf outputPlayerObject;
SLPlayItf outputPlayerPlay;
// output buffer interfaces
SLAndroidSimpleBufferQueueItf outputBufferQueue;
} Sample;
, और malloc-इंग
sample->buffer = malloc(sizeof(short)*sample->totalSamples);
मैं
// get the buffer queue interface
result = (*(sample->fdPlayerObject))->GetInterface(sample->fdPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(sample->fdBufferQueue));
के साथ अपने BufferQueue इंटरफेस हो रही है के साथ मेरी बाइट बफर के लिए स्मृति
फिर मैं आउटपुट प्लेयर:
को तुरंत चालू करता हूं// create audio player for output buffer queue
const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req1[] = {SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &(sample->outputPlayerObject), &outputAudioSrc, &audioSnk,
1, ids1, req1);
// realize the output player
result = (*(sample->outputPlayerObject))->Realize(sample->outputPlayerObject, SL_BOOLEAN_FALSE);
assert(result == SL_RESULT_SUCCESS);
// get the play interface
result = (*(sample->outputPlayerObject))->GetInterface(sample->outputPlayerObject, SL_IID_PLAY, &(sample->outputPlayerPlay));
assert(result == SL_RESULT_SUCCESS);
// get the buffer queue interface for output
result = (*(sample->outputPlayerObject))->GetInterface(sample->outputPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&(sample->outputBufferQueue));
assert(result == SL_RESULT_SUCCESS);
// set the player's state to playing
result = (*(sample->outputPlayerPlay))->SetPlayState(sample->outputPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(result == SL_RESULT_SUCCESS);
मैं नमूना खेलने के लिए चाहते हैं, तो मैं उपयोग कर रहा हूँ:
Sample *sample = &samples[sampleNum];
// THIS WORKS FOR SIMPLY PLAYING THE SAMPLE, BUT I WANT THE BUFFER DIRECTLY
// if (sample->fdPlayerPlay != NULL) {
// // set the player's state to playing
// (*(sample->fdPlayerPlay))->SetPlayState(sample->fdPlayerPlay, SL_PLAYSTATE_PLAYING);
// }
// fill buffer with the samples from the file descriptor
(*(sample->fdBufferQueue))->Enqueue(sample->fdBufferQueue, sample->buffer,sample->totalSamples*sizeof(short));
// write the buffer to the outputBufferQueue, which is already playing
(*(sample->outputBufferQueue))->Enqueue(sample->outputBufferQueue, sample->buffer, sample->totalSamples*sizeof(short));
बहरहाल, यह फ्रीज और बंद करने के लिए मेरे एप्लिकेशन का कारण बनता है। यहाँ कुछ गलत है। भी, मैं प्रत्येक बार फाइल डिस्क्रिप्टर के बफरक्यूयू से नमूने नहीं लेना पसंद करूंगा। इसके बजाए, मैं इसे बाइट सरणी में स्थायी रूप से संग्रहीत करना चाहता हूं, और जब भी मुझे पसंद हो तो उत्पादन को एनक्यू करें।
हैलो खिनर, क्या यह आपको जावा बाइट या शॉर्ट सरणी में संपत्ति फ़ोल्डर से .wav- फ़ाइलों को पढ़ने में मदद करेगा और फिर इसे आगे संसाधित करेगा? –
यह सुनिश्चित नहीं है कि मैं कितनी मदद कर सकता हूं, लेकिन सिर्फ रिकॉर्ड के लिए - क्या आप एनडीके का उपयोग कर रहे हैं? क्या आपका कोड सी ++ में क्यों है? – Erhannis
हां, मैं एनडीके का उपयोग कर रहा हूं, और यह वास्तव में शुद्ध सी है। यह सवाल दांत में लंबा हो रहा है। मैंने इस पर बहुत प्रगति की है और एक सभ्य उत्तर जोड़ने के लिए चारों ओर मिल जाएगा। – khiner