【发布时间】:2026-02-10 21:25:02
【问题描述】:
我目前正在尝试在我的 Android 应用程序中实现 libmp3lame,以便将 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 函数我做错了什么?
【问题讨论】:
标签: android android-ndk java-native-interface mp3