gpt4 book ai didi

android - Superpowered:无法让 TimeStretching 正常工作,输出声音失真

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:07:33 26 4
gpt4 key购买 nike

我正在尝试使用 Superpowered SDK在同时播放和录制的 mp3 文件上应用实时时间拉伸(stretch)和音高移动。问题是无论我做什么,输出的音质都很糟糕(到了失真的程度)。
我怀疑这是由于每个帧编号的样本冲突。这是我的 cpp 文件的完整源代码:

static SuperpoweredAndroidAudioIO *audioIO;
static SuperpoweredTimeStretching *stretching;
static SuperpoweredAudiopointerList *outputBuffers;
static SuperpoweredDecoder *decoder;
static SuperpoweredRecorder *recorder;
const char *outFilePath;
const char *tempFilePath;

static short int *intBuffer;
static float *playerBuffer;

bool audioInitialized = false;
bool playing = false;

static bool audioProcessing(
void *__unused clientData, // custom pointer
short int *audio, // buffer of interleaved samples
int numberOfFrames, // number of frames to process
int __unused sampleRate // sampling rate
) {

if (playing) {
unsigned int samplesDecoded = decoder->samplesPerFrame;
if (decoder->decode(intBuffer, &samplesDecoded) == SUPERPOWEREDDECODER_ERROR) return false;
if (samplesDecoded < 1) {
playing = false;
return false;
}



SuperpoweredAudiobufferlistElement inputBuffer;
inputBuffer.samplePosition = decoder->samplePosition;
inputBuffer.startSample = 0;
inputBuffer.samplesUsed = 0;
inputBuffer.endSample = samplesDecoded;
inputBuffer.buffers[0] = SuperpoweredAudiobufferPool::getBuffer(samplesDecoded * 8 + 64);
inputBuffer.buffers[1] = inputBuffer.buffers[2] = inputBuffer.buffers[3] = NULL;


SuperpoweredShortIntToFloat(intBuffer, (float *) inputBuffer.buffers[0], samplesDecoded);

stretching->process(&inputBuffer, outputBuffers);

if (outputBuffers->makeSlice(0, outputBuffers->sampleLength)) {

while (true) {
int numSamples = 0;
float *timeStretchedAudio = (float *) outputBuffers->nextSliceItem(&numSamples);
if (!timeStretchedAudio) break;

SuperpoweredFloatToShortInt(timeStretchedAudio, intBuffer,
(unsigned int) numSamples);
SuperpoweredShortIntToFloat(intBuffer, playerBuffer, (unsigned int) numSamples);

recorder->process(playerBuffer, (unsigned int) numSamples);
SuperpoweredFloatToShortInt(playerBuffer, audio, (unsigned int) numSamples);

};
outputBuffers->clear();
return true;
};
}
return false;
}


extern "C" JNIEXPORT void
Java_com_example_activities_DubsmashActivity_InitAudio(
JNIEnv __unused *env,
jobject __unused obj,
jint bufferSize,
jint sampleRate,
jstring outputPath,
jstring tempPath
) {

decoder = new SuperpoweredDecoder();

outputBuffers = new SuperpoweredAudiopointerList(8, 16);

outFilePath = env->GetStringUTFChars(outputPath, 0);
tempFilePath = env->GetStringUTFChars(tempPath, 0);

}

extern "C" JNIEXPORT jdouble
Java_com_example_activities_DubsmashActivity_OpenFile(
JNIEnv *env,
jobject __unused obj,
jstring filePath) {
const char *path = env->GetStringUTFChars(filePath, 0);
decoder->open(path);
intBuffer = (short int *) malloc(decoder->samplesPerFrame * 2 * sizeof(short int) + 32768);
playerBuffer = (float *) malloc(decoder->samplesPerFrame * 2 * sizeof(short int) + 32768);
audioIO = new SuperpoweredAndroidAudioIO(
decoder->samplerate,
decoder->samplesPerFrame,
false,
true,
audioProcessing,
NULL,
-1, -1,
decoder->samplesPerFrame * 2
);

stretching = new SuperpoweredTimeStretching(decoder->samplerate);

stretching->setRateAndPitchShift(1, 0);

recorder = new SuperpoweredRecorder(
tempFilePath,
decoder->samplerate,
1,
2,
false,
recorderStopped,
NULL
);

return 0;
}

需要考虑的一些注意事项:

  1. 这不是 this question 的拷贝,因为该线程中的解决方案对我不起作用
  2. 我试过使用 decoder->samplesPerFramenumSamples 但我无法获得像样的输出。
  3. 如果我将 Time Stretching 设置为 1 并将 Pitch Shift 设置为 0,声音将无缝播放。

更新 1:
经过更多的篡改和使用不同的样本数值,我认为问题一定出在音频输出 ( DAC MAN ) 期望的样本量与 outputBuffers->nextSliceItem 实际提供。
话虽如此,我可以想出一种方法来缓解这个问题,那就是将 outputBuffers->nextSliceItem 的输出附加到一个临时缓冲区,然后当它达到阈值时,将其定向到音频输出。

因此我的第二个问题:在 C++ 中有没有办法将一个缓冲区附加到另一个缓冲区?

最佳答案

您需要输出 audioProcessing(int numberOfFrames) 帧数。因此在 outputBuffers->makeSlice 中你需要询问 numberOfFrames,而不是 outputBuffers->sampleLength(基本上你是在询问“outputBuffers 中的任意数量的帧”,而不是“numberOfFrames”)。

然后你从 float 转换为 int,然后再转换回 float?这没有意义。您在 timeStretchedAudio 中获得了浮点音频,您的录音机可以立即对其进行处理。

在那之后,在将一些浮点样本转换成“音频”之后,您忘记了向前推进。

最后,您从 outputBuffers 中删除所有音频,而您只需要删除输出到“音频”的帧数。

关于android - Superpowered:无法让 TimeStretching 正常工作,输出声音失真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52898011/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com