2013-07-25 7 views
12

के लिए ओपस कोडेक को संकलित करने के लिए मेकफ़ाइल की आवश्यकता है, मैं एंड्रॉइड एप्लिकेशन में उपयोग के लिए ओपस ऑडियो कोडेक (http://www.opus-codec.org/downloads/) संकलित करने की कोशिश कर रहा हूं। मैं अपने पुस्तकालयों को संकलित करने के लिए एंड्रॉइड एनडीके (रिलीज 6) का उपयोग कर रहा हूं। अब तक, मूल सी पुस्तकालय जो मुझे अपने आवेदन के लिए संकलित करना था, काफी सरल रहा है और मैं अपने एंड्रॉइड.एमके फ़ाइलों को जेनी में ज्यादातर ट्यूटोरियल या अन्य उदाहरणों पर आधारित करने में सक्षम हूं। हालांकि, ओपस का संकलन कुछ और जटिल दिखता है। Tar.gz संग्रह में विंडोज के लिए पुस्तकालयों को संकलित करने के लिए एक समाधान फ़ाइल है और इसमें मानक यूनिक्स कार्यान्वयन के लिए कुछ मेकफ़ाइल भी शामिल हैं, लेकिन इन्हें एंड्रॉइड एनडीके द्वारा उपयोग के लिए एंड्रॉइड.एमके मेकफ़ाइल में अनुवाद करना एक चुनौती है।एंड्रॉइड

मैंने खोज की है, लेकिन एंड्रॉइड मेकफ़ाइल के लिए libopus संकलित करने के लिए ऑनलाइन संस्करण नहीं ढूंढ पाया है। क्या कोई शायद मुझे ऐसे मेकफ़ाइल से जोड़ सकता है? वैकल्पिक रूप से, मुझे कुछ आसान याद आ रहा है? क्या संभवत: tar.gz में पहले से शामिल यूनिक्स मेकफ़ाइल से एंड्रॉइड.एमके फ़ाइल उत्पन्न करने के लिए ऑटोमैक या किसी प्रकार का कनवर्टर का उपयोग करना संभव है?

उत्तर

12

एंड्रॉइड.एमके मेकफ़ाइल निम्नलिखित है जो अंततः मेरे लिए काम करता है। मुझे उम्मीद है कि यह भविष्य में किसी और की भी मदद कर सकता है। ध्यान दें कि ओपस आर्काइव में यूनिक्स मेकफ़ाइल में शामिल है, फिक्स्ड या फ्लोट रेशम स्रोतों का उपयोग करने का निर्णय "ifdef" के रूप में परिभाषित किया गया है, जबकि यहां मैं "निश्चित" का उपयोग कर रहा हूं। ("फ्लोट" का उपयोग करने के लिए सरल हो सकता है -। बस रास्तों "रेशम/तय करने के लिए" "रेशम/फ्लोट" बात करने के लिए और अद्यतन CFLAGS

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

MY_MODULE_DIR  := opus 

LOCAL_MODULE  := $(MY_MODULE_DIR) 
LOCAL_SRC_FILES  := \ 
    $(subst $(ROOT_DIR)/$(MY_MODULE_DIR)/,,$(wildcard $(ROOT_DIR)/$(MY_MODULE_DIR)/src/*.c*)) \ 
    $(subst $(ROOT_DIR)/$(MY_MODULE_DIR)/,,$(wildcard $(ROOT_DIR)/$(MY_MODULE_DIR)/celt/*.c*)) \ 
    $(subst $(ROOT_DIR)/$(MY_MODULE_DIR)/,,$(wildcard $(ROOT_DIR)/$(MY_MODULE_DIR)/silk/*.c*)) \ 
    $(subst $(ROOT_DIR)/$(MY_MODULE_DIR)/,,$(wildcard $(ROOT_DIR)/$(MY_MODULE_DIR)/silk/fixed/*.c*)) 
LOCAL_LDLIBS  := -lm -llog 
LOCAL_C_INCLUDES := \ 
    $(ROOT_DIR)/$(MY_MODULE_DIR)/include \ 
    $(ROOT_DIR)/$(MY_MODULE_DIR)/silk \ 
    $(ROOT_DIR)/$(MY_MODULE_DIR)/silk/fixed \ 
    $(ROOT_DIR)/$(MY_MODULE_DIR)/celt 
LOCAL_CFLAGS  := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno 
LOCAL_CPPFLAGS  := -DBSD=1 
LOCAL_CPPFLAGS   += -ffast-math -O3 -funroll-loops 

include $(BUILD_STATIC_LIBRARY) 
+2

इसे ओपस लोगों को वापस क्यों न दें? – Samveen

+0

अच्छा विचार। करूँगा। – Stanley

+1

हे स्टेनली, क्या इसे कभी भी आधिकारिक ओपस रिलीज में जोड़ा गया है? ओपस का कौन सा संस्करण इस मेकफ़ाइल के लिए था? क्या आपके पास v1.1 के लिए एक अपडेटेड मेकफ़ाइल है? –

2

संपादित करें: ऊपर दिए गए स्वीकृत उत्तर के समाधान का उपयोग करें, मूल लिंक मृत है और यह मूल रूप से उत्तर दिए गए समय के रूप में स्वीकार किए गए उत्तर के समान है।

यहाँ एक है, हो सकता है एक छोटे से पुराना (यह रचना 0.9.14 प्रयुक्त):

https://github.com/haxar/mangler/blob/master/android/jni/Android.mk

आप पुस्तकालय संकलित करने के लिए प्राप्त करने के बाद कुछ JNI रैपर लिखने के लिए कर रहे हैं, हालांकि ...

+0

धन्यवाद, इस ट्रैक पर मुझे सेट में मदद की। मेकफ़ाइल के लिबोपस भाग का उपयोग करते समय मुझे कुछ लिंकर त्रुटियां मिलीं, इसलिए मुझे इसे बदलना पड़ा। मैं उलझन में हूं क्योंकि लिंक यह दिखाने में मददगार था कि सेल्ट, रेशम और ओपस स्रोतों को एक संकलन में जोड़ा जा सकता है और इसे अलग-अलग मॉड्यूल में अलग से संकलित नहीं किया जाना चाहिए। – Stanley

+0

जो एंड्रॉइड से इन जेएनआई इंटरफ़ेस को कॉल करने के बारे में जानता है? मैं आवाज रिकॉर्ड करना चाहता हूं, लेकिन मुझे नहीं पता कि आवाज़ रिकॉर्ड करने और उन्हें फ़ाइल में सहेजने के लिए ओपस फ़ंक्शंस का उपयोग कैसे करें। – brucenan

+0

@ ब्रुसेनन आप [जावा एपीआई] (http://developer.android.com/reference/android/media/AudioRecord.html) का उपयोग करके ऑडियो नमूने रिकॉर्ड करना चाहते हैं, फिर एन्कोडिंग के लिए सी दायरे में नमूने की रिकॉर्ड की गई सरणी पास करें। उस भाग के लिए आपको खुद को रैपर लिखने की ज़रूरत है, क्योंकि यह स्पष्ट है कि ओपस के पास अब जावा समर्थन नहीं है। उम्मीद है कि [लिपोपस एपीआई दस्तावेज] (http://www.opus-codec.org/docs/html_api-1.1.0/index.html) के अनुसार ऐसे रैपर लिखना आसान है; यह सुनिश्चित करें कि आपने इसे देख किया। फिर, एन्कोडिंग पूर्ण होने के बाद फ़ाइल को पूरी तरह से जावा में किया जा सकता है। उम्मीद है की यह मदद करेगा! –

2

@Stanley के लिए धन्यवाद, मैं एक बनाने के लिए कर रहा था अद्यतन साझा लाइब्रेरी को थोड़ा सा हल करके सफलतापूर्वक साझा किया गया। मुझे अभी तक पता नहीं है कि एक स्थिर लाइब्रेरी बनाम एक साझा लाइब्रेरी बनाने का कोई फायदा है। मुझे पता है कि मुझे जेएनआई रैपर के लिए साझा लाइब्रेरी चाहिए। यही वह है जो मैं । की है। नोट नियत बिन्दु के लिए संकलक झंडे उन के बिना संकलन नियत बिन्दु मोड के लिए असफल हो जायेगी।

पहली प्रति celt_sources.mk, silk_sources.mk और अपने JNI निर्देशिका के लिए रचना स्रोत टारबॉल से opus_sources.mk। लाओ इन फ़ाइलों को अपने Android.mk फ़ाइल में डालने से विभिन्न चर शामिल होंगे जिनका उपयोग आप बिल्ड के प्रकार के आधार पर स्रोत फ़ाइलों को शामिल करने के लिए कर सकते हैं। ओपस बिल्ड प्रक्रिया भी यही करती है।

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

#include the .mk files 
include celt_sources.mk 
include silk_sources.mk 
include opus_sources.mk 

MY_MODULE_DIR  := opus 

LOCAL_MODULE  := $(MY_MODULE_DIR) 

#fixed point sources 
SILK_SOURCES += $(SILK_SOURCES_FIXED) 

#ARM build 
CELT_SOURCES += $(CELT_SOURCES_ARM) 
SILK_SOURCES += $(SILK_SOURCES_ARM) 
LOCAL_SRC_FILES  := \ 
$(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES) 

LOCAL_LDLIBS  := -lm -llog 

LOCAL_C_INCLUDES := \ 
$(LOCAL_PATH)/include \ 
$(LOCAL_PATH)/silk \ 
$(LOCAL_PATH)/silk/fixed \ 
$(LOCAL_PATH)/celt 

LOCAL_CFLAGS  := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 
LOCAL_CFLAGS  += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT=1 -DDISABLE_FLOAT_API -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -O3 -fno-math-errno 
LOCAL_CPPFLAGS  := -DBSD=1 
LOCAL_CPPFLAGS  += -ffast-math -O3 -funroll-loops 

#build a shared library not a static one like in Stanley's solution 
include $(BUILD_SHARED_LIBRARY) 

ओपस लाइब्रेरी के लिए मेरी परियोजना संरचना यहां दी गई है।

Project structure

+0

यह एआरएम के लिए ठीक काम करता प्रतीत होता है, लेकिन x86 के लिए इतना नहीं है। क्या आप जानते हैं कि x86 के लिए मेकफ़ाइल कैसा दिखता है? – Buddy

+0

आपके पास क्या समस्या थी? – praneetloke

+0

ओह ...ऐसा लगता है कि अब ठीक काम करता है, मेरे कोड में कोई समस्या थी। मैंने इसे opusfile के साथ एक साथ संकलित किया है और [op_read()] (https://mf4.xiph.org/jenkins/view/opus/job/opusfile-unix/ws/doc/html/group__stream__decoding का उपयोग कर फ़ाइल पढ़ रहा था। एचटीएमएल # ga963c917749335e29bb2b698c1cb20a10)। ऐसा लगता है कि x86 पर '_buf_size/2' के साथ ठीक काम करना प्रतीत होता है, लेकिन जब मैं '_buf_size' को' jint' के रूप में पास करता हूं (एआरएम पर ठीक काम करता है) तो यह एक सेगफॉल्ट के साथ दुर्घटनाग्रस्त हो जाता है। मैंने देखा कि किसी अन्य व्यक्ति द्वारा लिखे गए कोड में, लेकिन मुझे इस व्यवहार के कारण का पता नहीं है। मुझे बफर आकार को 2 से विभाजित क्यों करना है? धारा मोनो, बीटीडब्ल्यू है। – Buddy

9

महत्वपूर्ण संपादित छवियों तारीख तक नहीं हो सकता है, लेकिन काम संस्करणों नीचे पर परीक्षण किया गया:

  • रचना-1.1
  • रचना-1.1।2

एक अद्यतन संस्करण @ praneetloke के समाधान के (opus-1.1.2 के लिए काम करता है)। कुछ अतिरिक्त के साथ एक अलग दृष्टिकोण। सब से पहले नीचे उपयोग करने के लिए मेरी संरचना (मैं और अधिक पुस्तकालयों का उपयोग करने का इरादा है, इसलिए मैं अपने सब-फ़ोल्डर में रचना डाल दिया।) folder structor for opus JNI

दूसरी बात मैं एक रूट Android.mk फ़ाइल और एक दूसरे फ़ोल्डर रचना के अंदर है -1.1.2

यहाँ जड़ Android.mk फ़ाइल है:

LOCAL_PATH := $(call my-dir) 
OPUS_DIR   := opus-1.1.2 

include $(OPUS_DIR)/Android.mk 

include $(CLEAR_VARS) 

LOCAL_MODULE  := codec 
LOCAL_SRC_FILES  := Opus_jni.cpp 
LOCAL_CFLAGS  := -DNULL=0 
LOCAL_LDLIBS  := -lm -llog 
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(OPUS_DIR)/include 
LOCAL_SHARED_LIBRARIES := opus 
include $(BUILD_SHARED_LIBRARY) 

Android.mkरचना-1.1.2 फ़ोल्डर के अंदर फाइल के नीचे है:

#Backing up previous LOCAL_PATH so it does not screw with the root Android.mk file 
LOCAL_PATH_OLD := $(LOCAL_PATH) 
LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

#include the .mk files 
include $(LOCAL_PATH)/celt_sources.mk 
include $(LOCAL_PATH)/silk_sources.mk 
include $(LOCAL_PATH)/opus_sources.mk 

LOCAL_MODULE  := opus 

#fixed point sources 
SILK_SOURCES += $(SILK_SOURCES_FIXED) 

#ARM build 
CELT_SOURCES += $(CELT_SOURCES_ARM) 
SILK_SOURCES += $(SILK_SOURCES_ARM) 
LOCAL_SRC_FILES  := \ 
$(CELT_SOURCES) $(SILK_SOURCES) $(OPUS_SOURCES) 

LOCAL_LDLIBS  := -lm -llog 

LOCAL_C_INCLUDES := \ 
$(LOCAL_PATH)/include \ 
$(LOCAL_PATH)/silk \ 
$(LOCAL_PATH)/silk/fixed \ 
$(LOCAL_PATH)/celt 

LOCAL_CFLAGS  := -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 

LOCAL_CFLAGS  += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT=1 -DDISABLE_FLOAT_API -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -DAVOID_TABLES 
LOCAL_CFLAGS  += -w -std=gnu99 -O3 -fno-strict-aliasing -fprefetch-loop-arrays -fno-math-errno 
LOCAL_CPPFLAGS  := -DBSD=1 
LOCAL_CPPFLAGS  += -ffast-math -O3 -funroll-loops 

include $(BUILD_SHARED_LIBRARY) 

#Putting previous LOCAL_PATH back here 
LOCAL_PATH := $(LOCAL_PATH_OLD) 

यह है कि यह कैसे opus- अंदर की तरह लग रहा है 1.1.2 फ़ोल्डर:

Whole Opus Folder structure

मूल स्रोतों का एकमात्र स्पर्श Android.mk फ़ाइल का एकमात्र स्पर्श है। कुछ भी नहीं हटाया गया।

इस तरह से मैं एक अलग पुस्तकालय की तरह ओपस का उपयोग और अद्यतन कर सकता हूं।


यहां उन लोगों के लिए अतिरिक्त है जो एंड्रॉइड में संकलन और उपयोग करना चाहते हैं; आवरण स्रोत, आंशिक रूप से:

#include <jni.h> 
#include <android/log.h> 
#include <opus.h> 

/* Header for class net_abcdefgh_opustrial_codec_Opus */ 
#ifndef _Included_net_abcdefgh_opustrial_codec_Opus 
#define _Included_net_abcdefgh_opustrial_codec_Opus 

#define TAG "Opus_JNI" 
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG,__VA_ARGS__) 
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , TAG,__VA_ARGS__) 
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG,__VA_ARGS__) 
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , TAG,__VA_ARGS__) 
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , TAG,__VA_ARGS__) 
#ifdef __cplusplus 
extern "C" { 
    #endif 
    JNIEXPORT jint JNICALL Java_net_abcdefgh_opustrial_codec_Opus_open 
    (JNIEnv *env, jobject thiz){ 
     ... 
     return error; 
    } 
    JNIEXPORT jint JNICALL Java_net_abcdefgh_opustrial_codec_Opus_decode 
    (JNIEnv * env, jobject thiz, jbyteArray jencoded, jint jencodedOffset, jint jencodedLength, jbyteArray jpcm, jint jpcmOffset, jint jframeSize) { 
     ... 
     return decodedSize; 
    } 
    JNIEXPORT jint JNICALL Java_net_abcdefgh_opustrial_codec_Opus_encode 
    (JNIEnv * env, jobject thiz, jbyteArray jpcm, jint jpcmOffset, jint jpcmLength, jbyteArray jencoded, jint jencodedOffset) { 
     ... 
     return encodedSize; 
    } 
    JNIEXPORT void JNICALL Java_net_abcdefgh_opustrial_codec_Opus_close 
    (JNIEnv *env, jobject thiz){ 
     ... 
    } 
    #ifdef __cplusplus 
} 
#endif 
#endif 

Application.mk फ़ाइल (वैकल्पिक)

APP_ABI := all # mips, armeabi, armeabi-v7a, x86 etc. builds 
+0

में एक ही SO फ़ाइल मिलती है बहुत उपयोगी, धन्यवाद! मैं भी, अरमेबी के लिए एक libopus.so बनाने के लिए ऊपर और ऊपर के समान एक है। हालांकि, मैं सोच रहा था कि क्या आपने आर्मेबी-वी 7 ए संस्करण भी बनाया है? – leenephi

+1

@leenhihi मुझे यकीन नहीं है, लेकिन 'application.mk' में' APP_ABI: = all' .so फ़ाइल का समूह उत्पन्न करेगा। यदि आप केवल आर्मेबी और आर्मेबी-वी 7 ए चाहते हैं तो आप 'APP_ABI: = armeabi armeabi-v7a' का उपयोग कर सकते हैं। मैंने अन्य फाइलों का परीक्षण नहीं किया है। इसलिए फाइलें। – guness

+0

मुझे खींचो! यू धन्यवाद! ~ – funs