Sequencing multiple audio files on a single channel

edited April 2016

Hi there, I'm working on a DAW-like sequencer and trying to allow arbitrary audio files to be scheduled on each track. I'd like to keep a track limited to one channel. Is there a good strategy for scheduling playback with something like this? All I've been able to find is making a separate AESequencerChannel for each audio file and then scheduling those individually, which is obviously a bad solution. Thanks!

Comments

  • I've not announced it widely yet (going to get into that over the next days), but you might want to investigate TAAE2: https://github.com/TheAmazingAudioEngine/TAAE2

  • Awesome! I will check it out

  • Having a tough time getting any scheduling to work. When I try this....

    [testPlayer playAtTime:AEHostTicksFromSeconds(timeVal)];

    ...it only works if timeVal is 0. My understanding was that I run [output start:error] and it plays my file timeVal seconds later. Is that how this is supposed to work?

  • Ah never mind! Didn't realize the clock was already ticking... In case anyone else is confused, I needed to add AECurrentTimeInHostTicks() to the playtime

  • edited April 2016

    Got another question related to this: I'm able to sequence events, but I'm getting a very loud click when each file reaches its end (not the overlap point). Looping is off. There's no discontinuity in the audio files themselves. Any ideas here would be much appreciated (I'm completely new to non-matlab audio programming). Below is the start method in my audio controller... Thanks!

    - (BOOL)start:(NSError *__autoreleasing *)error {
        // Request a 128 frame hardware duration, for minimal latency
        AVAudioSession * session = [AVAudioSession sharedInstance];
        [session setPreferredIOBufferDuration:128.0/session.sampleRate error:NULL];
    
        // Start the session
        if ( ![self setAudioSessionCategory:error] || ![session setActive:YES error:error] ) {
            return NO;
        }
    
        //Load test urls
        NSMutableArray *urls = [[NSMutableArray alloc]initWithCapacity:16];
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"Low Tom0005" withExtension:@"aif"];
        [urls addObject:url];
        url = [[NSBundle mainBundle] URLForResource:@"KickDrum0017" withExtension:@"aif"];
        [urls addObject:url];
        url = [[NSBundle mainBundle] URLForResource:@"Closed Hihat0001" withExtension:@"aif"];
        [urls addObject:url];
    
    
        //    Make NSarray of players
    
    
        for (TimePoint *tp in _trackEvents) {
            //Check for an assigned clip on the timepoint (i.e. clipnumber is not null)
    
            if (tp.clipNumber) {
    
                //Load url for current clip number
                NSURL *url = [urls objectAtIndex:tp.clipNumber];
    
                AEAudioFilePlayerModule *filePlayer = [[AEAudioFilePlayerModule alloc] initWithRenderer:_renderer URL:url error: NULL];
    
                double playTime = AECurrentTimeInHostTicks() + AEHostTicksFromSeconds(tp.time);
                [filePlayer playAtTime:playTime];
    
                //Add fileplayers to NSMutableArray,
                [_players addObject:filePlayer];
    
            }
        }
    
    
        [_playersArray updateWithContentsOfArray:_players];
    
        AEArray * finalPlayersArray = [AEArray new];
        finalPlayersArray = _playersArray;
    
    
        _renderer.block = ^(const AERenderContext * _Nonnull context) {
            //         Run all the players
    
            AEArrayEnumerateObjects(finalPlayersArray, AEAudioFilePlayerModule *, player, {
                if ( AEAudioFilePlayerModuleGetPlaying(player) ) {
    
                    AEModuleProcess(player, context);
    
                    // Put on output
                    AEBufferStackMixToBufferList(context->stack, 0, 0, YES, context->output);
                    AEBufferStackPop(context->stack, 1);
                }
            });
    
    
        };
    
        return [self.output start:error];
    }
    
  • Hey @daliparton - sorry about the delay. Hmm, that's weird; any chance of providing a little sample app that demonstrates this? I don't think I can diagnose blind on this one, and your code looks good to me.

Sign In or Register to comment.