[Wiki]Everything there is to know about LibAudio

inline static uint16_t volume = 256;

1 Like

Thanks … that’s what I discovered with a little help. The volume is being applied, now its up to me to do the fade in and out stuff. But that’s ‘standard’ code that mere mortals like me are capable of :slight_smile:

Thanks again!

3 Likes

Have these changes been pushed yet?

Not sure if they should become part of the LibAudio library or not.

Either way, you can see how I used the code in Trials of Astarok. I simply fade to zero and back again as I swap themes.

Its also worth mentioning, that I am using a second @Fmanga trick that allows me to have the themes and sound effects sampled at one rate (16Khz in my case) and have others at a lower rate. The lower rate needs to be half / quarter of the full rate and I have used this to squeeze a sound effect in at 8Khz to save memory. The function also allows you to specify a volume for the sound effect between 0 - 255.

All good stuff!

3 Likes

Is there any way to detect when a sound effect is playing? (apologies if I have asked this before).

There isn’t, since the SFX8Source has no public methods. It’d be simple to add, though.

Somewhere after the public: line, add:

        template<u32 len = 0>
        bool isPlaying(const u8 (&data)[len]){
            return head >= data && head < data + len;
        }

Now, your game needs a reference to the sound effect source:
auto& source = Audio::play(soundEffect);

To check if it’s playing:
if (source.isPlaying(soundEffect)) { ... }.

5 Likes

Me again.

When I review the elf file after compiling something that uses LibAudio, I can see there is 1K being used in high RAM for the ‘audio_buffer’.

Can I access the rest of the RAM using the techniques used in this link? I am guessing there is approximately 3K there for the taking but I am not sure of the starting address of the free RAM.

I should add that you are using in my_settings.h:

#define PROJ_HIGH_RAM HIGH_RAM_MUSIC

Btw. Does the elf-viewer in Femto even show the high ram area?

The addresses of the high ram areas are as follows, 2k each:
constexpr uint32_t HIGH_RAM1 = 0x20000000;
constexpr uint32_t HIGH_RAM2 = 0x20004000;

But I do not know how much audio uses of that when HIGH_RAM_MUSIC is set? All? @FManga should know this better.

I think so …

The snippet above is after compilation with the #define PROJ_HIGH_RAM HIGH_RAM_MUSIC

Right … and if the 1K is in this area, can I assume its at the start of the first bank?

Even so, it would mean that there is 2K from 0x20000400 - 0x200007FF and a second bank of 2K from 0x20004000 to 0x200047FF. So, unfortunately, non-contiguous.

I don’t think that buffer is from LibAudio. I noticed it in PtaD and iirc it was in PokittoSound.

Iirc LibAudio only uses 512 bytes per channel, but I could be wrong.

Oh … if that is so, then I do not see that memory in the elf.

I am using 4 channels Audio::Sink<4, PROJ_AUD_FREQ> audio; so the 1024 would equal 256 bytes per channel if this audio_buffer was for LibAudio but if you see it in PtaD and you do not use LibAudio then I am not sure,

I am streaming music and graphics as well as sounds in memory, so maybe the 560 bytes for YAPFS::_fs and 256 bytes for filehandles was created for these. Not sure if they are in standard memory or not.

I do not believe high ram allocations are visible in elf because you cannot actually allocate variables in high ram :wink:

You just set a pointer to the high ram area which you happen to know is not used by anybody else.

That makes sense. If only I knew what was not being used :slight_smile:

I guess Felipe is busy so we need to dig into LibAudio codes ourselves to find out :slight_smile:

Yeah … guess I was looking for the lazy, easy answer.

This does not promise very good…

#define HIGH_RAM_MUSIC   2 // SRAM1/SRAM2 are enabled and used by music

I cannot find anywhere that high ram is really used for audio. I only found this in the LibAudio header file:


    inline constexpr u32 bufferCount = 2;

    extern "C" {
        inline volatile u32 audio_volume;
        inline volatile u32 audio_playHead;
        inline volatile u8 audio_state[bufferCount];
        inline u8 audio_buffer[512 * bufferCount];
    }

That looks like it always allocates 1k buffer in ram.
Does the define actually affect the ram usage at all?

#define PROJ_HIGH_RAM HIGH_RAM_ON => ram:88 %
#define PROJ_HIGH_RAM HIGH_RAM_OFF => ram:88 %
#define PROJ_HIGH_RAM HIGH_RAM_MUSIC => ram:88 %

There is no difference! Looks like the audio is no more using high ram for buffers (?).
Which is very confusing as the HIGH_RAM_MUSIC define still exists.

Sorry, only saw this conversation now.
HIGH_RAM_MUSIC was pre-LibAudio, when PokittoSound needed 4KB of RAM for buffers, which made sense to stash into the 4KB of high RAM.
LibAudio only needs 1KB of audio buffer (regardless of the number of channels), so it was a bit awkward to put it into a 2KB bank.

It’d be pretty simple to put the buffer into one of the banks:

  • Add -DAUDIO_BUFFER_ADDRESS=0x20000000 to the Pokitto C++ flags in project.json.
  • Enable the high ram banks using PROJ_HIGH_RAM HIGH_RAM_ON
  • Change inline u8 audio_buffer[512 * bufferCount]; into:
#ifndef AUDIO_BUFFER_ADDRESS
inline u8 audio_buffer[512 * bufferCount];
#else
inline u8* const audio_buffer = reinterpret_cast<u8*>(AUDIO_BUFFER_ADDRESS);
#endif
5 Likes

Thanks @fmanga, that is a nice solution and I think we should add it to the library itself.

If you think that’s a good idea, I will create a PR on your behalf if you like.

2 Likes