filoe / cscore

An advanced audio library, written in C#. Provides tons of features. From playing/recording audio to decoding/encoding audio streams/files to processing audio data in realtime (e.g. applying custom effects during playback, create visualizations,...). The possibilities are nearly unlimited.
Other
2.14k stars 450 forks source link

CSCORE AudioClient initializing problem or problem elsewhere? #475

Open crashdummie opened 1 year ago

crashdummie commented 1 year ago

Hi!

I´m trying to write a program that captures a USB microphone and fills a byte array defined in the code. Eventually the bytes will undergo FFT analysis and other stuff. The essentials of the capturing code is as follows:


using CSCore.CoreAudioAPI;

MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator(); MMDeviceCollection allDevices = deviceEnum.EnumAudioEndpoints(DataFlow.Capture, DeviceState.Active);

NOfDevices = 0;

foreach (var listDevice in allDevices) { deviceBox.Items.Add(listDevice); NOfDevices++; }//Devicebox is a combobox

ConnectedDevNbr = deviceBox.SelectedIndex;//Number from click in DeviceBox microphoneDevice = allDevices[ConnectedDevNbr];

waveFormat = new WaveFormat(44100, 16, 1, AudioEncoding.Pcm);//This format is supported (has been tested). long samplesByteArrayDurationTime = (882 8) / (44100 16 * 1);//Extra time calculation for 882 bytes. Returns 10 ms.

AudioClient auCli = AudioClient.FromMMDevice(microphoneDevice); auCli.GetDevicePeriodNative(out long DefaultDevicePeriod, out long MinimumDevicePeriod);//Returns 100 000 = 10 ms (100 000 x 100 ns). auCli.Initialize(AudioClientShareMode.Exclusive, AudioClientStreamFlags.None, DefaultDevicePeriod, DefaultDevicePeriod, waveFormat, Guid.Empty); auCli.Start();

long endpointBufferSize = auCli.GetBufferSize();//Returns 2646 which is 3 * 882 bytes, i.e. 3 times the length of the expected 882 bytes.

AudioCaptureClient auCapCli = AudioCaptureClient.FromAudioClient(auCli);//Creates a new AudioCaptureClient IntPtr endpointBufferPointer = auCapCli.GetBuffer(out int NOfFramesInPacket, out AudioClientBufferFlags auCliBufferFlags);//Retrieves a pointer to the next available packet in endpoint buffer.

byte[] samplesByteArray = new byte[882]; Marshal.Copy(endpointBufferPointer, samplesByteArray, 0, 882);


PROBLEMS:

1.In auCli.Initialize I don´t know where to find the sessionguid. For now Guid.Empty is used.

  1. The fact that endpointBufferSize is 3 times the length of the expected 882 bytes puzzles me. In the DeviceBox 3 devices turn up, which maybe could have something to do with it?

  2. The endpointBufferPointer returns 0 which maybe indicates that auCli has not been initialized properly, or?

  3. Marshal.Copy complains about that the source (= endpointBufferPointer) is not allowed to be 0.

Please help me if you can! By asking you I have not taken the easy way out! Many days have been spent on this problem alone.

filoe commented 1 year ago

Use WasapiCapture class. The usage of the device api is quite complex. If you dont want to use WasapiCapture, you can take a look at the class as exampleAm 21.09.2022 um 11:38 schrieb crashdummie @.***>: Hi! I´m trying to write a program that captures a USB microphone and fills a byte array defined in the code. Eventually the bytes will undergo FFT analysis and other stuff. The essentials of the capturing code is as follows:

using CSCore.CoreAudioAPI; MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator(); MMDeviceCollection allDevices = deviceEnum.EnumAudioEndpoints(DataFlow.Capture, DeviceState.Active); NOfDevices = 0; foreach (var listDevice in allDevices) { deviceBox.Items.Add(listDevice); NOfDevices++; }//Devicebox is a combobox ConnectedDevNbr = deviceBox.SelectedIndex;//Number from click in DeviceBox microphoneDevice = allDevices[ConnectedDevNbr]; waveFormat = new WaveFormat(44100, 16, 1, AudioEncoding.Pcm);//This format is supported (has been tested). long samplesByteArrayDurationTime = (882 8) / (44100 16 1);//Extra time calculation for 882 bytes. Returns 10 ms. AudioClient auCli = AudioClient.FromMMDevice(microphoneDevice); auCli.GetDevicePeriodNative(out long DefaultDevicePeriod, out long MinimumDevicePeriod);//Returns 100 000 = 10 ms (100 000 x 100 ns). auCli.Initialize(AudioClientShareMode.Exclusive, AudioClientStreamFlags.None, DefaultDevicePeriod, DefaultDevicePeriod, waveFormat, Guid.Empty); auCli.Start(); long endpointBufferSize = auCli.GetBufferSize();//Returns 2646 which is 3 882 bytes, i.e. 3 times the length of the expected 882 bytes. AudioCaptureClient auCapCli = AudioCaptureClient.FromAudioClient(auCli);//Creates a new AudioCaptureClient IntPtr endpointBufferPointer = auCapCli.GetBuffer(out int NOfFramesInPacket, out AudioClientBufferFlags auCliBufferFlags);//Retrieves a pointer to the next available packet in endpoint buffer. byte[] samplesByteArray = new byte[882]; Marshal.Copy(endpointBufferPointer, samplesByteArray, 0, 882);

PROBLEMS: 1.In auCli.Initialize I don´t know where to find the sessionguid. For now Guid.Empty is used.

The fact that endpointBufferSize is 3 times the length of the expected 882 bytes puzzles me. In the DeviceBox 3 devices turn up, which maybe could have something to do with it?

The endpointBufferPointer returns 0 which maybe indicates that auCli has not been initialized properly, or?

Marshal.Copy complains about that the source (= endpointBufferPointer) is not allowed to be 0.

Please help me if you can! By asking you I have not taken the easy way out! Many days have been spent on this problem alone.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

crashdummie commented 1 year ago

Thank you for your answer: I have been trying to get a complete sollution by WinMM, Wasapi and CoreAudioAPI so far, and I´m ready to go back to Wasapi again if you believe that´s where I´ll manage the best.

//CD