AVAudioEngine播放音頻變速不變調(diào)

AVAudioEngine和AVAudioPlayerNode的使用

AVAudioPlayer能通過(guò)rate屬性控制播放的速率,但是變速后會(huì)變調(diào),而AVAudioEngine能做到控制播放變速不變調(diào)。

    //create Node
    self.mbEngine = [AVAudioEngine new];
    self.mbPlayerNode = [AVAudioPlayerNode new];
    self.mbAudioUnitTimePitch = [AVAudioUnitTimePitch new];
    self.mbAudioUnitVarispeed = [AVAudioUnitVarispeed new];
    
    [self.mbEngine attachNode:self.mbPlayerNode];
    [self.mbEngine attachNode:self.mbAudioUnitTimePitch];
    [self.mbEngine attachNode:self.mbAudioUnitVarispeed];
    
    //connectNode
    [self.mbEngine connect:self.mbPlayerNode to:self.mbAudioUnitTimePitch format:self.mbAudioFile.processingFormat];
    
    [self.mbEngine connect:self.mbAudioUnitTimePitch to:self.mbAudioUnitVarispeed format:self.mbAudioFile.processingFormat];
    
    [self.mbEngine connect:self.mbAudioUnitVarispeed to:self.mbEngine.mainMixerNode format:self.mbAudioFile.processingFormat];
    //start Engine
    [self.mbEngine prepare];
    [self.mbEngine startAndReturnError:&error];
   
    //通過(guò)設(shè)置mbAudioUnitVarispeed和AVAudioUnitTimePitch來(lái)控制速度和音調(diào)。兩者間存在個(gè)關(guān)系。
    float  speed = 0.5;
    float  pitch = 0;
    pitch = fabsf(log2f(speed)) *1200;
    self.mbAudioUnitVarispeed.rate = speed;
    self.mbAudioUnitTimePitch.pitch = pitch;
    
    
    //然后是播放,控制一下兩邊極值
    seekTime = seekTime > self.playerNodeDuration ? self.playerNodeDuration : seekTime;
    
    seekTime = seekTime > 0 ? seekTime : 0;
    
    AVAudioFramePosition seekFrame = seekTime * tempFile.processingFormat.sampleRate;
    //記錄一下播放前的位置,用來(lái)計(jì)算當(dāng)前的播放時(shí)間
    self.lastStartFramePosition = seekFrame;
    AVAudioFrameCount frameCount = (AVAudioFrameCount)(tempFile.length - seekFrame);
    
    BOOL isPlaying = self.mbPlayerNode.isPlaying;
    
    [self.mbPlayerNode stop];
    
    if (seekFrame < (AVAudioFramePosition)tempFile.length) {
        
        [self.mbPlayerNode scheduleSegment:tempFile startingFrame:seekFrame frameCount:frameCount atTime:nil completionHandler:^{
            
        }];
        
        if (isPlaying) {
            [self.mbPlayerNode play];
        }
    }

關(guān)于獲取總時(shí)間和當(dāng)前的播放時(shí)間

AVAudioTime *playerTime = [self.mbPlayerNode playerTimeForNodeTime:self.mbPlayerNode.lastRenderTime];
self.playerNodeCurrenttime = (self.lastStartFramePosition+playerTime.sampleTime)/playerTime.sampleRate;
NSLog(@"當(dāng)前時(shí)間%f",self.playerNodeCurrenttime);

可能會(huì)出現(xiàn)的一些問(wèn)題

//1,engine被置空為nil了
required condition is false: _engine != nil
//2,engine在node播放前未啟動(dòng)
required condition is false: _engine->IsRunning()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容