簡體   English   中英

如何改變音頻音調?

[英]How to change audio pitch?

我正在使用雙簧管C++ 庫在我的 android 應用程序中播放聲音。 我想改變我的音頻樣本的音高。 所以,我開始創建“ mPos ”浮點值來保存當前播放的幀並每一步添加“ mPitch ”值。

似乎使用新音高正確播放了音頻,但是當音高高(例如 1.2)並發出奇怪的噪音以及音高低(例如 0.212)時,它是它自身的兩倍。

這是我第一次進行音頻編程,在發布這個問題之前我做了很多研究。 我什至直接向“雙簧管”支持人員發送消息,但沒有回應。 有沒有人知道如何正確實施 Pitch?

streamLength始終為192

channelCount總是2

代碼:

void Player::renderAudio(float *stream, int32_t streamLength){

    const int32_t channelCount = mSound->getChannelCount();

    if (mIsPlaying){

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

        // Check whether we're about to reach the end of the recording
        if (mPos + streamLength >= totalSourceFrames ){
            framesToRenderFromData = (totalSourceFrames - mPos);
            mIsPlaying = false;
        }
        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(mPos >= totalSourceFrames){
                mPos = 0;
            }
        }
        if (framesToRenderFromData < streamLength){
            renderSilence(&stream[(size_t)framesToRenderFromData], streamLength * channelCount);
        }
    } else {
        renderSilence(stream, streamLength * channelCount);
    }
}

void Player::renderSilence(float *start, int32_t numSamples){
    for (int i = 0; i < numSamples; ++i) {
        start[i] = 0;
    }
}

void Player::setPitch(float pitchData){
    mPitch = pitchData;
};

將浮點變量 (mPos) 乘以整數類型變量 (channelCount) 時,結果是浮點數。 至少,您弄亂了頻道交錯。 代替

(size_t)(mPos * channelCount)

嘗試

((size_t)mPos) * channelCount

編輯:您在到達末尾時故意循環源,使用導致mPos = 0;的 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;
        }
    }

但是,為了完整起見,請注意:對於任何嚴肅的應用程序,您真的不應該以這種方式完成音調變化——音質會很糟糕。 有免費的庫可以將音頻重采樣到任意目標速率; 這些會將您的源樣本轉換為更多或更少的樣本,並在以與源相同的速率重播時提供高質量的音高變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM