我目前正在尝试将libmp3lame实现到我的Android应用程序中,以便将MP3数据解码为PCM。
要使用libmp3lame,我需要使用JNI / NDK实现,并将MP3解码为PCM我需要使用libmp3lame中的hip_decode()函数。
此函数实例化为“lame.h”文件:
int CDECL hip_decode( hip_t gfp
, unsigned char * mp3buf
, size_t len
, short pcm_l[]
, short pcm_r[]
);
我的应用程序是这样的: 我从WebSocket收到一个单声道MP3样本。我需要将此示例从MP3解码为PCM,然后将其写入我的AudioTrack进行播放。它是实时流,所以我需要尽可能低的延迟。我正在使用JLayer,我完全可以理解发言者的说法,但我有一个“哈希”问题/机器人声音。似乎我在每个样本的开头有一些0值,它引起了一些奇怪的效果。现在我需要对libmp3lame做同样的事情。所以我想做的是以下内容。每次调用WebSocket甚至接收时,我都需要接收字节数组(包含音频数据)并将其解码为PCM。我需要在PCM中使用byte []或short []然后在音轨中播放它。问题是我不确定如何使用hip_decode这样做。我真的不熟悉C编程,所以可能有一个非常简单的方法来做,但我不能这样做。现在在我的wrapper.c中我有这个:
JNIEXPORT void JNICALL Java_com_example_jneb_myapplication_MainActivity_decoderInit(JNIEnv *env, jobject jobj,
) {
hip = hip_decode_init();
}
我不确定使用hip_decode函数需要什么pcm_l和pcm_r。以下是有关该功能的更多信息:
/*********************************************************************
* input 1 mp3 frame, output (maybe) pcm data.
*
* nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r);
*
* input:
* len : number of bytes of mp3 data in mp3buf
* mp3buf[len] : mp3 data to be decoded
*
* output:
* nout: -1 : decoding error
* 0 : need more data before we can complete the decode
* >0 : returned 'nout' samples worth of data in pcm_l,pcm_r
* pcm_l[nout] : left channel data
* pcm_r[nout] : right channel data
*
*********************************************************************/
编辑: 感谢bukkojot回答我已经能够理解什么是pcm_l& pcm_r用于。
以下是我的代码的更新:
JNIEXPORT jshortArray JNICALL Java_com_example_jneb_myapplication_AudioTrackClass_decoderInit(JNIEnv *env, jobject jobj,
jbyteArray data, jint size) {
jsize mp3Len = (*env)->GetArrayLength(env, data);
// Print the data.length = 96
LOGI("JNI integer: %d", mp3Len);
// mp3 contains all 96 values
jbyte *mp3 = (*env)->GetByteArrayElements(env, data, 0);
// Trying to decode mp3 into PCM
int x = hip_decode(hip, (unsigned char*) mp3, (size_t) mp3Len, pcm_l, pcm_r);
jshortArray pcmBuffer;
pcmBuffer = (*env)->NewShortArray(env, mp3Len);
(*env)->SetShortArrayRegion(env, pcmBuffer, 0, mp3Len, pcm_l);
// Releasing byte array
(*env)->ReleaseByteArrayElements(env, data, mp3, 0);
// Returning
return pcmBuffer;
}
现在pcmBuffer只返回0值,而hip_decode也只返回0值。该文档说,如果hip_decode返回0,则hip_decode函数“在我们完成解码之前需要更多数据”。我已经给了函数我所有的数据了。我对hip_decode函数做错了什么?
答案 0 :(得分:2)
不确定使用hip_decode需要什么pcm_l和pcm_r 功能
这是缓冲区的指针,其中将写入解码的PCM。
Alloc某处有足够的内存用于未压缩的声音,如:
signed short *pcm_l=malloc(1000000); // make sure it's enough
signed short *pcm_r=malloc(1000000);
然后将它们传递给解码功能。函数将返回有用样本的数量。将此数据传递给Java部分并写入AudioTrack。