amerkoleci / Vortice.Windows

.NET bindings for Direct3D12, Direct3D11, WIC, Direct2D1, XInput, XAudio, X3DAudio, DXC, Direct3D9 and DirectInput.
MIT License
1.01k stars 73 forks source link

The type 'WaveFormat' exists in both 'Vortice.DirectX' and 'Vortice.Multimedia' #443

Closed shellohunter closed 4 months ago

shellohunter commented 4 months ago
The type 'WaveFormat' exists in both 'Vortice.DirectX, Version=3.5.0.0, Culture=neutral, PublicKeyToken=5431ec61a7e925da' and 'Vortice.Multimedia, Version=1.8.0.0, Culture=neutral, PublicKeyToken=null' 

This error showed up in a small demo project that uses Vortice.XAudio2 & Vortice.MultiMedia & Vortice.MediaFoundation. these packages were installed via nuget.

I cannot figure a way to get rid of this... any help is appreciated.

btw, the project was targeting .net 4.7.2, is it ok?

amerkoleci commented 4 months ago

You need to remove Vortice.Multimedia package reference as it is deprecated

shellohunter commented 4 months ago

Great! Removing Vortice.Multimedia do eliminated that error. Thanks

But the code run into an exception immediately:

Exception thrown: 'SharpGen.Runtime.SharpGenException' in SharpGen.Runtime.dll
The thread '[Thread Destroyed]' (17364) has exited with code 0 (0x0).
'testhost.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.5\System.Diagnostics.StackTrace.dll'. 
SharpGen.Runtime.SharpGenException: HRESULT: [0x88960001], Module: [Vortice.XAudio2], ApiCode: [XAUDIO2_E_INVALID_CALL/InvalidCall]
   at SharpGen.Runtime.Result.ThrowFailureException()
   at SharpGen.Runtime.Result.CheckError()
   at Vortice.XAudio2.IXAudio2SourceVoice.SubmitSourceBuffer(AudioBuffer buffer, Nullable`1 bufferWMA)
   at Vortice.XAudio2.IXAudio2SourceVoice.SubmitSourceBuffer(AudioBuffer buffer, UInt32[] decodedXMWAPacketInfo)
   at ClientTest.MirSounds.Tests.VorticeTests.TestVorticleXAudio2() in E:\workspace\oss\MiSounds\VorticeTest.cs:line 36
'testhost.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\PrivateAssemblies\Runtime\Microsoft.VisualStudio.Debugger.Runtime.NetCoreApp.dll'. 

the code was taken from here: https://github.com/amerkoleci/Vortice.Windows/blob/main/src/samples/HelloXAudio2/Program.cs I just wrapped it as a unit test method.

exception line was: https://github.com/amerkoleci/Vortice.Windows/blob/e4a2fb506ad42a17b181d8b81c9f5dbe25af0624/src/samples/HelloXAudio2/Program.cs#L36

shellohunter commented 4 months ago

Actually I'm try to test the native aot compatibility of any xaudio libs. Previously I failed to make sharpdx work with native aot. not sure if Vortice is aot compatible.

amerkoleci commented 4 months ago

It is but you need to use latest version

shellohunter commented 4 months ago

no luck yet. the exception mentioned above always happens. I try to debug it:

    internal unsafe void SubmitSourceBuffer(AudioBuffer buffer, BufferWma? bufferWMA)
    {
        AudioBuffer.__Native @ref = default(AudioBuffer.__Native);
        buffer.__MarshalTo(ref @ref);
        BufferWma value = default(BufferWma);
        if (bufferWMA.HasValue)
        {
            value = bufferWMA.Value;
        }
        Result result = ((delegate* unmanaged[Stdcall]<nint, void*, void*, int>)base[21])(base.NativePointer, &@ref, (!bufferWMA.HasValue) ? null : (&value));
        buffer.__MarshalFree(ref @ref);
        result.CheckError();  // <------ SharpGen.Runtime.SharpGenException here. beyond my reach.
    }

after changing playback code to sharpdx.xaudio2, it works without any issue.

amerkoleci commented 4 months ago

Share some code so I can help out

shellohunter commented 4 months ago

I'm using a demo project with only 2 files.

VorticeXAudio2Test.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vortice.XAudio2;
using Vortice.Multimedia;

namespace TestXAudio2
{
    internal class VorticeXAudio2Test
    {

// Copyright (c) Amer Koleci and contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.

    public static async Task TestVorticeXAudio2(string filePath)
    {
        // Create the XAudio2 engine.
        using IXAudio2 audio = XAudio2.XAudio2Create(ProcessorSpecifier.DefaultProcessor);

        // The engine is already in the started state when initialized.
        // In other cases, the following call will start the audio engine.
        // XAudio.StartEngine();

        // Create mastering voice.
        using IXAudio2MasteringVoice masterVoice = audio.CreateMasteringVoice();

        // Define wave format.
        WaveFormatExtensible format = new(96000, 24, 2);

        // Create source voice for buffer submission.
        using IXAudio2SourceVoice voice = audio.CreateSourceVoice(format, false);

        // Load sound effect into audio buffer.
        using Stream stream = new MemoryStream(File.ReadAllBytes(filePath));
        SoundStream soundStream = new(stream);
        using AudioBuffer effectBuffer = new(soundStream.ToDataStream());

        // Play buffer.
        voice.SubmitSourceBuffer(effectBuffer, null);
        voice.Start(0);

        Console.SetCursorPosition(0, 0);
        Console.WriteLine("Playing sound effect 'SpaceVehicleFlyby.wav'");

        // XAudio2 is a non-blocking API, so wait for the buffer to finish
        // playing before allowing the program to complete.
        bool isPlaying = true;
        while (isPlaying)
        {
            isPlaying = voice.State.BuffersQueued != 0;
            Console.Write('.');
            await Task.Delay(100);
        }
    }
    }
}

Program.cs:

using System.Threading;
using System.Threading.Tasks;

namespace TestXAudio2
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            string audio = @".\BD60.wav";
#if true // the sound manager uses SharpDx, which works fine.
            SoundManager.PlayAudioFile(audio);
            Thread.Sleep(10000);
#else
            Task.Run(async ()=> { await VorticeXAudio2Test.TestVorticeXAudio2(audio); });
            Thread.Sleep(10000000);
#endif
        }
    }
}
shellohunter commented 4 months ago

lucky day! I just made it work! It turns out that the .wav file I was using is somehow different from the one in your demo project. Tried a lot of wav files, only a few works. THEN, I realized that I should use the MediaFoundation lib with XAudio2! after the integration, all wav plays with no issue!