From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/xactengine3_7/tests/Makefile.in | 1 + dlls/xactengine3_7/tests/resource.rc | 375 +++++++++++++++ dlls/xactengine3_7/tests/test.xwb | Bin 0 -> 30060 bytes dlls/xactengine3_7/tests/xact3.c | 685 ++++++++++++++++++++++++++- 4 files changed, 1055 insertions(+), 6 deletions(-) create mode 100644 dlls/xactengine3_7/tests/resource.rc create mode 100644 dlls/xactengine3_7/tests/test.xwb
diff --git a/dlls/xactengine3_7/tests/Makefile.in b/dlls/xactengine3_7/tests/Makefile.in index 54046e85b88..5373f4bb4bf 100644 --- a/dlls/xactengine3_7/tests/Makefile.in +++ b/dlls/xactengine3_7/tests/Makefile.in @@ -2,4 +2,5 @@ TESTDLL = xactengine3_7.dll IMPORTS = ole32
SOURCES = \ + resource.rc \ xact3.c diff --git a/dlls/xactengine3_7/tests/resource.rc b/dlls/xactengine3_7/tests/resource.rc new file mode 100644 index 00000000000..8dc2231b98c --- /dev/null +++ b/dlls/xactengine3_7/tests/resource.rc @@ -0,0 +1,375 @@ +/* + * Resource file to embed XACT binaries. + * + * Copyright 2025 Elizabeth Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "windef.h" + +/* Wave files generated with: + * ffmpeg -f lavfi -i "sine=frequency=300" -t 0.3 -ar 44100 -f wav -acodec pcm_u8 test.wav + * ffmpeg -f lavfi -i "sine=frequency=400" -t 0.4 -ar 44100 -f wav -acodec pcm_s16le test2.wav + * ffmpeg -f lavfi -i "sine=frequency=500" -t 0.5 -ar 44100 -f wav -acodec pcm_s16le -ac 2 test3.wav + * + * The wavebank, soundbank, and global settings were generated from the following source: */ + +#if 0 +Signature = XACT3; +Version = 18; + +Global Settings +{ + Windows File = test.xgs; + + Variable + { + Name = v1; + Public = 1; + Global = 1; + Internal = 0; + External = 0; + Monitored = 1; + Reserved = 0; + Read Only = 0; + Time = 0; + Value = 0.000000; + Initial Value = 10.000000; + Min = 0.000000; + Max = 100.000000; + } + + Variable + { + Name = v2; + Public = 1; + Global = 0; + Internal = 0; + External = 0; + Monitored = 1; + Reserved = 0; + Read Only = 0; + Time = 0; + Value = 0.000000; + Initial Value = 10.000000; + Min = 0.000000; + Max = 100.000000; + } + + Variable + { + Name = v3; + Public = 0; + Global = 1; + Internal = 0; + External = 0; + Monitored = 1; + Reserved = 0; + Read Only = 0; + Time = 0; + Value = 0.000000; + Initial Value = 10.000000; + Min = 0.000000; + Max = 100.000000; + } + + Variable + { + Name = v4; + Public = 1; + Global = 1; + Internal = 0; + External = 0; + Monitored = 1; + Reserved = 0; + Read Only = 1; + Time = 0; + Value = 0.000000; + Initial Value = 10.000000; + Min = 0.000000; + Max = 100.000000; + } + + Compression Preset + { + Name = xwma; + Xbox Format Tag = 353; + PC Format Tag = 353; + WMA Quality = 1; + } + + Compression Preset + { + Name = adpcm; + Xbox Format Tag = 353; + PC Format Tag = 2; + Samples Per Block = 32; + } +} + +Wave Bank +{ + Name = wb; + Windows File = test.xwb; + + Wave + { + Name = w1; + File = test.wav; + } + + Wave + { + Name = w2; + File = test2.wav; + Compression Preset Name = adpcm; + + Cache + { + Format Tag = 0; + Channels = 1; + Sampling Rate = 44100; + Bits Per Sample = 1; + Play Region Offset = 78; + Play Region Length = 35280; + Loop Region Offset = 0; + Loop Region Length = 0; + File Type = 1; + Last Modified Low = 2836222863; + Last Modified High = 31027759; + } + } + + Wave + { + Name = w3; + File = test3.wav; + Compression Preset Name = xwma; + } +} + +Sound Bank +{ + Name = sb; + Windows File = test.xsb; + Windows Bank Path Edited = 1; + + Sound + { + Name = s1; + Volume = -1234; + Pitch = 66; + Priority = 0; + + Category Entry + { + Name = Default; + } + + Track + { + Name = t1; + Volume = -123; + + Play Wave Event + { + Loop Count = 2; + + Event Header + { + Name = e1; + } + + Variation + { + Variation Type = 0; + Variation Table Type = 0; + New Variation On Loop = 1; + } + + Wave Entry + { + Bank Name = wb; + Bank Index = 0; + Entry Name = w1; + Entry Index = 0; + Weight = 100; + Weight Min = 1; + } + + Wave Entry + { + Bank Name = wb; + Bank Index = 0; + Entry Name = w2; + Entry Index = 1; + Weight = 200; + Weight Min = 2; + } + } + } + + Track + { + Name = t2; + Volume = -321; + + Play Wave Event + { + Event Header + { + Name = e3; + } + + Wave Entry + { + Bank Name = wb; + Bank Index = 0; + Entry Name = w3; + Entry Index = 2; + Weight = 140; + Weight Min = 3; + } + } + } + } + + Sound + { + Name = s2; + Volume = 555; + Pitch = -8; + Priority = 0; + + Category Entry + { + Name = Music; + } + + Track + { + Name = t4; + Volume = -111; + + Play Wave Event + { + Event Header + { + Name = e4; + } + + Wave Entry + { + Bank Name = wb; + Bank Index = 0; + Entry Name = w2; + Entry Index = 1; + Weight = 200; + Weight Min = 2; + } + } + } + } + + Cue + { + Name = c1; + + Variation + { + Variation Type = 0; + Variation Table Type = 1; + } + + Sound Entry + { + Name = s1; + Index = 0; + Weight Min = 1; + Weight Max = 20; + } + + Sound Entry + { + Name = s2; + Index = 1; + Weight Min = 30; + Weight Max = 60; + } + } + + Cue + { + Name = c2; + + Variation + { + Variation Type = 3; + Variation Table Type = 3; + + Variable Entry + { + Name = v1; + } + } + + Sound Entry + { + Name = s1; + Index = 0; + Variable Min = 1.0; + Variable Max = 5.0; + Linger = 1; + } + + Sound Entry + { + Name = s2; + Index = 1; + Variable Min = 8.0; + Variable Max = 24.0; + } + + Instance Limit + { + Max Instances = 11; + Behavior = 0; + } + } + + Cue + { + Name = c3; + + Variation + { + Variation Type = 0; + Variation Table Type = 1; + } + + Sound Entry + { + Name = s2; + Index = 1; + Weight Min = 1; + Weight Max = 20; + } + } +} +#endif + +/* @makedep: test.xwb */ +test.xwb RCDATA "test.xwb" diff --git a/dlls/xactengine3_7/tests/test.xwb b/dlls/xactengine3_7/tests/test.xwb new file mode 100644 index 0000000000000000000000000000000000000000..2e807ccf1a40efdbd58fcc86e974b5eee3a1ffed GIT binary patch literal 30060 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 Hs1N`E9R(4!
literal 0 HcmV?d00001
diff --git a/dlls/xactengine3_7/tests/xact3.c b/dlls/xactengine3_7/tests/xact3.c index 48a5f0a4374..e869a9ca91c 100644 --- a/dlls/xactengine3_7/tests/xact3.c +++ b/dlls/xactengine3_7/tests/xact3.c @@ -91,6 +91,87 @@ static void test_interfaces(void) } }
+/* See resource.rc for the source code. */ + +static const char soundbank_data[] = +{ + 0x53, 0x44, 0x42, 0x4b, 0x2e, 0x00, 0x2b, 0x00, 0x38, 0x9a, 0x1d, 0x05, 0x92, 0xc6, 0x57, 0x0d, + 0xdc, 0x01, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x02, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x23, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x54, 0x02, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x46, 0x01, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x22, 0x02, + 0x00, 0x00, 0x42, 0x02, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x73, 0x62, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x62, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x58, 0x42, 0x00, + 0x00, 0x4d, 0x00, 0x02, 0xa8, 0xe6, 0x00, 0x00, 0x00, 0xc0, 0x5d, 0xe8, 0x03, 0x96, 0x06, 0x01, + 0x00, 0x00, 0xc0, 0x5d, 0xe8, 0x03, 0x01, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0xff, 0x0c, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, + 0x64, 0x01, 0x00, 0x00, 0x02, 0xc8, 0x01, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0xff, 0x0c, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xe9, 0xf8, 0xff, 0x00, 0x0c, 0x00, + 0x01, 0x00, 0x00, 0x04, 0x17, 0x01, 0x00, 0x00, 0x01, 0x46, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5a, 0x01, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff, 0xca, 0x00, + 0x00, 0x00, 0x01, 0x14, 0x17, 0x01, 0x00, 0x00, 0x1e, 0x3c, 0x02, 0x00, 0x1b, 0x00, 0xff, 0xff, + 0x07, 0x00, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0xa0, 0x40, 0x01, 0x00, + 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0xc0, 0x41, 0x01, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x54, 0x02, 0x00, 0x00, 0xff, 0xff, 0x57, 0x02, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x02, + 0x00, 0x00, 0xff, 0xff, 0x63, 0x33, 0x00, 0x63, 0x31, 0x00, 0x63, 0x32, 0x00, +}; + +static const char global_settings_data[] = +{ + 0x58, 0x47, 0x53, 0x46, 0x2e, 0x00, 0x2a, 0x00, 0x4c, 0xca, 0x37, 0x2f, 0xa2, 0x52, 0xb7, 0x0b, + 0xdc, 0x01, 0x03, 0x03, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4d, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x1a, 0x01, 0x00, + 0x00, 0x41, 0x01, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0xa3, 0x01, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xb4, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, + 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x6a, 0x46, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x6a, 0x46, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xc3, 0x00, 0x00, 0x34, 0x43, 0x0d, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x09, 0x00, 0xc0, 0xab, + 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x74, 0x49, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x74, 0x49, 0x01, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x42, 0x05, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x42, + 0x00, 0x00, 0x00, 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x42, 0x03, 0x00, 0x00, + 0x20, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x42, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x01, 0x00, 0x00, 0xff, 0xff, + 0x33, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x01, 0x00, 0x00, 0xff, 0xff, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x00, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x4d, 0x75, 0x73, 0x69, 0x63, + 0x00, 0x02, 0x00, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x08, + 0x00, 0xa3, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x01, 0x00, 0x00, 0x04, 0x00, 0xbe, 0x01, 0x00, + 0x00, 0x09, 0x00, 0xca, 0x01, 0x00, 0x00, 0x0a, 0x00, 0xdb, 0x01, 0x00, 0x00, 0xff, 0xff, 0xee, + 0x01, 0x00, 0x00, 0x06, 0x00, 0xfb, 0x01, 0x00, 0x00, 0xff, 0xff, 0x04, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x07, 0x02, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x02, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x02, 0x00, + 0x00, 0xff, 0xff, 0x4e, 0x75, 0x6d, 0x43, 0x75, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x00, 0x41, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x00, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x00, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x00, 0x44, 0x6f, 0x70, 0x70, 0x6c, + 0x65, 0x72, 0x50, 0x69, 0x74, 0x63, 0x68, 0x53, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x00, 0x53, 0x70, + 0x65, 0x65, 0x64, 0x4f, 0x66, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x00, 0x44, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x00, 0x76, 0x31, 0x00, 0x76, 0x32, 0x00, 0x76, 0x33, 0x00, 0x76, 0x34, 0x00, +}; + static WCHAR *gen_xwb_file(void) { static const WAVEBANKENTRY entry = @@ -194,13 +275,8 @@ static void test_notifications(void) HRESULT hr;
hr = CoCreateInstance(&CLSID_XACTEngine, NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void **)&engine); - ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /* Win 10 v1507 */, "Cannot create engine, hr %#lx\n", hr); + ok(hr == S_OK, "Got hr %#lx.\n", hr);
- if (hr == REGDB_E_CLASSNOTREG) - { - win_skip("XACT not supported\n"); - return; - }
params.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; params.fnNotificationCallback = notification_cb; @@ -287,12 +363,609 @@ static void test_notifications(void) DeleteFileW(filename); }
+static void test_properties(void) +{ + XACT_RUNTIME_PARAMETERS params = {.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT}; + const XACT_VARIATION_PROPERTIES *var_props; + const XACT_SOUND_PROPERTIES *sound_props; + const XACT_TRACK_PROPERTIES *track_props; + XACT_WAVE_INSTANCE_PROPERTIES wave_props; + XACT_CUE_INSTANCE_PROPERTIES *props; + XACT_CUE_PROPERTIES cue_props; + IXACT3SoundBank *soundbank; + void *soundbank_data_copy; + IXACT3WaveBank *wavebank; + XACTVARIABLEVALUE value; + XACTINDEX count, index; + IXACT3Cue *cue, *cue2; + IXACT3Engine *engine; + IXACT3Wave *wave; + ULONG refcount; + DWORD state; + HRESULT hr; + HRSRC res; + + hr = CoCreateInstance(&CLSID_XACTEngine, NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void **)&engine); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + params.pGlobalSettingsBuffer = (void *)global_settings_data; + params.globalSettingsBufferSize = sizeof(global_settings_data); + hr = IXACT3Engine_Initialize(engine, ¶ms); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + res = FindResourceW(NULL, L"test.xwb", (const WCHAR *)RT_RCDATA); + ok(!!res, "Got error %lu.\n", GetLastError()); + + hr = IXACT3Engine_CreateInMemoryWaveBank(engine, + LockResource(LoadResource(GetModuleHandleA(NULL), res)), + SizeofResource(GetModuleHandleA(NULL), res), 0, 0, &wavebank); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + /* Despite the parameter here being const, native will attempt to overwrite + * some of this data. */ + soundbank_data_copy = malloc(sizeof(soundbank_data)); + memcpy(soundbank_data_copy, soundbank_data, sizeof(soundbank_data)); + hr = IXACT3Engine_CreateSoundBank(engine, soundbank_data_copy, sizeof(soundbank_data), 0, 0, &soundbank); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IXACT3SoundBank_GetState(soundbank, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(!state, "Got state %#lx.\n", state); + + hr = IXACT3SoundBank_GetNumCues(soundbank, &count); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(count == 3, "Got count %u.\n", count); + + memset(&cue_props, 0xcc, sizeof(cue_props)); + hr = IXACT3SoundBank_GetCueProperties(soundbank, 1, &cue_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!strcmp(cue_props.friendlyName, "c1"), "Got name %s.\n", debugstr_a(cue_props.friendlyName)); + ok(!cue_props.interactive, "Got interactive %d.\n", cue_props.interactive); + todo_wine ok(cue_props.iaVariableIndex == XACTINDEX_INVALID, "Got variable index %u.\n", cue_props.iaVariableIndex); + ok(cue_props.numVariations == 2, "Got %u variations.\n", cue_props.numVariations); + ok(cue_props.maxInstances == XACTINSTANCELIMIT_INFINITE, "Got max instances %u.\n", cue_props.maxInstances); + ok(!cue_props.currentInstances, "Got current instances %u.\n", cue_props.currentInstances); + + memset(&cue_props, 0xcc, sizeof(cue_props)); + hr = IXACT3SoundBank_GetCueProperties(soundbank, 2, &cue_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!strcmp(cue_props.friendlyName, "c2"), "Got name %s.\n", debugstr_a(cue_props.friendlyName)); + ok(cue_props.interactive == TRUE, "Got interactive %d.\n", cue_props.interactive); + ok(cue_props.iaVariableIndex == 7, "Got variable index %u.\n", cue_props.iaVariableIndex); + ok(cue_props.numVariations == 2, "Got %u variations.\n", cue_props.numVariations); + ok(cue_props.maxInstances == 11, "Got max instances %u.\n", cue_props.maxInstances); + ok(!cue_props.currentInstances, "Got current instances %u.\n", cue_props.currentInstances); + + memset(&cue_props, 0xcc, sizeof(cue_props)); + hr = IXACT3SoundBank_GetCueProperties(soundbank, 0, &cue_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!strcmp(cue_props.friendlyName, "c3"), "Got name %s.\n", debugstr_a(cue_props.friendlyName)); + ok(!cue_props.interactive, "Got interactive %d.\n", cue_props.interactive); + todo_wine ok(cue_props.iaVariableIndex == XACTINDEX_INVALID, "Got variable index %u.\n", cue_props.iaVariableIndex); + todo_wine ok(cue_props.numVariations == 1, "Got %u variations.\n", cue_props.numVariations); + ok(cue_props.maxInstances == XACTINSTANCELIMIT_INFINITE, "Got max instances %u.\n", cue_props.maxInstances); + ok(!cue_props.currentInstances, "Got current instances %u.\n", cue_props.currentInstances); + + hr = IXACT3SoundBank_Prepare(soundbank, 1, 0, 0, &cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3SoundBank_Prepare(soundbank, 1, 0, 0, &cue2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(cue2 != cue, "Expected different cues.\n"); + + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_PREPARED, "Got state %#lx.\n", state); + + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(props->allocAttributes == 0x1, "Got alloc attributes %#lx.\n", props->allocAttributes); + ok(!strcmp(props->cueProperties.friendlyName, "c1"), + "Got name %s.\n", debugstr_a(props->cueProperties.friendlyName)); + ok(!props->cueProperties.interactive, "Got interactive %d.\n", props->cueProperties.interactive); + todo_wine ok(props->cueProperties.iaVariableIndex == XACTINDEX_INVALID, + "Got variable index %u.\n", props->cueProperties.iaVariableIndex); + ok(props->cueProperties.numVariations == 2, "Got %u variations.\n", props->cueProperties.numVariations); + ok(props->cueProperties.maxInstances == XACTINSTANCELIMIT_INFINITE, + "Got max instances %u.\n", props->cueProperties.maxInstances); + ok(!props->cueProperties.currentInstances, "Got current instances %u.\n", props->cueProperties.currentInstances); + var_props = &props->activeVariationProperties.variationProperties; + ok(!var_props->index, "Got variation index %u.\n", var_props->index); + todo_wine ok(var_props->weight == 20, "Got variation weight %u.\n", var_props->weight); + ok(!var_props->iaVariableMin, "Got variable min %.8e.\n", var_props->iaVariableMin); + ok(!var_props->iaVariableMax, "Got variable max %.8e.\n", var_props->iaVariableMax); + ok(!var_props->linger, "Got linger %u.\n", var_props->linger); + /* The sound properties are already filled, for the first sound variation + * which will play. Since our cue has the variation type 0 (ordered) this + * will always be its first sound variation. */ + sound_props = &props->activeVariationProperties.soundProperties; + todo_wine ok(sound_props->category == 1, "Got category %u.\n", sound_props->category); + ok(!sound_props->priority, "Got priority %u.\n", sound_props->priority); + todo_wine ok(sound_props->pitch == 66, "Got pitch %d.\n", sound_props->pitch); + todo_wine ok(sound_props->volume == 0.237621084f, "Got volume %.8e.\n", sound_props->volume); + todo_wine ok(sound_props->numTracks == 2, "Got %u tracks.\n", sound_props->numTracks); + if (sound_props->numTracks == 2) + { + track_props = &sound_props->arrTrackProperties[0]; + ok(track_props->numVariations == 2, "Got %u variations.\n", track_props->numVariations); + ok(track_props->numChannels == 1, "Got %u channels.\n", track_props->numChannels); + /* Similarly the wave variation is filled for the first wave variation + * which will play, and we use the ordered type here. */ + ok(!track_props->waveVariation, "Got active variation %u.\n", track_props->waveVariation); + /* The duration reflects the loop count multiplied by the track length. + * This would seem to be a bug in native, since the event has the "new + * variation on loop" flag set and so we should presumably get the + * second wave variation on the second loop. That said, when manually + * testing I was unable to get the track to actually play more than + * once. */ + ok(track_props->duration == 300 * 3, "Got duration %lu.\n", track_props->duration); + ok(track_props->loopCount == 2, "Got loop count %u.\n", track_props->loopCount); + track_props = &sound_props->arrTrackProperties[1]; + ok(track_props->duration == 522, "Got duration %lu.\n", track_props->duration); + ok(track_props->numVariations == 1, "Got %u variations.\n", track_props->numVariations); + ok(track_props->numChannels == 2, "Got %u channels.\n", track_props->numChannels); + ok(!track_props->waveVariation, "Got active variation %u.\n", track_props->waveVariation); + ok(!track_props->loopCount, "Got loop count %u.\n", track_props->loopCount); + } + CoTaskMemFree(props); + + hr = IXACT3Cue_GetProperties(cue2, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!props->cueProperties.currentInstances, "Got current instances %u.\n", props->cueProperties.currentInstances); + var_props = &props->activeVariationProperties.variationProperties; + todo_wine ok(var_props->index == 1, "Got variation index %u.\n", var_props->index); + todo_wine ok(var_props->weight == 60, "Got variation weight %u.\n", var_props->weight); + ok(!var_props->iaVariableMin, "Got variable min %.8e.\n", var_props->iaVariableMin); + ok(!var_props->iaVariableMax, "Got variable max %.8e.\n", var_props->iaVariableMax); + ok(!var_props->linger, "Got linger %u.\n", var_props->linger); + sound_props = &props->activeVariationProperties.soundProperties; + todo_wine ok(sound_props->category == 2, "Got category %u.\n", sound_props->category); + ok(!sound_props->priority, "Got priority %u.\n", sound_props->priority); + todo_wine ok(sound_props->pitch == -8, "Got pitch %d.\n", sound_props->pitch); + todo_wine ok(sound_props->volume == 1.66583312f, "Got volume %.8e.\n", sound_props->volume); + todo_wine ok(sound_props->numTracks == 1, "Got %u tracks.\n", sound_props->numTracks); + if (sound_props->numTracks) + { + track_props = &sound_props->arrTrackProperties[0]; + ok(track_props->numVariations == 1, "Got %u variations.\n", track_props->numVariations); + ok(track_props->numChannels == 1, "Got %u channels.\n", track_props->numChannels); + ok(!track_props->waveVariation, "Got active variation %u.\n", track_props->waveVariation); + ok(track_props->duration == 400, "Got duration %lu.\n", track_props->duration); + ok(!track_props->loopCount, "Got loop count %u.\n", track_props->loopCount); + } + CoTaskMemFree(props); + + hr = IXACT3Cue_Pause(cue, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == (XACT_STATE_PREPARED | XACT_STATE_PAUSED), "Got state %#lx.\n", state); + + hr = IXACT3Cue_Play(cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(state == (XACT_STATE_PLAYING | XACT_STATE_PAUSED), "Got state %#lx.\n", state); + + hr = IXACT3Cue_Play(cue); + todo_wine ok(hr == XACTENGINE_E_INVALIDUSAGE, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(props->cueProperties.currentInstances == 1, "Got current instances %u.\n", props->cueProperties.currentInstances); + var_props = &props->activeVariationProperties.variationProperties; + ok(!var_props->index, "Got variation index %u.\n", var_props->index); + CoTaskMemFree(props); + + hr = IXACT3Cue_GetProperties(cue2, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(props->cueProperties.currentInstances == 1, "Got current instances %u.\n", props->cueProperties.currentInstances); + var_props = &props->activeVariationProperties.variationProperties; + todo_wine ok(var_props->index == 1, "Got variation index %u.\n", var_props->index); + CoTaskMemFree(props); + + hr = IXACT3Cue_Play(cue2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_Pause(cue2, FALSE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_Pause(cue2, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_GetState(cue2, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == (XACT_STATE_PLAYING | XACT_STATE_PAUSED), "Got state %#lx.\n", state); + hr = IXACT3Cue_Play(cue2); + todo_wine ok(hr == XACTENGINE_E_INVALIDUSAGE, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(props->cueProperties.currentInstances == 2, "Got current instances %u.\n", props->cueProperties.currentInstances); + var_props = &props->activeVariationProperties.variationProperties; + ok(!var_props->index, "Got variation index %u.\n", var_props->index); + CoTaskMemFree(props); + + hr = IXACT3Cue_Destroy(cue2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(props->cueProperties.currentInstances == 1, "Got current instances %u.\n", props->cueProperties.currentInstances); + CoTaskMemFree(props); + + index = IXACT3Engine_GetGlobalVariableIndex(engine, "v1"); + ok(index == 7, "Got index %u.\n", index); + value = -1.0f; + hr = IXACT3Engine_GetGlobalVariable(engine, index, &value); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(value == 10.0f, "Got value %.8e.\n", value); + + hr = IXACT3Cue_Stop(cue, XACT_FLAG_STOP_IMMEDIATE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_Stop(cue, XACT_FLAG_STOP_IMMEDIATE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + /* Despite STOP_IMMEDIATE we're not STOPPED until the render thread notices. */ + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_STOPPING || state == XACT_STATE_STOPPED, "Got state %#lx.\n", state); + + hr = IXACT3Cue_Play(cue); + todo_wine ok(hr == XACTENGINE_E_INVALIDUSAGE, "Got hr %#lx.\n", hr); + + /* Third instance of this cue: we've now alternated back to the first sound + * variation, and since this is the second instance of that variation we + * alternate to the second wave variation. */ + hr = IXACT3SoundBank_Prepare(soundbank, 1, 0, 0, &cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!strcmp(props->cueProperties.friendlyName, "c1"), + "Got name %s.\n", debugstr_a(props->cueProperties.friendlyName)); + var_props = &props->activeVariationProperties.variationProperties; + ok(!var_props->index, "Got variation index %u.\n", var_props->index); + sound_props = &props->activeVariationProperties.soundProperties; + todo_wine ok(sound_props->numTracks == 2, "Got %u tracks.\n", sound_props->numTracks); + if (sound_props->numTracks == 2) + { + track_props = &sound_props->arrTrackProperties[0]; + ok(track_props->numVariations == 2, "Got %u variations.\n", track_props->numVariations); + ok(track_props->numChannels == 1, "Got %u channels.\n", track_props->numChannels); + ok(track_props->waveVariation == 1, "Got active variation %u.\n", track_props->waveVariation); + ok(track_props->duration == 400 * 3, "Got duration %lu.\n", track_props->duration); + ok(track_props->loopCount == 2, "Got loop count %u.\n", track_props->loopCount); + track_props = &sound_props->arrTrackProperties[1]; + ok(track_props->duration == 522, "Got duration %lu.\n", track_props->duration); + ok(track_props->numVariations == 1, "Got %u variations.\n", track_props->numVariations); + ok(track_props->numChannels == 2, "Got %u channels.\n", track_props->numChannels); + ok(!track_props->waveVariation, "Got active variation %u.\n", track_props->waveVariation); + ok(!track_props->loopCount, "Got loop count %u.\n", track_props->loopCount); + } + CoTaskMemFree(props); + + hr = IXACT3SoundBank_Prepare(soundbank, 2, 0, 0, &cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_PREPARED, "Got state %#lx.\n", state); + + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(props->allocAttributes == 0x1, "Got alloc attributes %#lx.\n", props->allocAttributes); + ok(!strcmp(props->cueProperties.friendlyName, "c2"), + "Got name %s.\n", debugstr_a(props->cueProperties.friendlyName)); + ok(props->cueProperties.interactive == TRUE, "Got interactive %d.\n", props->cueProperties.interactive); + ok(props->cueProperties.iaVariableIndex == 7, + "Got variable index %u.\n", props->cueProperties.iaVariableIndex); + ok(props->cueProperties.numVariations == 2, "Got %u variations.\n", props->cueProperties.numVariations); + ok(props->cueProperties.maxInstances == 11, "Got max instances %u.\n", props->cueProperties.maxInstances); + ok(!props->cueProperties.currentInstances, "Got current instances %u.\n", props->cueProperties.currentInstances); + /* Unlike the non-interactive case, the variation properties are *not* + * filled before playing. In fact, they're not filled immediately after + * Play() either, but only at a delay. DoWork() seems to be necessary, but + * unlike with wavebank notifications, isn't sufficient either. + * Unfortunately this makes it pretty much impossible to reliably test. + * + * The actual returned properties are filled as one would expect. + * "weight" remains zero. + * + * If the variable is set to a value that's not in any range, the variation + * properties remain unchanged (INVALID and zeroes), but currentInstances + * is still 1. + */ + var_props = &props->activeVariationProperties.variationProperties; + todo_wine ok(var_props->index == XACTVARIABLEINDEX_INVALID, "Got variation index %u.\n", var_props->index); + ok(!var_props->weight, "Got variation weight %u.\n", var_props->weight); + ok(!var_props->iaVariableMin, "Got variable min %.8e.\n", var_props->iaVariableMin); + ok(!var_props->iaVariableMax, "Got variable max %.8e.\n", var_props->iaVariableMax); + ok(!var_props->linger, "Got linger %u.\n", var_props->linger); + sound_props = &props->activeVariationProperties.soundProperties; + todo_wine ok(sound_props->category == XACTCATEGORY_INVALID, "Got category %u.\n", sound_props->category); + ok(!sound_props->priority, "Got priority %u.\n", sound_props->priority); + todo_wine ok(sound_props->pitch == XACTPITCH_MIN, "Got pitch %d.\n", sound_props->pitch); + ok(!sound_props->volume, "Got volume %.8e.\n", sound_props->volume); + ok(!sound_props->numTracks, "Got %u tracks.\n", sound_props->numTracks); + CoTaskMemFree(props); + + /* The instance count at least is updated immediately. */ + hr = IXACT3Cue_Play(cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(props->cueProperties.currentInstances == 1, "Got current instances %u.\n", props->cueProperties.currentInstances); + + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_PLAYING, "Got state %#lx.\n", state); + hr = IXACT3Cue_Play(cue); + todo_wine ok(hr == XACTENGINE_E_INVALIDUSAGE, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_Stop(cue, XACT_FLAG_STOP_IMMEDIATE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_STOPPING || state == XACT_STATE_STOPPED, "Got state %#lx.\n", state); + hr = IXACT3Cue_Play(cue); + todo_wine ok(hr == XACTENGINE_E_INVALIDUSAGE, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_Destroy(cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + for (unsigned int i = 0; i < 12; ++i) + { + hr = IXACT3SoundBank_Prepare(soundbank, 2, 0, 0, &cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Cue_Play(cue); + todo_wine_if (i >= 10) ok(hr == (i < 11 ? S_OK : XACTENGINE_E_INSTANCELIMITFAILTOPLAY), "Got hr %#lx.\n", hr); + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine_if (i < 10) ok(props->cueProperties.currentInstances == min(i + 1, 11), + "Got current instances %u.\n", props->cueProperties.currentInstances); + } + + /* Test a cue which has only one sound, and is therefore encoded + * differently. */ + hr = IXACT3SoundBank_Prepare(soundbank, 0, 0, 0, &cue); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IXACT3Cue_GetState(cue, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_PREPARED, "Got state %#lx.\n", state); + + hr = IXACT3Cue_GetProperties(cue, &props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(props->allocAttributes == 0x1, "Got alloc attributes %#lx.\n", props->allocAttributes); + ok(!strcmp(props->cueProperties.friendlyName, "c3"), + "Got name %s.\n", debugstr_a(props->cueProperties.friendlyName)); + ok(!props->cueProperties.interactive, "Got interactive %d.\n", props->cueProperties.interactive); + todo_wine ok(props->cueProperties.iaVariableIndex == XACTINDEX_INVALID, + "Got variable index %u.\n", props->cueProperties.iaVariableIndex); + todo_wine ok(props->cueProperties.numVariations == 1, "Got %u variations.\n", props->cueProperties.numVariations); + ok(props->cueProperties.maxInstances == XACTINSTANCELIMIT_INFINITE, + "Got max instances %u.\n", props->cueProperties.maxInstances); + ok(!props->cueProperties.currentInstances, "Got current instances %u.\n", props->cueProperties.currentInstances); + var_props = &props->activeVariationProperties.variationProperties; + ok(!var_props->index, "Got variation index %u.\n", var_props->index); + todo_wine ok(var_props->weight == 0xff, "Got variation weight %u.\n", var_props->weight); + ok(!var_props->iaVariableMin, "Got variable min %.8e.\n", var_props->iaVariableMin); + ok(!var_props->iaVariableMax, "Got variable max %.8e.\n", var_props->iaVariableMax); + ok(!var_props->linger, "Got linger %u.\n", var_props->linger); + sound_props = &props->activeVariationProperties.soundProperties; + todo_wine ok(sound_props->category == 2, "Got category %u.\n", sound_props->category); + ok(!sound_props->priority, "Got priority %u.\n", sound_props->priority); + todo_wine ok(sound_props->pitch == -8, "Got pitch %d.\n", sound_props->pitch); + todo_wine ok(sound_props->volume == 1.66583312f, "Got volume %.8e.\n", sound_props->volume); + todo_wine ok(sound_props->numTracks == 1, "Got %u tracks.\n", sound_props->numTracks); + if (sound_props->numTracks) + { + track_props = &sound_props->arrTrackProperties[0]; + ok(track_props->numVariations == 1, "Got %u variations.\n", track_props->numVariations); + ok(track_props->numChannels == 1, "Got %u channels.\n", track_props->numChannels); + ok(!track_props->waveVariation, "Got active variation %u.\n", track_props->waveVariation); + ok(track_props->duration == 400, "Got duration %lu.\n", track_props->duration); + ok(!track_props->loopCount, "Got loop count %u.\n", track_props->loopCount); + } + CoTaskMemFree(props); + + memset(&wave_props, 0xcc, sizeof(wave_props)); + hr = IXACT3WaveBank_GetWaveProperties(wavebank, 0, &wave_props.properties); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(wave_props.properties.friendlyName[0] == (char)0xcc, + "Got name %s.\n", debugstr_a(wave_props.properties.friendlyName)); + ok(wave_props.properties.format.wFormatTag == WAVEBANKMINIFORMAT_TAG_PCM, + "Got format %u.\n", wave_props.properties.format.wFormatTag); + ok(wave_props.properties.format.nChannels == 1, + "Got %u channels.\n", wave_props.properties.format.nChannels); + ok(wave_props.properties.format.nSamplesPerSec == 44100, + "Got sample rate %u.\n", wave_props.properties.format.nSamplesPerSec); + ok(wave_props.properties.format.wBlockAlign == 1, + "Got alignment %u.\n", wave_props.properties.format.wBlockAlign); + ok(wave_props.properties.format.wBitsPerSample == WAVEBANKMINIFORMAT_BITDEPTH_8, + "Got bit depth %u.\n", wave_props.properties.format.wBitsPerSample); + ok(wave_props.properties.durationInSamples == 44100 * 3 / 10, + "Got duration %lu.\n", wave_props.properties.durationInSamples); + ok(!wave_props.properties.loopRegion.dwStartSample, + "Got loop start %lu.\n", wave_props.properties.loopRegion.dwStartSample); + ok(!wave_props.properties.loopRegion.dwTotalSamples, + "Got loop length %lu.\n", wave_props.properties.loopRegion.dwTotalSamples); + ok(!wave_props.properties.streaming, "Got streaming %d.\n", wave_props.properties.streaming); + + memset(&wave_props, 0xcc, sizeof(wave_props)); + hr = IXACT3WaveBank_GetWaveProperties(wavebank, 1, &wave_props.properties); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(wave_props.properties.friendlyName[0] == (char)0xcc, + "Got name %s.\n", debugstr_a(wave_props.properties.friendlyName)); + ok(wave_props.properties.format.wFormatTag == WAVEBANKMINIFORMAT_TAG_ADPCM, + "Got format %u.\n", wave_props.properties.format.wFormatTag); + ok(wave_props.properties.format.nChannels == 1, + "Got %u channels.\n", wave_props.properties.format.nChannels); + ok(wave_props.properties.format.nSamplesPerSec == 44080, + "Got sample rate %u.\n", wave_props.properties.format.nSamplesPerSec); + ok(!wave_props.properties.format.wBlockAlign, + "Got alignment %u.\n", wave_props.properties.format.wBlockAlign); + ok(!wave_props.properties.format.wBitsPerSample, + "Got bit depth %u.\n", wave_props.properties.format.wBitsPerSample); + ok(wave_props.properties.durationInSamples == 44080 * 4 / 10, + "Got duration %lu.\n", wave_props.properties.durationInSamples); + ok(!wave_props.properties.loopRegion.dwStartSample, + "Got loop start %lu.\n", wave_props.properties.loopRegion.dwStartSample); + ok(wave_props.properties.loopRegion.dwTotalSamples == 44080 * 4 / 10, + "Got loop length %lu.\n", wave_props.properties.loopRegion.dwTotalSamples); + ok(!wave_props.properties.streaming, "Got streaming %d.\n", wave_props.properties.streaming); + + memset(&wave_props, 0xcc, sizeof(wave_props)); + hr = IXACT3WaveBank_GetWaveProperties(wavebank, 2, &wave_props.properties); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(wave_props.properties.friendlyName[0] == (char)0xcc, + "Got name %s.\n", debugstr_a(wave_props.properties.friendlyName)); + ok(wave_props.properties.format.wFormatTag == WAVEBANKMINIFORMAT_TAG_WMA, + "Got format %u.\n", wave_props.properties.format.wFormatTag); + ok(wave_props.properties.format.nChannels == 2, + "Got %u channels.\n", wave_props.properties.format.nChannels); + ok(wave_props.properties.format.nSamplesPerSec == 44100, + "Got sample rate %u.\n", wave_props.properties.format.nSamplesPerSec); + ok(wave_props.properties.format.wBlockAlign == 99, + "Got alignment %u.\n", wave_props.properties.format.wBlockAlign); + ok(!wave_props.properties.format.wBitsPerSample, + "Got bit depth %u.\n", wave_props.properties.format.wBitsPerSample); + todo_wine ok(wave_props.properties.durationInSamples == 23040, + "Got duration %lu.\n", wave_props.properties.durationInSamples); + ok(!wave_props.properties.loopRegion.dwStartSample, + "Got loop start %lu.\n", wave_props.properties.loopRegion.dwStartSample); + ok(!wave_props.properties.loopRegion.dwTotalSamples, + "Got loop length %lu.\n", wave_props.properties.loopRegion.dwTotalSamples); + ok(!wave_props.properties.streaming, "Got streaming %d.\n", wave_props.properties.streaming); + + hr = IXACT3WaveBank_Prepare(wavebank, 0, XACT_FLAG_UNITS_MS, 100, 2, &wave); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetProperties(wave, &wave_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(wave_props.properties.friendlyName[0] == (char)0xcc, + "Got name %s.\n", debugstr_a(wave_props.properties.friendlyName)); + ok(wave_props.properties.format.wFormatTag == WAVEBANKMINIFORMAT_TAG_PCM, + "Got format %u.\n", wave_props.properties.format.wFormatTag); + ok(wave_props.properties.format.nChannels == 1, + "Got %u channels.\n", wave_props.properties.format.nChannels); + ok(wave_props.properties.format.nSamplesPerSec == 44100, + "Got sample rate %u.\n", wave_props.properties.format.nSamplesPerSec); + ok(wave_props.properties.format.wBlockAlign == 1, + "Got alignment %u.\n", wave_props.properties.format.wBlockAlign); + ok(wave_props.properties.format.wBitsPerSample == WAVEBANKMINIFORMAT_BITDEPTH_8, + "Got bit depth %u.\n", wave_props.properties.format.wBitsPerSample); + ok(wave_props.properties.durationInSamples == 44100 * 3 / 10, + "Got duration %lu.\n", wave_props.properties.durationInSamples); + ok(!wave_props.properties.loopRegion.dwStartSample, + "Got loop start %lu.\n", wave_props.properties.loopRegion.dwStartSample); + ok(!wave_props.properties.loopRegion.dwTotalSamples, + "Got loop length %lu.\n", wave_props.properties.loopRegion.dwTotalSamples); + ok(!wave_props.properties.streaming, "Got streaming %d.\n", wave_props.properties.streaming); + ok(!wave_props.backgroundMusic, "Got background music %d.\n", wave_props.backgroundMusic); + + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_PREPARED, "Got state %#lx.\n", state); + + hr = IXACT3Wave_Play(wave); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + /* Calling GetState() at this point might still yield PREPARED; it doesn't + * switch to PLAYING until the render thread notices. + * Calling Play() while PLAYING is illegal, same as for cues, but calling + * Play() twice before the render thread notices is fine. */ + +if (!winetest_platform_is_wine) +{ + hr = IXACT3Wave_Stop(wave, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_STOPPING || state == XACT_STATE_STOPPED, "Got state %#lx.\n", state); + hr = IXACT3Wave_Play(wave); + ok(hr == XACTENGINE_E_INVALIDUSAGE, "Got hr %#lx.\n", hr); + + hr = IXACT3Wave_Stop(wave, XACT_FLAG_STOP_IMMEDIATE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_Stop(wave, XACT_FLAG_STOP_IMMEDIATE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_STOPPED, "Got state %#lx.\n", state); +} + + hr = IXACT3WaveBank_Prepare(wavebank, 1, XACT_FLAG_UNITS_MS, 100, 2, &wave); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetProperties(wave, &wave_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(wave_props.properties.format.wFormatTag == WAVEBANKMINIFORMAT_TAG_ADPCM, + "Got format %u.\n", wave_props.properties.format.wFormatTag); + ok(!wave_props.backgroundMusic, "Got background music %d.\n", wave_props.backgroundMusic); + + hr = IXACT3Wave_Pause(wave, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == (XACT_STATE_PREPARED | XACT_STATE_PAUSED), "Got state %#lx.\n", state); + hr = IXACT3Wave_Pause(wave, FALSE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == XACT_STATE_PREPARED, "Got state %#lx.\n", state); + + hr = IXACT3Wave_Pause(wave, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == (XACT_STATE_PREPARED | XACT_STATE_PAUSED), "Got state %#lx.\n", state); + /* Unlike with cues, Play() while PREPARED and PAUSED does nothing. + * Even if you unpause and wait, it'll remain in PREPARED. */ + hr = IXACT3Wave_Play(wave); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(state == (XACT_STATE_PREPARED | XACT_STATE_PAUSED), "Got state %#lx.\n", state); + hr = IXACT3Wave_Pause(wave, FALSE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetState(wave, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(state == XACT_STATE_PREPARED, "Got state %#lx.\n", state); + + hr = IXACT3WaveBank_Prepare(wavebank, 2, XACT_FLAG_UNITS_MS, 100, 2, &wave); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetProperties(wave, &wave_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(wave_props.properties.format.wFormatTag == WAVEBANKMINIFORMAT_TAG_WMA, + "Got format %u.\n", wave_props.properties.format.wFormatTag); + ok(!wave_props.backgroundMusic, "Got background music %d.\n", wave_props.backgroundMusic); + + /* The background music flag is documented as being ignored, but it's at + * least still recorded and propagated to the properties. */ + hr = IXACT3WaveBank_Prepare(wavebank, 2, XACT_FLAG_UNITS_MS | XACT_FLAG_BACKGROUND_MUSIC, 100, 2, &wave); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IXACT3Wave_GetProperties(wave, &wave_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine ok(wave_props.backgroundMusic == TRUE, "Got background music %d.\n", wave_props.backgroundMusic); + + refcount = IXACT3Engine_Release(engine); + todo_wine ok(!refcount, "Got outstanding refcount %ld.\n", refcount); +} + START_TEST(xact3) { + IXACT3Engine *engine; + HRESULT hr; + CoInitialize(NULL);
+ hr = CoCreateInstance(&CLSID_XACTEngine, NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void **)&engine); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /* Win 10 v1507 */, "Cannot create engine, hr %#lx\n", hr); + + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip("XACT is not supported.\n"); + return; + } + IXACT3Engine_Release(engine); + test_interfaces(); test_notifications(); + test_properties();
CoUninitialize(); }