translate audio_player.c into English

translate audio_player.c into English
pull/166/head
xufulong 5 years ago
parent 3e4def578d
commit 639c0082bf
  1. 91
      app/src/main/cpp/openSL_audio_player.c

@ -17,29 +17,28 @@
#define TAG "OpenSLPlayer"
//引擎接口
//object of engine
SLObjectItf engineObject = NULL;
SLEngineItf engineEngine;
//输出混音器接口
//object of mixer
SLObjectItf outputMixObject = NULL;
SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
//缓冲播放器接口
//object of buffer
SLObjectItf bqPlayerObject = NULL;
SLPlayItf bqPlayerPlay;
SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
SLEffectSendItf bqPlayerEffectSend;
SLVolumeItf bqPlayerVolume;
//音效设置
//audio effect
const SLEnvironmentalReverbSettings reverbSettings = SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
void *buffer;
size_t bufferSize;
uint8_t *outputBuffer;
size_t outputBufferSize;
//FFmpeg相关
AVPacket packet;
int audioStream;
AVFrame *aFrame;
@ -48,48 +47,40 @@ AVFormatContext *aFormatCtx;
AVCodecContext *aCodecCtx;
int frame_count = 0;
int createAudioPlayer(int *rate, int *channel, const char *file_name) ;
int createAudioPlayer(int *rate, int *channel, const char *file_name);
// 释放相关资源
int releaseAudioPlayer();
// 获取PCM数据, 自动回调获取
int getPCM(void **pcm, size_t *pcmSize) ;
int getPCM(void **pcm, size_t *pcmSize);
//播放回调方法
//callback by player
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bufferQueueItf, void *context) {
bufferSize = 0;
getPCM(&buffer, &bufferSize);
//如果buffer不为空,入待播放队列
if (NULL != buffer && 0 != bufferSize) {
SLresult result;
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer, bufferSize);
if(result < 0){
if (result < 0) {
LOGE(TAG, "Enqueue error...");
} else{
} else {
LOGI(TAG, "decode frame count=%d", frame_count++);
}
}
}
//创建OpenSLES引擎
//create the engine of OpenSLES
void createEngine() {
SLresult result;
//创建引擎
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
LOGI(TAG, "slCreateEngine=%d", result);
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
LOGI(TAG, "engineObject->Realize=%d", result);
//获取引擎接口
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
LOGI(TAG, "engineObject->GetInterface=%d", result);
//创建输出混音器
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
LOGI(TAG, "CreateOutputMix=%d", result);
//关联输出混音器
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
LOGI(TAG, "outputMixObject->Realize=%d", result);
//获取reverb接口
result = (*outputMixObject)->GetInterface(outputMixObject, SL_IID_ENVIRONMENTALREVERB,
&outputMixEnvironmentalReverb);
LOGI(TAG, "outputMixObject->GetInterface=%d", result);
@ -101,12 +92,12 @@ void createEngine() {
}
//创建带有缓冲队列的音频播放器
void createBufferQueueAudioPlayer(int rate, int channel, int bitsPerSample) {
SLresult result;
//配置音频源
SLDataLocator_AndroidSimpleBufferQueue buffer_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
//config audio source
SLDataLocator_AndroidSimpleBufferQueue buffer_queue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
2};
SLDataFormat_PCM format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM;
format_pcm.numChannels = (SLuint32) channel;
@ -120,66 +111,54 @@ void createBufferQueueAudioPlayer(int rate, int channel, int bitsPerSample) {
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
SLDataSource audioSrc = {&buffer_queue, &format_pcm};
//配置音频池
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
//创建音频播放器
const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME};
const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
3, ids, req);
LOGI(TAG, "CreateAudioPlayer=%d", result);
//关联播放器
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
LOGI(TAG, "bqPlayerObject Realize=%d", result);
//获取播放接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
LOGI(TAG, "GetInterface bqPlayerPlay=%d", result);
//获取缓冲队列接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
&bqPlayerBufferQueue);
LOGI(TAG, "GetInterface bqPlayerBufferQueue=%d", result);
//注册缓冲队列回调
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
LOGI(TAG, "RegisterCallback=%d", result);
//获取音效接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND,
&bqPlayerEffectSend);
LOGI(TAG, "GetInterface effect=%d", result);
//获取音量接口
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
LOGI(TAG, "GetInterface volume=%d", result);
//开始播放音乐
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
LOGI(TAG, "SetPlayState=%d", result);
}
int createAudioPlayer(int *rate, int *channel, const char *file_name) {
//注册相关组件
av_register_all();
aFormatCtx = avformat_alloc_context();
//打开音频文件
if (avformat_open_input(&aFormatCtx, file_name, NULL, NULL) != 0) {
LOGE(TAG, "Couldn't open file:%s\n", file_name);
return -1; // Couldn't open file
return -1;
}
//寻找stream信息
if (avformat_find_stream_info(aFormatCtx, NULL) < 0) {
LOGE(TAG, "Couldn't find stream information.");
return -1;
}
//寻找音频stream
int i;
audioStream = -1;
for (i = 0; i < aFormatCtx->nb_streams; i++) {
@ -192,64 +171,56 @@ int createAudioPlayer(int *rate, int *channel, const char *file_name) {
LOGE(TAG, "Couldn't find audio stream!");
return -1;
}
//获取解码器context
aCodecCtx = aFormatCtx->streams[audioStream]->codec;
//寻找音频解码器
AVCodec *aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
if (!aCodec) {
fprintf(stderr, "Unsupported codec!\n");
return -1;
}
//打开解码器
if (avcodec_open2(aCodecCtx, aCodec, NULL) < 0) {
LOGE(TAG, "Could not open codec.");
return -1;
}
aFrame = av_frame_alloc();
// 设置格式转换
swr = swr_alloc();
av_opt_set_int(swr, "in_channel_layout", aCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "out_channel_layout", aCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "in_sample_rate", aCodecCtx->sample_rate, 0);
av_opt_set_int(swr, "out_sample_rate", aCodecCtx->sample_rate, 0);
av_opt_set_sample_fmt(swr, "in_sample_fmt", aCodecCtx->sample_fmt, 0);
av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_int(swr, "in_channel_layout", aCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "out_channel_layout", aCodecCtx->channel_layout, 0);
av_opt_set_int(swr, "in_sample_rate", aCodecCtx->sample_rate, 0);
av_opt_set_int(swr, "out_sample_rate", aCodecCtx->sample_rate, 0);
av_opt_set_sample_fmt(swr, "in_sample_fmt", aCodecCtx->sample_fmt, 0);
av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
swr_init(swr);
// 分配PCM数据缓存
outputBufferSize = 8196;
outputBuffer = (uint8_t *) malloc(sizeof(uint8_t) * outputBufferSize);
// 返回sample rate和channels
*rate = aCodecCtx->sample_rate;
*channel = aCodecCtx->channels;
return 0;
}
// 获取PCM数据, 自动回调获取
int getPCM(void **pcm, size_t *pcmSize) {
while (av_read_frame(aFormatCtx, &packet) >= 0) {
int frameFinished = 0;
//音频流
//is audio stream
if (packet.stream_index == audioStream) {
avcodec_decode_audio4(aCodecCtx, aFrame, &frameFinished, &packet);
//解码完一帧数据
//decode success
if (frameFinished) {
// data_size为音频数据所占的字节数
int data_size = av_samples_get_buffer_size(
aFrame->linesize, aCodecCtx->channels,
aFrame->nb_samples, aCodecCtx->sample_fmt, 1);
if (data_size > outputBufferSize) {
outputBufferSize = (size_t) data_size;
outputBuffer = (uint8_t *) realloc(outputBuffer, sizeof(uint8_t) * outputBufferSize);
outputBuffer = (uint8_t *) realloc(outputBuffer,
sizeof(uint8_t) * outputBufferSize);
}
// 音频格式转换
swr_convert(swr, &outputBuffer, aFrame->nb_samples,
(uint8_t const **) (aFrame->extended_data),
aFrame->nb_samples);
// 返回pcm数据
*pcm = outputBuffer;
*pcmSize = (size_t) data_size;
return 0;
@ -259,7 +230,6 @@ int getPCM(void **pcm, size_t *pcmSize) {
return -1;
}
// 释放相关资源
int releaseAudioPlayer() {
av_packet_unref(&packet);
av_free(outputBuffer);
@ -275,20 +245,12 @@ AUDIO_PLAYER_FUNC(void, playAudio, jstring filePath) {
const char *file_name = (*env)->GetStringUTFChars(env, filePath, NULL);
LOGI(TAG, "file_name=%s", file_name);
// 创建音频解码器
createAudioPlayer(&rate, &channel, file_name);
// 创建播放引擎
createEngine();
// 创建缓冲队列音频播放器
createBufferQueueAudioPlayer(rate, channel, SL_PCMSAMPLEFORMAT_FIXED_16);
// 启动音频播放
bqPlayerCallback(bqPlayerBufferQueue, NULL);
}
//停止播放,释放相关资源
AUDIO_PLAYER_FUNC(void, stop) {
if (bqPlayerObject != NULL) {
(*bqPlayerObject)->Destroy(bqPlayerObject);
@ -311,6 +273,5 @@ AUDIO_PLAYER_FUNC(void, stop) {
engineEngine = NULL;
}
// 释放解码器相关资源
releaseAudioPlayer();
}

Loading…
Cancel
Save