2017-01-12 8 views
2

ギャラクシーS5でlolipopを更新してから私のアプリで通話記録を修正しようとしています。ベースとして私はここからGoogleサンプルプロジェクトを使用しています:SampleOpenSLで録音する

そして、これはコードの主要な部分である:

AudioRecorder :: AudioRecorder(SampleFormat * sampleFormat、SLEngineItf slEngine):freeQueue_(nullptr)、recQueue_(nullptr)、devShadowQueue_(nullptr)、callback_(nullptr)

SLresult result; 
sampleInfo_ = *sampleFormat; 
SLAndroidDataFormat_PCM_EX format_pcm; 
ConvertToSLSampleFormat(&format_pcm, &sampleInfo_); 

gFp = fopen("/storage/emulated/0/file.pcm", "w"); 

// configure audio source 
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, 
            SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; 
SLDataSource audioSrc = {&loc_dev, NULL}; 


// configure audio sink 
SLDataLocator_AndroidSimpleBufferQueue loc_bq = { 
     SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 
     DEVICE_SHADOW_BUFFER_QUEUE_LEN}; 

SLDataSink audioSnk = {&loc_bq, &format_pcm}; 

// create audio recorder 
// (requires the RECORD_AUDIO permission) 
const SLInterfaceID id[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, 
          SL_IID_ANDROIDCONFIGURATION}; 

const SLboolean req[2] = {SL_BOOLEAN_FALSE, SL_BOOLEAN_FALSE}; 

result = (*slEngine)->CreateAudioRecorder(slEngine, 
              &recObjectItf_, 
              &audioSrc, 
              &audioSnk, 
              2, 
              id, req); 
SLASSERT(result); 

// Configure the voice recognition preset which has no 
// signal processing for lower latency. 
SLAndroidConfigurationItf inputConfig; 
result = (*recObjectItf_)->GetInterface(recObjectItf_, 
             SL_IID_ANDROIDCONFIGURATION, 
             &inputConfig); 

SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; 
result = (*inputConfig)->SetConfiguration(inputConfig, 
              SL_ANDROID_KEY_RECORDING_PRESET, 
              &presetValue, 
              sizeof(SLint32)); 
SLASSERT(result); 


result = (*recObjectItf_)->Realize(recObjectItf_, SL_BOOLEAN_FALSE); 
SLASSERT(result); 

result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_RECORD, &recItf_); 
SLASSERT(result); 

result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, 
             &recBufQueueItf_); 
SLASSERT(result); 

result = (*recBufQueueItf_)->RegisterCallback(recBufQueueItf_, bqRecorderCallback, this); 
SLASSERT(result); 

devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN); 
assert(devShadowQueue_); 

ここで私の問題は、出力ファイルにコールの相手側を記録せず、マイクからの音声しか聞こえないことです。私はパラメータを変更しようとしましたが、同じ結果でした。誰でも私が間違っていることを知っていますか?

+0

こんにちはする@ラファウ・deptaの例がありますが、何か解決策を手に入れました同じまたはアンドロイドでの録音録音のために?どんな助けでも本当に感謝しています。前もって感謝します。 –

+0

こんにちは@ChanchalShelarでこの問題を解決するAndroid NDKを使用してC++でコードを書く必要があります。 –

+0

ヒントのための@ rafal-depta、ありとあらゆる参照がありますか? –

答えて

2

私は、Galaxy S5コール録音を解決する解決策を見つけました。

主なことは、呼び出しを開始するときにループ内で status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)を呼び出すことです。

まず所望の機能を得る:我々はaudio_io_handle_tString8&オブジェクト必要

open_media = dlopen("/system/lib/libmedia.so", RTLD_LAZY); 

set_parameters = (int (*)(int, void *)) dlsym(open_media, 
                "_ZN7android11AudioSystem13setParametersEiRKNS_7String8E"); 

次へ:

  1. audio_io_handle_t - オーディオセッションIDが1増加され、あなたはAudioRecord.getAudioSessionId
  2. からそれを得ることができます

    String8&これは難しいです:

    我々は、すべての必要な部品を持っている場合
    //First inicialize function 
    create_string = (void (*)(void *, const char *)) dlsym(open_util, 
    "_ZN7android7String8C2EPKc"); 
    
    //next call this function to convert string to required object 
    create_string(&str8, str); 
    

我々はsetParametersを使用する関数を呼び出すことができます。

//remember to call this in loop when recording is starting 
set_parameters(id + 1, &str8); 

どのように変数宣言が見えること:

int (*set_parameters)(int, void *); 

void (*create_string)(void *, const char *); 

void *str8 = 0; 
const char *str = "input_source=4"; 

@ChanchalShelar


を@ピーター@AkshatVajpayee

これは私の.cppファイルがどのように見えるかです:

void *open_media; 
void *open_util; 

int (*set_parameters)(int, void *); 

void (*create_string)(void *, const char *); 

void *str8 = 0; 
const char *str = "input_source=4"; 


extern "C" { 
    JNIEXPORT bool JNICALL 
    Java_com_sample_NativeAudio_init(JNIEnv *env, jclass); 
    JNIEXPORT int JNICALL 
    Java_com_sample_NativeAudio_setParameters(JNIEnv *env, jclass, int id); 
} 


void get_string8() { 
    create_string = (void (*)(void *, const char *)) dlsym(open_util, "_ZN7android7String8C2EPKc"); 

    if (!create_string) { 
     LOGD("There is no create_string function"); 
    } else { 
     LOGD("create_string function OK"); 
    } 

    create_string(&str8, str); 
    if (!str8) { 
     LOGD("Filed to create str8"); 
    } else { 
     LOGD("create str8 success"); 
    } 

} 

JNIEXPORT int JNICALL Java_com_sample_NativeAudio_setParameters(JNIEnv *env, 
                    jclass  type, int id) { 
    if (set_parameters) { 
     return set_parameters(id + 1, &str8); 
    } 

    return 0; 
} 


JNIEXPORT bool JNICALL Java_com_sample_NativeAudio_init(JNIEnv *env, jclass type) { 

    open_util = dlopen("/system/lib/libutils.so", RTLD_LAZY); 

    if (open_util) { 
     get_string8(); 
    } else { 
     return false; 
    } 

    open_media = dlopen("/system/lib/libmedia.so", RTLD_LAZY); 

    if (open_media) { 
     set_parameters = (int (*)(int, void *)) dlsym(open_media, 
               "_ZN7android11AudioSystem13setParametersEiRKNS_7String8E"); 
    } else { 
     return false; 
    } 

    return true; 
} 
+0

男はもう少し完成したコードを表示できますか?お願いします – Peter

2

あなたはNDKを使用する必要があります。実行する必要がある関数の例を次に示します。

libmedia.soとlibutilsをロードします。そう

int load(JNIEnv *env, jobject thiz) { 
    void *handleLibMedia; 
    void *handleLibUtils; 
    int result = -1; 
    lspr func = NULL; 

    pthread_t newthread = (pthread_t) thiz; 

    handleLibMedia = dlopen("libmedia.so", RTLD_NOW | RTLD_GLOBAL); 
    if (handleLibMedia != NULL) { 
     func = dlsym(handleLibMedia, "_ZN7android11AudioSystem13setParametersEiRKNS_7String8E"); 
     if (func != NULL) { 
      result = 0; 
     } 
     audioSetParameters = (lasp) func; 
    } else { 
     result = -1; 
    } 

    handleLibUtils = dlopen("libutils.so", RTLD_NOW | RTLD_GLOBAL); 
    if (handleLibUtils != NULL) { 
     fstr = dlsym(handleLibUtils, "_ZN7android7String8C2EPKc"); 
     if (fstr == NULL) { 
      result = -1; 
     } 
    } else { 
     result = -1; 
    } 

    cmd = CM_D; 

    int resultTh = pthread_create(&newthread, NULL, taskAudioSetParam, NULL); 

    return result;} 

機能setParametersを

int setParam(jint i, jint as) { 
pthread_mutex_lock(&mt); 

audioSession = (int) (as + 1); 

kvp = "input_source=4"; 
kvps = toString8(kvp); 

cmd = (int) i; 

pthread_cond_signal(&cnd); 
pthread_mutex_unlock(&mt); 

return 0;} 

タスクAudioSetParameters

void *taskAudioSetParam(void *threadid) { 
    while (1) { 
     pthread_mutex_lock(&mt); 
     if (cmd == CM_D) { 
      pthread_cond_wait(&cnd, &mt); 
     } else if (audioSetParameters != NULL) { 
      audioSetParameters(audioSession, kvps); 
     } 
     pthread_mutex_unlock(&mt); 
    } 
} 

ライブラリと使用https://github.com/ViktorDegtyarev/CallRecLib