其他分享
首页 > 其他分享> > android – 用OpenSL调用录音

android – 用OpenSL调用录音

作者:互联网

自从我的Galaxy S5中的lolipop更新后,我尝试在我的应用程序中修复通话录音.作为基础我从这里使用谷歌示例项目:Sample.

这是代码的主要部分:

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

这是我的问题,这段代码不记录通话的另一面,在输出文件中我只能听到麦克风发出的声音.我尝试更改参数,但结果相同.谁知道我做错了什么?

解决方法:

我找到了修复Galaxy S5通话录音的解决方案.

主要是这个叫:
调用开始时循环中的status_t AudioSystem :: setParameters(audio_io_handle_t ioHandle,const String8& keyValuePairs).

首先得到所需的功能:

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

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

接下来我们需要audio_io_handle_t和String8&宾语:

> audio_io_handle_t-音频会话ID增加1,您可以从AudioRecord.getAudioSessionId获取它
> 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

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

标签:android,android-ndk,audio-recording,voice-recording
来源: https://codeday.me/bug/20191004/1853931.html