2017-01-12 5 views
2

J'essaye de réparer l'enregistrement d'appel dans mon application depuis la mise à jour de lolipop dans mon Galaxy S5. Comme base, j'utilise google exemple de projet d'ici: Sample.Enregistrement d'appel avec OpenSL

Et ceci est la partie principale du code:

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_); 

Et voici mon problème ce code ne pas enregistrer autre côté de l'appel, dans le fichier de sortie, je ne peux pas entendre la voix du microphone. J'ai essayé de changer les paramètres mais avec le même résultat. Quelqu'un sait ce que je fais mal?

+0

Bonjour @ Rafal-DeptA, avez-vous une solution pour le même ou pour l'enregistrement d'appel dans Android? Toute aide sera vraiment appréciable. Merci d'avance. –

+0

Bonjour @ChanchalShelar pour résoudre ce problème Vous devez écrire du code en C++ en utilisant Android NDK. –

+0

Merci, @ rafal-depta pour l'indice, une référence possible? –

Répondre

2

J'ai trouvé la solution pour corriger l'enregistrement d'appel Galaxy S5.

Le principal est d'appeler ceci: status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) dans la boucle lorsque l'appel est lancé.

D'abord obtenir la fonction souhaitée:

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

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

Ensuite, nous devons audio_io_handle_t et String8& objet:

  1. audio_io_handle_t - est l'identifiant de session audio a augmenté de 1, vous pouvez l'obtenir à partir AudioRecord.getAudioSessionId
  2. String8& c'est plus difficile:

    //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); 
    

Quand nous avons toutes les pièces nécessaires, nous pouvons appeler la fonction de setParameters:

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

que la façon dont la déclaration des variables semble:

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

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

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

@ChanchalShelar


@ Peter @AkshatVajpayee

Voici comment mon fichier .cpp ressemble:

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

homme pouvez-vous montrer un peu plus de code complété? S'il vous plaît – Peter

2

Vous devez utiliser NDK. Voici des exemples de fonctions qui doivent être effectuées.

Charge libmedia.so et libutils.si

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;} 

Fonction 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 Tâche

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); 
    } 
} 

Il y a une bibliothèque et un exemple d'utilisation https://github.com/ViktorDegtyarev/CallRecLib