# Sound RAM usage

I decided to add streaming sound support to my game and to my surprise… when I add this:

#define PROJ_ENABLE_SOUND       1
#define PROJ_STREAMING_MUSIC    1
#define PROJ_AUD_FREQ           11025


The linker says that RAM is overflowed:

section .bss' will not fit in region Ram0_32'
region Ram0_32' overflowed by 1340 bytes


According to the ELF file, without sound I use 70.3% of RAM, 77.7% with PROJ_ENABLE_SOUND and 95.4% with PROJ_ENABLE_SYNTH. Almost all RAM is used for the framebuffer. Am I limited to synth sound then? I wanted to use both streamed music and some synth sounds, but I’ll have to rethink that

Streaming sound uses … afaicr … 4 buffers

It probably does work with less, esp. now that many things are optimized

So dont despair! We’ve had worse situations here (ahem, l’Abbaye ahem)!

2 Likes

Speaking of which @manuelsagra , your game would be perfect for TAS mode… the bg gfx consist of static tiles and cars could be sprites. You could use way, way less RAM I believe

1 Like

#define PROJ_HIGH_RAM HIGH_RAM_MUSIC

3 Likes

@FManga your responses are always like magic. That seems to compile and the ELF shows 92.4% RAM usage with this settings:

#define PROJ_SCREENMODE         15
#define PROJ_ENABLE_SOUND       1
#define PROJ_ENABLE_SYNTH       1
#define PROJ_STREAMING_MUSIC    1
#define PROJ_AUD_FREQ           22050
#define PROJ_HIGH_RAM HIGH_RAM_MUSIC


@jonne I’ll take a look at TAS mode. You’re right, my game is basically a mix of tiles of sprites, except the sidebar.

2 Likes

That’s still pretty full, it might have some stability problems when you run it.

I use these in MIB game to reduce synth buffer usage:
#define PROJ_SYNTH_MAXBLOCKS 7
#define PROJ_SYNTH_MAXPATCHES 3

But it really depends on how many channels you want to use in synth sounds etc.

2 Likes

We really need these things documented.

The number of times I look in on a question and the solution is ‘define these macros that I’ve never heard of and never knew existed’ is frankly disturbing.

4 Likes

Absolutely!

I knew of this one … as I happened to have the same issue previously but had never seen these two …

2 Likes

There’s many ways to look at this problem. Yes, it could be fixed by better documentation. It could also be fixed by making it the default.
It can also not be fixed, and simply considered a feature instead. From a gamasutra article:

# The Programming Antihero

I was fresh out of college, still wet behind the ears, and about to enter the beta phase of my first professional game project – a late-90s PC title. It had been an exciting rollercoaster ride, as projects often are. All the content was in and the game was looking good. There was one problem though: We were way over our memory budget.

Since most memory was taken up by models and textures, we worked with the artists to reduce the memory footprint of the game as much as possible. We scaled down images, decimated models, and compressed textures. Sometimes we did this with the support of the artists, and sometimes over their dead bodies.

We cut megabyte after megabyte, and after a few days of frantic activity, we reached a point where we felt there was nothing else we could do. Unless we cut some major content, there was no way we could free up any more memory. Exhausted, we evaluated our current memory usage. We were still 1.5 MB over the memory limit!

At this point one of the most experienced programmers in the team, one who had survived many years of development in the “good old days,” decided to take matters into his own hands. He called me into his office, and we set out upon what I imagined would be another exhausting session of freeing up memory.

Instead, he brought up a source file and pointed to this line:

static char buffer[1024*1024*2];

“See this?” he said. And then deleted it with a single keystroke. Done!

He probably saw the horror in my eyes, so he explained to me that he had put aside those two megabytes of memory early in the development cycle. He knew from experience that it was always impossible to cut content down to memory budgets, and that many projects had come close to failing because of it. So now, as a regular practice, he always put aside a nice block of memory to free up when it’s really needed.

He walked out of the office and announced he had reduced the memory footprint to within budget constraints – he was toasted as the hero of the project.

As horrified as I was back then about such a “barbaric” practice, I have to admit that I’m warming up to it. I haven’t gotten into the frame of mind where I can put it to use yet, but I can see how sometimes, when you’re up against the wall, having a bit of memory tucked away for a rainy day can really make a difference. Funny how time and experience changes everything.

- Noel Llopis

4 Likes

That was a great story!

Have you noticed, how I have been tucking away memory in random places? Oh they joy that I see every time someone cuts the ram overhead of PokittoLib!

(edit: yes, completely intentional!..)

1 Like

An entertaining story, but not something that should be repeated.

The title of the article is “Dirty Coding Tricks”, and that’s precisely what that is - a dirty trick.

/// @def PROJ_HIGH_RAM
/// @brief No idea what it does
///
/// Can be defined as one of several values, including:
/// * HIGH_RAM_MUSIC
/// * Presumably something else

/// @def PROJ_SYNTH_MAXBLOCKS
/// @brief No idea what it does. Default value is I don't know.
///
/// Something to do with sound?
/// Should evaluate to an integer expression after macro replacement has occurred.

/// @def PROJ_SYNTH_MAXPATCHES
/// @brief No idea what it does. Default value is I don't know.
///
/// Something to do with sound?
/// Should evaluate to an integer expression after macro replacement has occurred.


Perhaps someone who actually knows what it does could write the rest, and then we’ll figure out where best to put it - whether all project macros should be documented in a single header somewhere, or whether they should be documented closer to the part of the code they actually affect.

That pattern can of course be used for all project macros.
Macros are particularly difficult to document though,
not just because they have to be documented explicitly with a @def/\def` command,
but also because there’s a usage difference between macros - some change behaviour by merely existing while others are actually evaluated.

I can’t form an opinion on this without knowing what the macros actually affect,
so I’ll either wait until it’s documented to form an opinion or let other people debate whether or not it should be the default.

Of the three options, I’m alright with whichever is chosen as all three have their flaws (Fix docs: @Pharap is the only one who reads docs; Change default: “Why won’t my USB code work?!”; Call it a feature: it is a dirty hack) and their merits (Fix docs: at least we’d be able to point people to it when the problem appears; Change default: problem will appear less frequently; Call it a feature: this is a hobby and dirty hacks are fun).

I’d also point out that they’re not mutually exclusive (can change the default and fix docs).

I do. Extensively.

When I was first learning C# I’d have MDN open almost constantly,
gradually learning what all the classes do and what their functions were.

Even now, https://en.cppreference.com is probably my favourite website,
and I refer to it rather than digging through the actual C++ standard.

3 Likes

Touche. Fixed my previous comment.

2 Likes

I know that the last comment is jocular, but I feel the need to chime in here.

I would greatly appreciate some documentation as well! I’m trying to wrap up my first Pokitto project right now, and some combination of fighting with preprocessor directives and walking through signatures/implementation for PokittoSound is pretty discouraging (especially in the context of EmBitz).

I’m not much for forums, but I felt strongly enough to make an account so that I could +1 Pharap’s point…

6 Likes

Ok. I will do some writing on sound into the guidebook. I’ll post here when I’m done

1 Like