Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Get current ports of sink and source devices #1017

Open
Switch0621 opened this issue Jul 9, 2024 · 2 comments
Open

[Question] Get current ports of sink and source devices #1017

Switch0621 opened this issue Jul 9, 2024 · 2 comments

Comments

@Switch0621
Copy link

Switch0621 commented Jul 9, 2024

Greetings!
Please advice me, how can i get actual info about current sink and source ports?

I want to my app is notifying user about connecting/disconnecting microphone and headphones. So, two state - no active sink/source port : active port is port name

P.S.: likely error, after set log callback, i open device (with empty name) and create context for this device and all is freezed.

@kcat
Copy link
Owner

kcat commented Jul 10, 2024

Calling alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER) (or alcGetString(NULL, ALC_DEVICE_SPECIFIER) if ALC_ENUMERATE_ALL_EXT isn't supported) will return a nul-separated list of available device names. Like this:

const char *names = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
while(names && *names)
{
    printf("%s\n", names);
    names += strlen(names)+1;
}

It shouldn't freeze creating a context. Even if there's no devices, opening the default devices (using an empty name) should fail if there's nothing to open. Or if there is a device but it's unusable, opening the device or creating the context should fail. Something's wrong if it freezes. Can you provide a backtrace from a debug build?

@Switch0621
Copy link
Author

Switch0621 commented Jul 13, 2024

I think to compile a little CSharp project is more simple way.
There is a code of simple console application in dotnet8.0 on Linux:

`
using System.Runtime.InteropServices;

namespace ConsoleApp1;

class Program
{
private const string OpenAlLinux = "libopenal.so.1";
private static IntPtr _openalLinux = IntPtr.Zero;

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate void LogDelegate(IntPtr user, char level, string message, int length);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private delegate void LogCallbackSetter(LogDelegate callback, IntPtr user);

[DllImport(OpenAlLinux, EntryPoint = "alGetProcAddress", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress([In] string fname);

[DllImport(OpenAlLinux, EntryPoint = "alcOpenDevice", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern IntPtr OpenDevice([In] string devicename);

[DllImport(OpenAlLinux, EntryPoint = "alcCloseDevice", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern bool CloseDevice([In] IntPtr device);

[DllImport(OpenAlLinux, EntryPoint = "alcCreateContext", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr CreateContext([In] IntPtr device, [In] int[] attributeList);

private static IntPtr CreateContext(IntPtr device, OpenAlContextAttributes attributes) => CreateContext(device, attributes.CreateAttributeArray());

[DllImport(OpenAlLinux, EntryPoint = "alcDestroyContext", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern void DestroyContext(IntPtr context);

static void Main(string[] args)
{
    // load openAl library
    _openalLinux = NativeLibrary.Load(OpenAlLinux);
    if (_openalLinux == IntPtr.Zero)
        throw new Exception("Can't load library libopenal.so");
    
    // set log callback
    var sptr = GetProcAddress("alsoft_set_log_callback");
    var logSetter = Marshal.GetDelegateForFunctionPointer<LogCallbackSetter>(sptr);
    logSetter.Invoke(AlLogCallback, IntPtr.Zero);
    
    // try to create context

    var contextAttributes = new OpenAlContextAttributes();
    var defaultPlayingDevice = OpenDevice(string.Empty);
    var defaultPlayingDeviceContext = IntPtr.Zero;
    if (defaultPlayingDevice != IntPtr.Zero)
        defaultPlayingDeviceContext = CreateContext(defaultPlayingDevice, contextAttributes);
    
    // wait
    Console.ReadKey();
    
    // dispose
    if (defaultPlayingDeviceContext != IntPtr.Zero)
        DestroyContext(defaultPlayingDeviceContext);
    if (defaultPlayingDevice != IntPtr.Zero)
        CloseDevice(defaultPlayingDevice);
}

private static void AlLogCallback(IntPtr user, char level, string message, int length) { }

}
`

The program is shutdown on context creation.
If i comment 'set log callback' code block - it's working fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants