Handmade Hero » Forums » Code » Day 007 - Problem with WaveFormat.wFormatTag
Stahlherz
4 posts
#12057 Day 007 - Problem with WaveFormat.wFormatTag
3 months, 4 weeks ago

Hello everyone!

I'm a bit late to the Handmade Hero GameDev but I made my way up to Day 7 in one go. But now I ran into a problem with the Win32InitSound function which it seems I can't figure out myself. More specific it's the WaveFormat.wFormatTag which i cannot set without getting the [E_INVALIDARG One or more arguments are invalid - unrecognized token] error. If it is not set the PrimaryBuffer->SetFormat(&WaveFormat) returns S_OK. Is there a way to find out why it is not working? My code for the DirectSound Implementation:


  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
#include <dsound.h>

#define DIRECT_SOUND_CREATE(name) HRESULT WINAPI name(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter)
typedef DIRECT_SOUND_CREATE(direct_sound_create);

internal void Win32InitDirectSound(HWND Window, int32 SamplesPerSecond, int32 BufferSize)
{

	// note: load the library
	HMODULE DirectSoundLibrary = LoadLibrary("dsound.dll");

	if (DirectSoundLibrary) {

		// note: Get a DirectSound Object - cooperative
		direct_sound_create *DirectSoundCreate = (direct_sound_create *) GetProcAddress(DirectSoundLibrary, "DirectSoundCreate");

		// todo: doublecheck that this works on windows xp - directsound8 or 7?
		LPDIRECTSOUND DirectSound;
		if (DirectSoundCreate && SUCCEEDED(DirectSoundCreate(0, &DirectSound, 0))) {

			// note: waveformat für die buffer vorbereiten

			// typedef struct {
			// 	WORD  wFormatTag;
			// 	WORD  nChannels;
			// 	DWORD nSamplesPerSec;
			// 	DWORD nAvgBytesPerSec;
			// 	WORD  nBlockAlign;
			// 	WORD  wBitsPerSample;
			// 	WORD  cbSize;
			// } WAVEFORMATEX;
			WAVEFORMATEX WaveFormat 	= {};
			WaveFormat.cbSize 			= 0;
			WaveFormat.wFormatTag 		= WAVE_FORMAT_PCM; // -> E_INVALIDARG One or more arguments are invalid.
			WaveFormat.nChannels 		= 2;
			WaveFormat.wBitsPerSample  	= 16;
			WaveFormat.nSamplesPerSec 	= SamplesPerSecond;
			WaveFormat.nBlockAlign 		= (WaveFormat.nChannels * WaveFormat.wBitsPerSample) / 8;
			WaveFormat.nAvgBytesPerSec  = WaveFormat.nChannels * WaveFormat.nBlockAlign;

			if (SUCCEEDED(DirectSound->SetCooperativeLevel(Window, DSSCL_PRIORITY))) {

				// note: primären buffer anlegen
				// todo: DSBCAPS_GLOBALFOCUS?

				// typedef struct DSBUFFERDESC {
				// 	DWORD dwSize;
				// 	DWORD dwFlags;
				// 	DWORD dwBufferBytes;
				// 	DWORD dwReserved;
				// 	LPWAVEFORMATEX lpwfxFormat;
				// 	GUID guid3DAlgorithm;
				// } DSBUFFERDESC;
				DSBUFFERDESC BufferDescription  = {};
				BufferDescription.dwSize 		= sizeof(BufferDescription);
				BufferDescription.dwFlags 		= DSBCAPS_PRIMARYBUFFER;

				LPDIRECTSOUNDBUFFER PrimaryBuffer;
				if (SUCCEEDED(DirectSound->CreateSoundBuffer(&BufferDescription, &PrimaryBuffer, 0))) {

					// HRESULT error = PrimaryBuffer->SetFormat(&WaveFormat);
					// if (SUCCEEDED(error)) {
					if (SUCCEEDED(PrimaryBuffer->SetFormat(&WaveFormat))) {
						OutputDebugStringA("PrimaryBuffer format was set\n");
					} else {
						// todo: error log
					}

				} else {
					// todo: error log
				}

			} else {
				// todo: error log
			}

			// note: sekundären buffer anlegen
			// todo: DSBCAPS_GETCURRENTPOSITION2?
			DSBUFFERDESC BufferDescription  = {};
			BufferDescription.dwSize 		= sizeof(BufferDescription);
			BufferDescription.dwFlags 		= 0;
			BufferDescription.dwBufferBytes = BufferSize;
			BufferDescription.lpwfxFormat 	= &WaveFormat;

			LPDIRECTSOUNDBUFFER SecondaryBuffer;
			// HRESULT error = DirectSound->CreateSoundBuffer(&BufferDescription, &SecondaryBuffer, 0);
			// if (SUCCEEDED(error)) {
			if (SUCCEEDED(DirectSound->CreateSoundBuffer(&BufferDescription, &SecondaryBuffer, 0))) {

				OutputDebugStringA("SecondaryBuffer created successfully\n");

			} else {
				// todo: error log
			}

		} else {
			// todo: error log
		}

	}

}



PS: I'm developing on Windows 10 with VS2017 if that has anything to do with it
mmozeiko
Mārtiņš Možeiko
1477 posts
1 project
#12058 Day 007 - Problem with WaveFormat.wFormatTag
3 months, 4 weeks ago Edited by Mārtiņš Možeiko on May 30, 2017, 6:54 p.m.

nAvgBytesPerSec needs to be bytes per second, not bytes per all channels per all channels (you are multiplying channels two times into it).

1
nAvgBytesPerSec = WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign;

Read the documentation more carefully: https://msdn.microsoft.com/en-us/...ary/windows/desktop/dd390970.aspx
nAvgBytesPerSec

Required average data-transfer rate, in bytes per second, for the format tag. If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec must equal nSamplesPerSec × nBlockAlign.
Stahlherz
4 posts
#12059 Day 007 - Problem with WaveFormat.wFormatTag
3 months, 4 weeks ago

mmozeiko
nAvgBytesPerSec needs to be bytes per second, not bytes per all channels per all channels (you are multiplying channels two times into it).

1
nAvgBytesPerSec = WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign;

Read the documentation more carefully: https://msdn.microsoft.com/en-us/...ary/windows/desktop/dd390970.aspx
nAvgBytesPerSec

Required average data-transfer rate, in bytes per second, for the format tag. If wFormatTag is WAVE_FORMAT_PCM, nAvgBytesPerSec must equal nSamplesPerSec × nBlockAlign.


Whoops, that error must have slipped in as I was reordering the struct. Thanks for your fast response and good catch, would have taken ages to find that myself. Cheers!
DanZaidan
Daniel Zaidan
12 posts
#12060 Day 007 - Problem with WaveFormat.wFormatTag
3 months, 4 weeks ago

7 days in one go?
I wish I had your stamina! :D
Stahlherz
4 posts
#12061 Day 007 - Problem with WaveFormat.wFormatTag
3 months, 4 weeks ago

DanZaidan
7 days in one go?
I wish I had your stamina! :D


I have to admit that I skipped the Q&A's at the end of every video, but I'm so glad i stumbled upon this series. It really is invaluable from an educational perspective and the way Casey teaches makes it quite addictive one might say xD