From AudioBlock to AudioSampleBuffer/AudioChannelInfo

hi all,

I can’t seem to find a way to convert an AudioBlock into a AudioSourceChannelInfo. My use case is calling AudioThumbnail::addBlock from within void process (const ProcessContextReplacing<float>& context).

Did i miss something obvious, or am I looking at it from the wrong side?

thanks, piem

1 Like

I’m also having this issue.

Is there a way to call a function that expects an AudioBuffer on an AudioBlock without copying?

From within a Synthesiser class, I’m able to accomplish what I want by doing…

    /** Processes the input and output buffers supplied in the processing context. */
    template <typename ProcessContext>
    void process (const ProcessContext& context) noexcept
    {
        auto&& inBlock  = context.getInputBlock();
        auto&& outBlock = context.getOutputBlock();
        
        jassert (inBlock.getNumChannels() == outBlock.getNumChannels());
        jassert (inBlock.getNumSamples() == outBlock.getNumSamples());
        
        auto len         = inBlock.getNumSamples();

        const juce::MidiBuffer dummyMidi;
        buf.clear();
        renderNextBlock(ab, dummyMidi, 0, (int)len);
        AudioBlock<float> b(buf);
        outBlock.add(b);
    }

…where buf is an AudioBuffer, but I’d like to avoid the copy.

1 Like
    // Create an AudioBuffer and fill it with data

    AudioBuffer<float> buffer (2, 8);

    for (int c = 0; c < buffer.getNumChannels(); ++c)
        for (int s = 0; s < buffer.getNumSamples(); ++s)
            *buffer.getWritePointer (c, s) = s;

    // buffer contents: {{ 0, 1, 2, 3, 4, 5, 6, 7 },
    //                   { 0, 1, 2, 3, 4, 5, 6, 7 }}

    // Create an AudioBlock referencing a subset of the AudioBuffer's data. This
    // only references the data in `buffer` - there is no copying.

    AudioBlock<float> block { buffer, 4 };

    // block contents: {{ 4, 5, 6, 7 },
    //                  { 4, 5, 6, 7 }}

    // We can't take this view of the data and create an AudioBlock because the
    // data is indexed differently (with an offset). However, if we know the maximum
    // number of channels beforehand we can create an AudioBlock with low overhead
    // and no allocation.

    constexpr int maxNumChannels = 32;
    float* channels[maxNumChannels];

    for (size_t c = 0; c < block.getNumChannels(); ++c)
        channels[c] = block.getChannelPointer (c);

    AudioBuffer<float> newBuffer { channels, block.getNumChannels(), block.getNumSamples() };
2 Likes

excellent, thank you @t0m!