Register
Handmade Hero»Forums»Code»day 19 sound problem
Roman
15 posts

Roman Shvayko.I love low-level programming and games.

day 19 sound problem
2 weeks, 5 days ago Edited by Roman on July 26, 2020, 5:53 p.m. Reason: Initial post
Hi guys. I am at 19 ep handmade hero. Casey fixed sound lagging by increasing latency. When I try increase latency it doesn't change anything.
Why? My delta between write cursor and play cursor 5292 Casey said so big number is bad why? My framerate is 60.
Here is all sound code. Thanks in advance. (Actually my english is bad)
  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
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
internal void
fillSoundBuffer(Sound_output *soundOutput, Game_sound_output *sourceBuffer,DWORD byteToLock,DWORD bytesToWrite)
{


  VOID *region1;
  DWORD region1Size;
	      
  VOID *region2;
  DWORD region2Size;
		  
  gSecondaryBuffer->Lock(
			 byteToLock,
			 bytesToWrite,
			 &region1,&region1Size,
			 &region2,&region2Size,
			 DSBLOCK_FROMWRITECURSOR
			 );

  s16 *sampleSource  = sourceBuffer->samples;
  s16 *samplesDest = (s16*)region1;
  DWORD region1SampleCount = region1Size / 4;
  for(DWORD sampleIndex = 0; sampleIndex < region1SampleCount; sampleIndex++)
    {
      *samplesDest++ = *sampleSource++;
      *samplesDest++ = *sampleSource++;
      soundOutput->runningSampleIndex++;
    }
  
  
  DWORD region2SampleCount = region2Size / 4;
  samplesDest = (s16*)region2;
  for(DWORD sampleIndex = 0; sampleIndex < region2SampleCount; sampleIndex++)
    {    
      *samplesDest++ = *sampleSource++;
      *samplesDest++ = *sampleSource++;
      soundOutput->runningSampleIndex++;
    }
  gSecondaryBuffer->Unlock(region1, region1Size, region2,  region2Size);
}



main()
{
	  Sound_output soundOutput;	  
	  soundOutput.samplesPerSecond = 44100;
	  soundOutput.secondaryBufferSize = soundOutput.samplesPerSecond  * (sizeof(s16)*2);	  
	  soundOutput.hz = 256;
	  soundOutput.runningSampleIndex = 0;
	  soundOutput.wavePeriod  = soundOutput.samplesPerSecond / soundOutput.hz;
	  soundOutput.latencyCount = 4*(soundOutput.samplesPerSecond / 60);

 s16 *soundBuffer = (s16*)VirtualAlloc(0, soundOutput.secondaryBufferSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	  clearSoundBuffer(&soundOutput);
	  gSecondaryBuffer->Play(0, 0,DSBPLAY_LOOPING);

while(gameIsRunning)
{

	      DWORD targetCursor = 0;
	      DWORD byteToLock   = 0;
	      DWORD bytesToWrite = 0;
	      
	      if(soundIsValid)
		{
		  byteToLock = ((soundOutput.runningSampleIndex*4) % soundOutput.secondaryBufferSize);
		  targetCursor = ((lastPlayCursor + (soundOutput.latencyCount*4))
				  % soundOutput.secondaryBufferSize);
		  
		  if(byteToLock > targetCursor)
		    {
		      bytesToWrite = (soundOutput.secondaryBufferSize - byteToLock);
		      bytesToWrite += targetCursor;
		    }
		  else
		    {
		      bytesToWrite = targetCursor - byteToLock;
		    }
	      }



	      Game_sound_output gameSoundOutput = {};
	      gameSoundOutput.samplesPerSec = 44100;
	      gameSoundOutput.samplesToOutput = bytesToWrite / 4;
	      gameSoundOutput.samples = soundBuffer;

 gameUpdateAndRender(&gameFramebuffer, newInput, &gameMemory, &gameSoundOutput);	


#if 1	      	      	      
	      if(soundIsValid)
		{
#if DEBUG
		  DWORD playCursor;
		  DWORD writeCursor;
		  gSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor);
		  char buffer[256];
		  _snprintf_s(buffer, sizeof(buffer),"LPC:%u BTL:%u TC:%u: BTW:%u  PC:%u WC:%u\n",
			      lastPlayCursor, byteToLock, targetCursor, bytesToWrite, playCursor, writeCursor);
		  OutputDebugStringA(buffer);
#endif		  
		  
		  fillSoundBuffer(&soundOutput, &gameSoundOutput,byteToLock, bytesToWrite);
		}
#endif

	      DWORD playCursor;
	      DWORD writeCursor;
	      if(SUCCEEDED(gSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor)))
		{
		  lastPlayCursor = playCursor;
		  if(!soundIsValid)
		    {
		      soundOutput.runningSampleIndex = writeCursor / 4;
		      soundIsValid = true;
		    }
		}
	      else
		{
		  soundIsValid = false;		  
		}

}
}
Simon Anciaux
855 posts
day 19 sound problem
2 weeks, 4 days ago
One difference in your code is that you pass DSBLOCK_FROMWRITECURSOR (which value is 1) to DirectSoundBuffer::Lock while Casey passes 0. Which means that in your code, the first parameter is ignored according to the documentation.

Apart from that, have you tried compiling and running Casey's code to see if it works on your machine ?

You can search the forums for thread with "day 19" or "DirectSound" in the name, there are often questions about that and you might find valuable information there.
Roman
15 posts

Roman Shvayko.I love low-level programming and games.

day 19 sound problem
2 weeks, 4 days ago
Thank you! DSBLOCK_FROMWRITECURSOR was causing the problem.