TAAE2 - Crossfade looping

edited May 2016

Hello,

I am not so experience developer in core audio.
Currently I am working on one sequencer project and I want to implement Crossfade loop audio.

Here is explanation :

When user press any key in sequencer piano it will play some audio file and and that audio file will continue to play in loop until user release the key. But that loop will be crossfade to itself.

I am using AEAudioFilePlayerModule for looping but not sure how to crossfade audio file with this class.

Explanation of Cross fade :

Start/End: This setting allows me to choose where in the audio file I want the app to constantly loop so that if user taps+holds note down for a long time, the audio will sound continuously until the user releases his finger.

XFade: This function (crossfade) allows me to chose how to fade between the end and start of the audio loop. This is good so
that the sound will loop smoothly. Here, 9999 is set. So at about 5k samples before the 200k end point, the audio for this note
will begin to fade away and at the same time, the audio loop starting at 50k samples will fade in for a duration of about 5k samples (1/2 the XFade amount).

Please help.

Thank you.

Comments

  • Hi @pratik. I'm afraid you'll need to write your own player (or adapt the current one) for crossfading if you want this behaviour; the built-in player only does a microfade upon play and stop, not at the loop boundary.

  • Thanks for reply Michael :smile:

    can you give me the idea in brief on how create this player with AEAudioFilePlayerModule ?

  • It'd be quite a long answer, I'm afraid, and very technical, involving expanding the play region either side and buffering the outer parts to crossfade into the inner parts. I don't really have the resources to help you there, I'm afraid.

  • I am working on cross fade player and I am using AEAudioFilePlayerModule for it

    but the currently problem is when I create the AEAudioFilePlayerModule object with completion block it is not actually released later.

    Even i tried to nil it's object as well. but no luck.

    Check the code sample.

    - (void)playPlayer1
    {
      if(isPlaying)
      {
        __weak XMCrossFadeModulePlayer * weakSelf = self;
    
        AEAudioFilePlayerModule *sampler1 = [[AEAudioFilePlayerModule alloc] initWithRenderer:subrenderer URL:_url error:NULL];
        sampler1.loop = NO;
    
          if(_loopCount==-1)
          {
            sampler1.regionStartTime = 0;
            sampler1.regionDuration = audioDuration - _audioEndLoopDuration;
            sampler1.startCrossFadeFrames = 10;
          }
          else
          {
            sampler1.startCrossFadeFrames = (UInt32)((_crossFadeFrames)/2);
            sampler1.regionStartTime = _audioStartLoopDuration;
            sampler1.regionDuration = _loopRegionDuration;
          }
    
            sampler1.endCrossFadeFrames = (UInt32)((_crossFadeFrames)/2);
            sampler1.fadeSeconds = _fadeSeconds/1000; // Microfade a little, to avoid clicks when turning on/off in the middle
    
        //AEAggregatorModule * aggregator = [[AEAggregatorModule alloc] initWithRenderer:subrenderer];
        //aggregator.modules = [NSArray arrayWithObjects:sampler1,self.audioFilePlayerModule2, nil];
          [self.aggregator addModule:sampler1];
          //self.playerValue.objectValue = self.aggregator;
    
          __block  __weak AEAudioFilePlayerModule * weakSampler = sampler1;
    
        sampler1.completionBlock = ^{
           // NSLog(@"finished");
    
            [weakSelf.aggregator removeModule:weakSampler];
            self.playerValue.objectValue = weakSelf.aggregator;
    
            if(weakSampler.isAudioPlaying)
            [weakSelf playPlayer1];
    
            weakSampler = nil;
        };
          if(_loopCount==-1)
              [sampler1 playAtTime:startTime+AEHostTicksFromSeconds(0)];
          else
          {
              _loopCount++;
              [sampler1 playAtTime:startTime+AEHostTicksFromSeconds(_audiofadeStartDuration+_loopCount*_audioloopfadeStartDuration)];
          }
          self.audioFilePlayerModule1 = sampler1;
      }
    
    }
    
  • edited June 2016

    Oh - are you using the latest version, from Github? There was indeed a retain cycle, but that should be fixed now.

    edit: I notice this:

            self.playerValue.objectValue = weakSelf.aggregator;
    

    That's going to cause your own retain loop, I'm afraid - you're gonna want to use weakSelf instead of self there.

  • Thank you so much.

Sign In or Register to comment.