|   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,
			 ®ion1,®ion1Size,
			 ®ion2,®ion2Size,
			 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;		  
		}
}
}
 |