TAAE2: external buffers on stack

Would it be useful to be able to push external buffers on the stack? e.g. a module manages its own scratchbuffers and pushes them as needed.
Ramifications? maybe:
1. modules need to exist as long as the buffers are part of the stack.
2. bufferlengths? although these are always set to 4096 frames as previously discussed.

Comments

  • Interesting idea...I'm inclined towards 'no', just because of the added complexity involved. I think the increase in technical debt might not warrant the optimisation (basically saving a buffer copy each render).

  • I had a similar thought: Instead of doing any allocation of buffers in the stack, the stack could just hold pointers. The actual buffers would be owned by each module. This is the way it works in a way already for many AU's, you can pass NULL for mData and it will provide its own buffer which is guaranteed to be valid until the next call (or until deinit).

    It would simplify the buffer stack, since it only needs to have room for pointers, but it would also mean there can be no in-place processing. Or maybe there can, and only modules that pushes more buffers than it pops would push their own buffers, effects could still process in place.

    But I don't know exactly if this would be an improvement or not :)

  • Well, thinking out loud:
    It would seem that perhaps RPN in audio works slightly different from our previous assessment:
    1. you first create the main controller object (in order to not use the word context) and it pushes the outputbuffer on the stack
    2. you then "activate" a module which pushes its inputbuffers on the stack
    3. you then "activate" a generator module to fill the inputbuffers
    4. you then flush the result somehow

    "activate" probably means something like "push a module on the module stack", the module then pushes its buffers on the buffer stack.

    Flushing might be an operation per module.

    To me it still comes down to the previous question: **what problem are we trying to solve with a bufferstack? **
    and I mean what would be the elevatorpitch? Why would I totally want to transfer my codebase to the new TAAE version?

  • Note also that if the module manages its own buffers, it would reduce the memory-strain a lot, since if you just want to move mic input to a file, you don't create an entire bufferstack of which you only use the top two lists for example.

  • edited April 2016

    Or: all modules are generator modules which push their resultbuffer on the stack and expect enough buffers to be available for input when asked to render. This way the output module is the last module that needs to be pushed, since it will push the outputbuffer on the stack and then mixes the stack down to it and moves the result to HW...

  • Cool

    Sketch:

    OSStatus RenderLoop(AEStack *stack, UInt32 frameCount)
    {
        // stack is empty
    
        // render micA into its buffer and push to stack
        // render micB into its buffer and push to stack
        AEOperationRun(micA_Operation, stack, frameCount);
        AEOperationRun(micB_Operation, stack, frameCount);
    
        // stack contains two buffers: micB, micA
    
        // sum all stack buffers into sum_operation buffer
        AEOperationRun(sum_Operation, stack, frameCount);
    
        // top of stack is sum_operation buffer = final buffer
        AEStackCopyBufferAtIndex(stack, 0);
    
        /* 
            top of stack is final buffer with refcount of 2
            we can use refcounts since stack is assumed read-only
        */
    
        // write to file
        AEOperationRun(file_output_Operation, stack, frameCount);
    
        // monitor over speakers
        AEOperationRun(hw_output_Operation, stack, frameCount);
    
        // stack is empty
    }
    
    
    OSStatus AEOperationRun(AEOperation *op, AEStack *stack, UInt32 frameCount)
    {
        AEOperationBlockPtr *blockPtr = AEOperationGetBlockPtr(op);
        OSStatus result = blockPtr(op, stack, frameCount);
        if (result == noErr)
        {
            AudioBufferList *list = AEOperationGetOutputBuffer(op);
            AEStackPushBuffer(stack, list);
        }
    
        return result;
    }
    
    OSStatus myMicOperationBlock(AEOperation *op, AEStack *stack, UInt32 frameCount)
    {
        AudioBufferList *dstList = AEOperationGetOutputBuffer(op);
    
        AudioUnitRender(bla bla , dstList);
    }
    
    
    OSStatus mySumOperationBlock(AEOperation *op, AEStack *stack, UInt32 frameCount)
    {
        AudioBufferList *dstList = AEOperationGetOutputBuffer(op);
        AudioBufferList *srcList = AEStackGetBufferAtIndex(stack, 0);
        while (srcList != nil)
        {
            DSPAudioBufferListSumBuffers(srcList, dstList, frameCount);
            AEStackPopBuffer(stack);
            srcList = AEStackGetBufferAtIndex(stack, 0);
        }
    }
    
    AEStackPopBuffer:
    reduce refcount by 1,
    if refcount is zero, remove from stack
    
  • Could we have a little more commentary? =)

  • @Michael said:
    Could we have a little more commentary? =)

    It's just a rough outline which I quickly wrote in a branch where it shouldn't be, so I decided to copy it here instead as a note-to-self. Still chewing on it though...

  • Michael. What method to get a existing buffers from the stack

Sign In or Register to comment.