Absolutely lovin' working through the series, however I seem to have hit a point early on that's blocking me from going much further :( I'm wondering if anyone can offer me some advice?
I have the following function (win32WriteAudioBuffer), which I call (just once) to fill the audio buffer. (For the purposes of keeping the debugging simple, I don't call this within the game loop at the moment)
The buffer gets filled and the square wave audio loop plays perfectly, no cutting or anything. However, when I run the code, the Visual Studio debugger crashes probably 70% of the time. If I comment out the win32WriteAudioBuffer function, the Debugger never seems to crash. So there must be something buggy about my code, I just can't seem to figure out what!
I've verified that the 192,000 byte buffer gets filled from the first to the last byte - and never writes more than I expect it to, so I dont think it's that. However when I view the details of C:\Users\jon\AppData\Local\CrashDumps\devenv.exe.dmp, I get the following information:
1 2 3 4 5 6 7 8 9 | Dump Summary ------------ Dump File: devenv.exe.15424.dmp : C:\Users\jon\AppData\Local\CrashDumps\devenv.exe.15424.dmp Last Write Time: 29/04/2020 21:35:30 Process Name: devenv.exe : C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe Process Architecture: x86 Exception Code: 0xC0000005 Exception Information: The thread tried to read from or write to a virtual address for which it does not have the appropriate access. Heap Information: Not Present |
So it looks like i'm writing to/reading from something I shouldn't somewhere?
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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | internal_func void win32InitDirectSound(HWND window) { audioBuffer.bufferSuccessfulyCreated = FALSE; // Load the library HMODULE libHandle = LoadLibrary("dsound.dll"); if (!libHandle) { OutputDebugString("Could not load DirectSound DLL (dsound.dll)"); return; } // Create the struct audioBuffer.noOfChannels = 2; audioBuffer.bitsPerSample = 16; audioBuffer.samplesPerSecond = 48000; audioBuffer.bytesPerSample = ((audioBuffer.bitsPerSample * audioBuffer.noOfChannels) / BITS_PER_BYTE); audioBuffer.secondsWorthOfAudio = 1; audioBuffer.bufferSizeInBytes = ((audioBuffer.bytesPerSample * audioBuffer.samplesPerSecond) * audioBuffer.secondsWorthOfAudio); uint8_t blockAlignment = audioBuffer.bytesPerSample; // Result variable for the various function call return checks. HRESULT res; DirectSoundCreateDT *DirectSoundCreateAddr = (DirectSoundCreateDT*)GetProcAddress(libHandle, "DirectSoundCreate"); if (!DirectSoundCreateAddr) { OutputDebugString("DirectSoundCreate not in dsound.dll. Malformed DLL?"); return; } DirectSoundCreateDT *DirectSoundCreate = DirectSoundCreateAddr; LPDIRECTSOUND directSound; res = DirectSoundCreate(NULL, &directSound, NULL); if (FAILED(res)){ OutputDebugString("Could not create direct sound object"); return; } res = directSound->SetCooperativeLevel(window, DSSCL_PRIORITY); if (FAILED(res)){ OutputDebugString("Could not set cooperative level on direct sound object"); return; } // Primary buffer. DSBUFFERDESC primarySoundBufferDesc; ZeroMemory(&primarySoundBufferDesc, sizeof(DSBUFFERDESC)); primarySoundBufferDesc.dwSize = sizeof(primarySoundBufferDesc); primarySoundBufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; primarySoundBufferDesc.dwBufferBytes = 0; primarySoundBufferDesc.lpwfxFormat = NULL; primarySoundBufferDesc.guid3DAlgorithm = GUID_NULL; LPDIRECTSOUNDBUFFER primarySoundBuffer; res = directSound->CreateSoundBuffer(&primarySoundBufferDesc, &primarySoundBuffer, NULL); if (FAILED(res)){ OutputDebugString(LOG_LEVEL_ERROR, "Could not create primary buffer"); return; } // Set the format WAVEFORMATEX waveFormat = {}; waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nChannels = audioBuffer.noOfChannels; waveFormat.nSamplesPerSec = audioBuffer.samplesPerSecond; waveFormat.nAvgBytesPerSec = (audioBuffer.samplesPerSecond * blockAlignment); waveFormat.nBlockAlign = blockAlignment; waveFormat.wBitsPerSample = audioBuffer.bitsPerSample; waveFormat.cbSize = 0; res = primarySoundBuffer->SetFormat(&waveFormat); if (FAILED(res)){ OutputDebugString("Could not set sound format on primary buffer"); return; } // Secondary buffer. DSBUFFERDESC secondarySoundBufferDesc; ZeroMemory(&secondarySoundBufferDesc, sizeof(DSBUFFERDESC)); secondarySoundBufferDesc.dwSize = sizeof(secondarySoundBufferDesc); secondarySoundBufferDesc.dwFlags = 0; secondarySoundBufferDesc.dwBufferBytes = audioBuffer.bufferSizeInBytes; secondarySoundBufferDesc.lpwfxFormat = &waveFormat; secondarySoundBufferDesc.guid3DAlgorithm = GUID_NULL; res = directSound->CreateSoundBuffer(&secondarySoundBufferDesc, &audioBuffer.buffer, NULL); if (FAILED(res)){ OutputDebugString("Could not create secondary buffer"); return; } } internal_func void win32WriteAudioBuffer(DWORD lockOffsetInBytes, DWORD lockSizeInBytes) { HRESULT res; void *chunkOnePtr; DWORD chunkOneBytes; void *chunkTwoPtr; DWORD chunkTwoBytes; res = audioBuffer.buffer->Lock(lockOffsetInBytes, lockSizeInBytes, &chunkOnePtr, &chunkOneBytes, &chunkTwoPtr, &chunkTwoBytes, 0); if (SUCCEEDED(res)) { uint64_t chunkSamples = (chunkOneBytes / audioBuffer.bytesPerSample); uint16_t *audioSample = (uint16_t*)chunkOnePtr; int16_t waveSize = 4000; uint16_t cyclesPerSecond = 375; uint64_t cycleIndex = 0; int16_t audioSampleValue = -waveSize; for (size_t i = 0; i < chunkSamples; i++) { if (0 == (cycleIndex % cyclesPerSecond)) { if (audioSampleValue == waveSize) { audioSampleValue = -waveSize; } else { audioSampleValue = waveSize; } } // Left *audioSample = audioSampleValue; audioSample++; // Right *audioSample = audioSampleValue; audioSample++; cycleIndex++; } uint64_t chunkTwoSamples = (chunkTwoBytes / audioBuffer.bytesPerSample); uint16_t *audioTwoSample = (uint16_t*)chunkTwoPtr; for (size_t i = 0; i < chunkTwoSamples; i++) { if (0 == (cycleIndex % cyclesPerSecond)) { if (audioSampleValue == waveSize) { audioSampleValue = -waveSize; } else { audioSampleValue = waveSize; } } // Left *audioTwoSample = audioSampleValue; audioTwoSample++; // Right *audioTwoSample = audioSampleValue; audioTwoSample++; cycleIndex++; } res = audioBuffer.buffer->Unlock(chunkOnePtr, chunkOneBytes, chunkTwoPtr, chunkTwoBytes); if (FAILED(res)) { OutputDebugString("Could not unlock sound buffer\n"); } } else { OutputDebugString("Could not lock secondary sound buffer\n"); } } internal_func int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR commandLine, int showCode) { // window set up... //... win32InitDirectSound(window); win32WriteAudioBuffer(0, audioBuffer.bufferSizeInBytes); // 0, 192000 audioBuffer.buffer->Play(0, 0, DSBPLAY_LOOPING); // game loop... //... } |
Any help would be much appreciated
Jon