美文网首页
AVAudioEngine播放音频变速不变调

AVAudioEngine播放音频变速不变调

作者: shikaiming | 来源:发表于2020-01-13 15:09 被阅读0次

    AVAudioEngine和AVAudioPlayerNode的使用

    AVAudioPlayer能通过rate属性控制播放的速率,但是变速后会变调,而AVAudioEngine能做到控制播放变速不变调。

        //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];
       
        //通过设置mbAudioUnitVarispeed和AVAudioUnitTimePitch来控制速度和音调。两者间存在个关系。
        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;
        //记录一下播放前的位置,用来计算当前的播放时间
        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];
            }
        }
    

    关于获取总时间和当前的播放时间

    AVAudioTime *playerTime = [self.mbPlayerNode playerTimeForNodeTime:self.mbPlayerNode.lastRenderTime];
    self.playerNodeCurrenttime = (self.lastStartFramePosition+playerTime.sampleTime)/playerTime.sampleRate;
    NSLog(@"当前时间%f",self.playerNodeCurrenttime);
    

    可能会出现的一些问题

    //1,engine被置空为nil了
    required condition is false: _engine != nil
    //2,engine在node播放前未启动
    required condition is false: _engine->IsRunning()
    

    相关文章

      网友评论

          本文标题:AVAudioEngine播放音频变速不变调

          本文链接:https://www.haomeiwen.com/subject/wyzgactx.html