如何改变音高? 我在Android应用程序中使用 OBOE C++库播放声音。 我想更改音频样本的音调。 因此,我开始创建“mPos”浮点值来保存当前播放的帧,并在每一步添加“mPitch”值

如何改变音高? 我在Android应用程序中使用 OBOE C++库播放声音。 我想更改音频样本的音调。 因此,我开始创建“mPos”浮点值来保存当前播放的帧,并在每一步添加“mPitch”值,android,c++,audio,oboe,Android,C++,Audio,Oboe,似乎新音高的音频播放正确,但当音高较高(例如1.2)时,音频会加倍,并发出奇怪的噪音,当音高较低时(例如0.212),音频会加倍 这是我第一次做音频节目, 在我发布这个问题之前,我做了很多研究。我甚至直接向“双簧管”支持者发送消息,但没有回应。 有没有人知道如何正确地实施这个计划 streamLength始终192 channelCount始终2 代码: void播放器::renderAudio(float*stream,int32_t streamLength){ const int32_t

似乎新音高的音频播放正确,但当音高较高(例如1.2)时,音频会加倍,并发出奇怪的噪音,当音高较低时(例如0.212),音频会加倍

这是我第一次做音频节目, 在我发布这个问题之前,我做了很多研究。我甚至直接向“双簧管”支持者发送消息,但没有回应。 有没有人知道如何正确地实施这个计划

streamLength始终192

channelCount始终2

代码:

void播放器::renderAudio(float*stream,int32_t streamLength){
const int32_t channelCount=mSound->getChannelCount();
如果(错放){
float framesToRenderFromData=流长度;
float totalSourceFrames=mSound->getTotalFrames()/mPitch;
常量浮点*data=mSound->getData();
//检查我们是否即将结束录音
如果(mPos+streamLength>=totalSourceFrames){
FrameStoreAnderFromData=(totalSourceFrames-mPos);
错放=假;
}
对于(int i=0;i=totalSourceFrames){
mPos=0;
}
}
if(framesToRenderFromData
将浮点变量(mPos)乘以整型变量(channelCount)时,结果为浮点。你,至少,弄乱了你的频道交错。而不是

(size_t)(mPos * channelCount)
试一试

编辑: 当到达末尾时,您有意使用if语句循环源代码,从而导致
mPos=0。不必这样做,您可以独立于音高计算源采样数,但在源采样用尽时中断循环。此外,由于音高调整,源样本和目标样本的比较也没有用处:

    float framesToRenderFromData = streamLength ;
    float totalSourceFrames = mSound->getTotalFrames();  // Note change here
    const float *data = mSound->getData();

    // Note: Only check here is whether mPos has reached the end from
    // a previous call
    if ( mPos >= totalSourceFrames ) {
        framesToRenderFromData = 0.0f;
    }
    for (int i = 0; i < framesToRenderFromData; ++i) {
       for (int j = 0; j < channelCount; ++j) {
           if(j % 2 == 0){
                stream[(i*channelCount)+j] = (data[((size_t)mPos * channelCount)) + j] * mLeftVol) * mVol;
            }else{
                stream[(i*channelCount)+j] = (data[((size_t)mPos * channelCount)) + j] * mRightVol) * mVol;
            }
        }
        mPos += mPitch;
        if ( ((size_t)mPos) >= totalSourceFrames ) {   // Replace this 'if' and its contents
            framesToRenderFromData = (size_t)mPos;
            mPos = 0.0f;
            break;
        }
    }
float framesToRenderFromData=streamLength;
float totalSourceFrames=mSound->getTotalFrames();//注意这里的变化
常量浮点*data=mSound->getData();
//注意:此处仅检查mPos是否已从到达末尾
//先前的电话
如果(mPos>=totalSourceFrames){
FrameStoreAnderFromData=0.0f;
}
对于(int i=0;i=totalSourceFrames){//替换此“if”及其内容
FrameStoreAnderFromData=(大小)mPos;
mPos=0.0f;
打破
}
}

然而,为了完整起见,请注意:对于任何严肃的应用程序,您确实不应该以这种方式完成音高变化——音质将非常糟糕。有免费的库用于音频重新采样到任意目标速率;这些会将源样本转换为更高或更低数量的样本,并在以与源样本相同的速率重放时提供高质量的音高变化。

谢谢,Charles,这肯定修复了奇怪的噪音,但在某些样本中,当音高太高时,会播放多次。也许我在“if(mPos+streamLength>=totalSourceFrames){”行中遗漏了什么(检查我们是否即将到达录制的结尾)。谢谢,现在好多了!请注意安全查尔斯:)
((size_t)mPos) * channelCount
    float framesToRenderFromData = streamLength ;
    float totalSourceFrames = mSound->getTotalFrames();  // Note change here
    const float *data = mSound->getData();

    // Note: Only check here is whether mPos has reached the end from
    // a previous call
    if ( mPos >= totalSourceFrames ) {
        framesToRenderFromData = 0.0f;
    }
    for (int i = 0; i < framesToRenderFromData; ++i) {
       for (int j = 0; j < channelCount; ++j) {
           if(j % 2 == 0){
                stream[(i*channelCount)+j] = (data[((size_t)mPos * channelCount)) + j] * mLeftVol) * mVol;
            }else{
                stream[(i*channelCount)+j] = (data[((size_t)mPos * channelCount)) + j] * mRightVol) * mVol;
            }
        }
        mPos += mPitch;
        if ( ((size_t)mPos) >= totalSourceFrames ) {   // Replace this 'if' and its contents
            framesToRenderFromData = (size_t)mPos;
            mPos = 0.0f;
            break;
        }
    }