diff --git a/dlls/winmm/tests/wave.c b/dlls/winmm/tests/wave.c
index 98a16f5..538c120 100644
--- a/dlls/winmm/tests/wave.c
+++ b/dlls/winmm/tests/wave.c
@@ -825,6 +825,177 @@ EXIT:
     HeapFree(GetProcessHeap(), 0, frags);
 }
 
+static void wave_out_test_device_volume(UINT_PTR device)
+{
+    HWAVEOUT handle1, handle2 = NULL;
+    MMRESULT ret;
+    WAVEFORMATEX wfx;
+    DWORD orig_volume;
+    DWORD volume;
+
+    ret = waveOutGetVolume((HWAVEOUT)device, &orig_volume);
+    if (ret == MMSYSERR_NOERROR) ret = waveOutSetVolume((HWAVEOUT)device, 0x00000000);
+    if (ret != MMSYSERR_NOERROR)
+    {
+        skip("Can't test device ID vs. handle volume; can't get or set device volume\n");
+        return;
+    }
+
+    wfx.wFormatTag = WAVE_FORMAT_PCM;
+    wfx.nChannels = 1;
+    wfx.nSamplesPerSec = 11025;
+    wfx.nBlockAlign = 1;
+    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
+    wfx.wBitsPerSample = 8;
+    wfx.cbSize = 0;
+
+    ret = waveOutOpen(&handle1, 0, &wfx, 0, 0, 0);
+    if (ret != MMSYSERR_NOERROR)
+    {
+        skip("Can't test device vs. handle volume; can't open handle1\n");
+        goto done;
+    }
+
+    ret = waveOutOpen(&handle2, 0, &wfx, 0, 0, 0);
+    if (ret != MMSYSERR_NOERROR)
+        handle2 = NULL;
+
+    /* Does opening a handle on the device change the device volume? */
+    ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    /* Do newly-opened handles inherit the device volume? */
+    ret = waveOutGetVolume(handle1, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle1): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(handle1): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    if (handle2)
+    {
+        ret = waveOutGetVolume(handle2, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle2): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(handle2): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+    }
+
+
+    ret = waveOutSetVolume(handle1, 0x00004000);
+    ok(ret == MMSYSERR_NOERROR, "waveOutSetVolume(handle1): ret = %s\n", wave_out_error(ret));
+
+    /* Does the device have a separate volume or does it just reflect the average of handle volumes? */
+    ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    /* Does setting the handle volume take effect regardless of device volume? */
+    ret = waveOutGetVolume(handle1, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle1): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(handle1): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    /* Are handle volumes independent? */
+    if (handle2)
+    {
+        ret = waveOutGetVolume(handle2, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle2): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(handle2): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+    }
+
+
+    if (handle2)
+    {
+        ret = waveOutSetVolume(handle2, 0x00002000);
+        ok(ret == MMSYSERR_NOERROR, "waveOutSetVolume(handle2): ret = %s\n", wave_out_error(ret));
+
+        /* If two handles are set to different volumes, what is the device volume? */
+        ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+        ret = waveOutGetVolume(handle1, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle1): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(handle1): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+        ret = waveOutGetVolume(handle2, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle2): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(handle2): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+    }
+
+
+    ret = waveOutSetVolume((HWAVEOUT)device, 0x0000ffff);
+    ok(ret == MMSYSERR_NOERROR, "waveOutSetVolume(device): ret = %s\n", wave_out_error(ret));
+
+    ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    ret = waveOutGetVolume(handle1, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle1): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(handle1): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    if (handle2)
+    {
+        ret = waveOutGetVolume(handle2, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle2): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(handle2): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+    }
+
+
+    ret = waveOutSetVolume(handle1, 0x00008000);
+    ok(ret == MMSYSERR_NOERROR, "waveOutSetVolume(handle1): ret = %s\n", wave_out_error(ret));
+
+    ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    ret = waveOutGetVolume(handle1, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle1): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(handle1): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    if (handle2)
+    {
+        ret = waveOutGetVolume(handle2, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle2): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(handle2): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+        waveOutClose(handle2);
+        handle2 = NULL;
+
+        ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+        ret = waveOutGetVolume(handle1, &volume);
+        ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle1): ret = %s\n", wave_out_error(ret));
+        ok(volume == 0xaa55aa55, "waveOutGetVolume(handle1): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+    }
+
+    waveOutClose(handle1);
+
+
+    ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+
+    ret = waveOutSetVolume((HWAVEOUT)device, 0x0000c000);
+    ok(ret == MMSYSERR_NOERROR, "waveOutSetVolume(device): ret = %s\n", wave_out_error(ret));
+
+    ret = waveOutOpen(&handle1, 0, &wfx, 0, 0, 0);
+    ok(ret == MMSYSERR_NOERROR, "waveOutOpen(%s): ret = %s\n", dev_name(device), wave_out_error(ret));
+
+    ret = waveOutGetVolume((HWAVEOUT)device, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(device): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(device): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    ret = waveOutGetVolume(handle1, &volume);
+    ok(ret == MMSYSERR_NOERROR, "waveOutGetVolume(handle1): ret = %s\n", wave_out_error(ret));
+    ok(volume == 0xaa55aa55, "waveOutGetVolume(handle1): volume = 0x%08x (expected 0xaa55aa55)\n", volume);
+
+    waveOutClose(handle1);
+
+done:
+    waveOutSetVolume((HWAVEOUT)device, orig_volume);
+}
+
 static void wave_out_test_device(UINT_PTR device)
 {
     WAVEOUTCAPSA capsA;
@@ -1453,7 +1624,10 @@ static void wave_out_tests(void)
        dev_name(ndev+1),mmsys_error(rc));
 
     for (d=0;d<ndev;d++)
+    {
         wave_out_test_device(d);
+        wave_out_test_device_volume(d);
+    }
 
     if (ndev>0)
         wave_out_test_device(WAVE_MAPPER);
