Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Audio Block Allocation Question

  1. #1
    Member
    Join Date
    Aug 2016
    Location
    Texas
    Posts
    31

    Audio Block Allocation Question

    I'm working on a custom audio library object, and have changed AUDIO_BLOCK_SIZE from 128 to 16 samples in my project to improve some latency issues. That all works just fine.

    This leads me to several questions that hopefully Paul or any other knowledgeable person might be able to answer.

    If I allocate() a block, will this block size be 16 or 128 samples in size?

    The reason I ask, is in one case my code was reading more than 16 values from EEPROM and writing to the single block I had allocated(), and I was also reading back these values correctly from that single pointer for up to 64 sample memory locations.

    So I need to ask, is the allocated() block always a defined number of memory locations like 128, or does this size change and equal that called out in the AUDIO_BLOCK_SIZE declaration?

    If the allocated() block is in fact being reduced to 16 memory locations in my case, can someone please advise me on how to allocate() more blocks of this same size and have them be located sequentially one after the other in memory/code, when the code is compiled. For instance if my first allocated() block is called "tempCalc", would allocating additional blocks called "tempCalc2", "tempCalc3", and "tempCalc4" place the later right after "tempCalc" in memory?

    I'm curious how the compiler arranges all allocated blocks in memory. Does it go line by line in your code placing one after the other, or does is it arrange them alphabetically, or is it possible that each block will simply be wherever in memory?

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,784
    Quote Originally Posted by FRS View Post
    I'm working on a custom audio library object, and have changed AUDIO_BLOCK_SIZE from 128 to 16 samples in my project to improve some latency issues. That all works just fine.
    There is no AUDIO_BLOCK_SIZE. AudioStream.h defines AUDIO_BLOCK_SAMPLES. Yeah, this is a minor detail, but details matter...

    Each audio block is actually this: (defined about 20 lines below in the same header file)

    Code:
    typedef struct audio_block_struct {
    	uint8_t  ref_count;
    	uint8_t  reserved1;
    	uint16_t memory_pool_index;
    	int16_t  data[AUDIO_BLOCK_SAMPLES];
    } audio_block_t;
    If I allocate() a block, will this block size be 16 or 128 samples in size?
    As you can see in this typedef, the block will actually be 4 bytes of overhead, followed by an array of 16 bit samples which is the number defined by AUDIO_BLOCK_SAMPLES.

    The reason I ask, is in one case my code was reading more than 16 values from EEPROM and writing to the single block I had allocated(), and I was also reading back these values correctly from that single pointer for up to 64 sample memory locations.
    Sounds like you need to adapt your code to actually allocate 4 blocks and place the samples into them.

    If the allocated() block is in fact being reduced to 16 memory locations in my case, can someone please advise me on how to allocate() more blocks of this same size and have them be located sequentially one after the other in memory/code, when the code is compiled.
    From the typedef, it should be pretty obvious you'll have each array of samples interleaved with the 4 byte overhead that accompanies each block.

    It sounds like you want to have your cake and eat it too. Well, you can't. If you've decreased the block size to get low latency, then you need to make sure all the code you're using can properly adapt to the block size which is a choice of your own making.

    Most (but not all) of the audio library objects do adapt down to 16 sample block size. If you're using any that don't, or writing your own, you'll need to redesign them to work with the block size you've chosen. There isn't any sort of trick you can use to cheat this decision you've made.


    I'm curious how the compiler arranges all allocated blocks in memory.
    When you put AudioMemory(number) in your setup function, they're allocated as one big static array.

    This is also in AudioStream.h, where you edit AUDIO_BLOCK_SAMPLES

    Code:
    #define AudioMemory(num) ({ \
    	static DMAMEM audio_block_t data[num]; \
    	AudioStream::initialize_memory(data, num); \
    })
    Does it go line by line in your code placing one after the other, or does is it arrange them alphabetically, or is it possible that each block will simply be wherever in memory?
    They will always physically be within this big static array. But which ones are "allocated" to various objects in the audio library changes dynamically. You can find more static variables within the AudioStream base class which are used to track which blocks are allocated, and of course those 4 overhead bytes are used for tracking usage too. I don't recommend fiddling with that memory allocation stuff, but the code is all open source if you really want to play.

    Just know nothing about this system is designed to let you cheat the block size. If you choose a small block size, that's your decision and you need to deal with it in your code (or any of the audio lib code which doesn't scale).

  3. #3
    Member
    Join Date
    Aug 2016
    Location
    Texas
    Posts
    31
    Thanks Paul for all your help!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •