Hi everyone. I do breakout clone and use handmade hero
series.Now I have memory bug. So, I have done sound mixer like casey did in 140 episode. I trigger a brick collision sound when ball colides with bricks.
| if(checkCollision(ball.pos.x, ball.pos.y,
ball.pos.x + gameState->ballWidth, ball.pos.y + gameState->ballHeight,
brick->pos.x, brick->pos.y,
brick->pos.x + (gameState->brickWidth-1.0f), brick->pos.y+(gameState->brickHeight-1.0f)))
{
// NOTE(shvayko): collision sound for brick-ball
playSound(gameState, "bloop_00.wav");
}
|
So, every time I do this call my memory grows up and I don't know why cuz I use transient memory allocation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 | void gameGetSoundSamples(Game_Memory *gameMemory, Game_sound_output *gameSoundBuffer)
{
Game_State *gameState = (Game_State*)gameMemory->permanentStorage;
Transient_state *transState = (Transient_state *)gameMemory->transientStorage;
Temp_memory mixerMemory = beginTempMemory(&transState->transArena);
f32 *realChannel0 = (f32*)pushArray(&transState->transArena, f32, gameSoundBuffer->samplesToOutput);
f32 *realChannel1 = (f32*)pushArray(&transState->transArena, f32, gameSoundBuffer->samplesToOutput);
{
f32 *dest0 = realChannel0;
f32 *dest1 = realChannel1;
for(DWORD sampleIndex = 0;
sampleIndex < gameSoundBuffer->samplesToOutput;
sampleIndex++)
{
*dest0++ = 0;
*dest1++ = 0;
}
}
// NOTE(shvayko): sound mixer
for(Playing_sound **playingSoundPtr = &gameState->firstPlayingSound;
*playingSoundPtr; )
{
Playing_sound *playingSound = *playingSoundPtr;
bool soundIsFinished = false;
if(playingSound->loadedSound.sampleCount)
{
f32 *dest0 = realChannel0;
f32 *dest1 = realChannel1;
f32 volume0 = playingSound->volume[0];
f32 volume1 = playingSound->volume[1];
u32 samplesToMix = gameSoundBuffer->samplesToOutput;
u32 samplesRemaining = playingSound->loadedSound.sampleCount - playingSound->samplesPlayed;
if(samplesToMix > samplesRemaining)
{
samplesToMix = samplesRemaining;
}
for(DWORD sampleIndex = playingSound->samplesPlayed;
sampleIndex < playingSound->samplesPlayed + samplesToMix;
sampleIndex++)
{
f32 sampleValue = playingSound->loadedSound.samples[0][sampleIndex];
*dest0++ = volume0 * sampleValue;
*dest1++ = volume1 * sampleValue;
}
playingSound->samplesPlayed += samplesToMix;
soundIsFinished = (playingSound->samplesPlayed == playingSound->loadedSound.sampleCount);
}
// NOTE(shvayko): sound gets killed
if(soundIsFinished)
{
*playingSoundPtr = playingSound->next;
playingSound->next = gameState->firstFreePlayingSound;
gameState->firstFreePlayingSound = playingSound;
}
else
{
playingSoundPtr = &playingSound->next;
}
}
{
f32 *source0 = realChannel0;
f32 *source1 = realChannel1;
s16 *sampleDest = gameSoundBuffer->samples;
for(DWORD sampleIndex = 0; sampleIndex < gameSoundBuffer->samplesToOutput; sampleIndex++)
{
*sampleDest++ = (s16)(*source0++);
*sampleDest++ = (s16)(*source1++);
}
}
endTempMemory(mixerMemory);
checkArena(&transState->transArena);
//gameSoundOutput(gameSoundBuffer,gameMemory);
|
I have been debugging and all seems ok. At beggining I push memory in transient storage and then pop it .
Here playSound function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | internal Playing_sound*
playSound(Game_State *gameState, char *music)
{
if(!gameState->firstFreePlayingSound)
{
gameState->firstFreePlayingSound = (Playing_sound*)pushStruct(&gameState->levelArena, Playing_sound);
gameState->firstFreePlayingSound->next = 0;
}
Playing_sound *playingSound = gameState->firstFreePlayingSound;
gameState->firstFreePlayingSound = playingSound->next;
playingSound->volume[0] = 1.0f;
playingSound->volume[1] = 1.0f;
playingSound->loadedSound = loadWAVEFile(music);
playingSound->samplesPlayed = 0;
playingSound->next = gameState->firstPlayingSound;
gameState->firstPlayingSound = playingSound;
return playingSound;
}
|
Also I don't understand the point why we return Playing_sound* but when we call this function no one takes it.
Memory stuff ->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 | internal void
initArena(Memory_arena *arena, size_t size, u8 *base)
{
arena->base = base;
arena->used = 0;
arena->size = size;
arena->tempCount = 0;
}
#define pushStruct(arena, type) _pushSize(arena,sizeof(type))
#define pushArray(arena, type, num) _pushSize(arena, sizeof(type)*num)
inline void*
_pushSize(Memory_arena *arena, size_t size)
{
void *result = (arena->base + arena->used);
arena->used += size;
return result;
}
inline Temp_memory
beginTempMemory(Memory_arena *arena)
{
Temp_memory result;
result.arena = arena;
result.used = arena->used;
arena->tempCount++;
return result;
}
inline void
endTempMemory(Temp_memory tempMemory)
{
Memory_arena *arena = tempMemory.arena;
assert(arena->used >= tempMemory.used);
arena->used = tempMemory.used;
arena->tempCount--;
}
inline void
checkArena(Memory_arena *arena)
{
assert(arena->tempCount == 0);
}
|
So, may be I misunderstand the point of transient storage or I have a bug? Thanks in advance!!! (Sorry for the poor english)