[英]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.