【发布时间】:2015-08-13 11:54:10
【问题描述】:
我正在尝试实现循环功能。基本上我将音乐样本保存在缓冲区中。 然后,当我按下循环输入按钮时,我会及时设置初始循环,按下循环输出时会设置循环结束时间。 为了获得循环部分,我制作了循环时间 - 及时循环,这给了我循环的秒数。然后我乘以秒 * 采样率 (44100),分配一个具有该大小的新缓冲区并用声音数据填充它。 一切正常,但是当我通过 Open SL ES 收听循环缓冲区时,声音比原来的慢。 我真的不知道为什么......
SLmillisecond loopInPosition, loopOutPosition;
float loopDuration;
const char *lastPath;
short *sampleBuffer, *loopBuffer;
int xSampleBufferSize, xLoopBuffersize;
void playBuffer();
// get the position in the music sample when loop in or out button is pressed
SLmillisecond getCurrentPosition(jint playerIndex, SLmillisecond* whereToSave) {
Player player = players[playerIndex];
if (player.isReady == 1) {
(*(player.playerPlayItf))->GetPosition(player.playerPlayItf,
whereToSave);
__android_log_print(ANDROID_LOG_DEBUG, "jajaja",
">>NATIVE position is: %d", *whereToSave);
}
}
void loopIn(JNIEnv* env,
jclass clazz, jint selectedSlot, jstring filename) {
lastPath = (*env)->GetStringUTFChars(env, filename, NULL);
assert(NULL != path);
getCurrentPosition(selectedSlot, &loopInPosition);
}
void loopOut(JNIEnv* env,
jclass clazz, jint selectedSlot) {
getCurrentPosition(selectedSlot, &loopOutPosition);
loopDuration = (float) ((float) (loopOutPosition - loopInPosition) / 1000);
__android_log_print(ANDROID_LOG_DEBUG, "jajaja",
">>NATIVE loop duration is: %f", loopDuration);
SF_INFO sndInfo;
SNDFILE *sndFile = sf_open(lastPath, SFM_READ, &sndInfo);
if (sndInfo.format != (SF_FORMAT_WAV | SF_FORMAT_PCM_16)) {
fprintf(stderr, "Input should be 16bit Wav\n");
sf_close(sndFile);
} else {
__android_log_print(ANDROID_LOG_DEBUG, "jajaja",
">>NATIVE File info samplerate %d, channels %d, format %d, sections %d, seekable %d",
sndInfo.samplerate, sndInfo.channels, sndInfo.format,
sndInfo.sections, sndInfo.seekable);
}
// Sample Buffer
int sampleBufferSize = sndInfo.frames * sizeof(short);
xSampleBufferSize = sampleBufferSize;
sampleBuffer = malloc(sampleBufferSize);
__android_log_print(ANDROID_LOG_DEBUG, "jajaja",
">>NATIVE allocated sample buffer: size %d, frames %d",
sampleBufferSize, sndInfo.frames);
sf_readf_short(sndFile, sampleBuffer, sndInfo.frames);
// Loop Buffer
int loopBufferSize = loopDuration * 44100 * sizeof(short);
int loopBufferFrames = loopDuration * 44100;
xLoopBuffersize = loopBufferSize;
loopBuffer = malloc(loopBufferSize);
__android_log_print(ANDROID_LOG_DEBUG, "jajaja",
">>NATIVE allocated loop buffer: size %d, frames %d",
loopBufferSize, loopBufferFrames);
int index, i = 0;
int startIndex = (int) ((float) (loopInPosition / 1000) * 44100);
__android_log_print(ANDROID_LOG_DEBUG, "jajaja",
">>NATIVE start index is %d", startIndex);
for (index = startIndex, i = 0; index < startIndex + loopBufferFrames;
++index, ++i) {
loopBuffer[i] = sampleBuffer[index];
}
}
感谢您的宝贵时间
【问题讨论】:
-
听起来像采样率不匹配。慢了多少?
-
是立体声音频吗?另外,你听到的是整个循环还是只是其中的一部分(比如一半)?
-
频率也低吗?
-
我听到所有的循环和频率似乎是一样的,但我真的没有检查它。我现在正准备着手处理它,我不知道为什么如果我将最后几行更改为 loopBuffer[i] = sampleBuffer[index * 2]...效果很好...你能解释一下吗?
-
如果你知道要改变什么才能让它听起来正确,你为什么要在这个论坛上提问?
标签: c loops audio opensl libsndfile