используя аудио конечную точку, отличную от DefaultAudioEndpoint в C # - PullRequest
0 голосов
/ 29 ноября 2018

Эта программа представляет собой аудио-визуализатор для клавиатуры rgb, которая прослушивает аудиоустройство Windows по умолчанию.Моя настройка звука немного сложнее, и я использую гораздо больше, чем просто аудиоустройство по умолчанию.Например, когда я играю музыку с Winamp, она проходит через устройство Auxillary 1 (Synchronous Audio Router) вместо Desktop Input (Synchronous Audio Router), которое я установил по умолчанию.Я хотел бы иметь возможность сменить устройство, которое программа слушает для визуализации.

Я нашел в источнике, где объявлено аудиоустройство;Строки 32-36 в CSCoreAudioInput.cs:

public void Initialize()
{
    MMDevice captureDevice = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console);
    WaveFormat deviceFormat = captureDevice.DeviceFormat;
    _audioEndpointVolume = AudioEndpointVolume.FromDevice(captureDevice);
}

Насколько я понимаю из документации , в разделе MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console) Windows предоставляет приложению мой стандартный IMMEndpoint для рабочего столаВвод. "

Как мне изменить DefaultAudioEndpoint?

Дальнейшее чтение показывает несколько способов получить IMMDevice, одним из которых является DefaultAudioEnpoint,Мне кажется, что я должен был бы перечислить устройства, а затем выделить Auxillary 1 (Synchronous Audio Router), используя PKEY_Device_FriendlyName.Это немного для меня, так как у меня мало опыта.Есть ли более простой способ выбора другой конечной точки?Я на правильном пути?или я полностью пропускаю отметку?

Кроме того, в чем разница между MMDevice и IMMDevice?Источник, кажется, использует только MMDevice, в то время как все ссылки на документацию Microsoft IMMDevice.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 10 марта 2019

Меня попросили решить проблему подобного типа на этой неделе.Несмотря на то, что для этого есть несколько библиотек, меня специально попросили сделать это для программистов «не ish», поэтому я разработал это в PowerShell.

Устройство смены аудиоустройств по умолчанию Powershell - Github

Может быть, вы можете изменить его для своих нужд.

0 голосов
/ 12 февраля 2019

Я СДЕЛАЛ ЭТО!

Я выяснил, почему программа использует MMDevice вместо IMMDevice.Разработчик решил использовать библиотеку CSCore , а не собственный Windows Audio API Windows.

Из прочтения документации CSCore MMDeviceEnumerator похоже, что я "Придется создать отдельную программу, которая выводит все конечные точки и соответствующие им строки идентификаторов конечных точек.Затем я могу заменить метод DefaultAudioEndpoint на метод GetDevice(String id), где String id - это идентификатор любой конечной точки, которую я выбрал из отдельной программы.

Чтобы найти нужную конечную точку, я написал этокороткая программа, чтобы найти всю информацию, которую я хотел:

static void Main(string[] args)
    {
        MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
        MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
        Console.WriteLine($"\nNumber of active Devices: {collection.GetCount()}");

        int i = 0;
        foreach (MMDevice device in collection){

            Console.WriteLine($"\n{i} Friendly name: {device.FriendlyName}");
            Console.WriteLine($"Endpoint ID: {device.DeviceID}");
            i++;
        }
        Console.ReadKey();
    }

Это показало мне, что конечной точкой, которую я хотел, была позиция 3 (2 в массиве) в моем списке, и вместо использования GetDevice(String id) я использовалItemAt(int deviceIndex).

MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
MMDevice captureDevice = collection.ItemAt(2);

Однако в этом случае программа не использовала captureDevice для ввода аудиоданных.Это были магические строки:

_capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i));
_capture.Initialize();

Я обнаружил, что WasapiLoopbackCapture использует устройство Windows по умолчанию, если оно не изменилось, и код использовал DefaultAudioEndpoint, чтобы получить свойства устройства по умолчанию.Поэтому я добавил

_capture.Device = captureDevice;
//before
_capture.Initialize();

И теперь программа правильно извлекает аудиоданные из моей конечной точки звука, отличной от используемой по умолчанию.

...