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

Allow user to specify MMDevice when initialising WasapiCapture and WasapiLoopbackCapture #124

Closed
njbmartin opened this issue Aug 1, 2016 · 10 comments

Comments

@njbmartin
Copy link

njbmartin commented Aug 1, 2016

My preview issue #123 raised another potential overload, as both WasapiCapture and WasapiLoopbackCapture assume the default device should be used.

Currently, you can only change the device after initialising the instance, but even then, it has already been initialised with the default device settings (eg. WaveFormat), and you can't change the WaveFormat. Correction, it's not initialised unless specified in the overload.

So there are few potential things here:

  • Add MMDevice to the beginning of the overloads and assume that null uses default.
  • Allow user to customise/change both Device and WaveFormat after the instance has been initialised.
  • Allow a user to modify some properties of WaveFormat and apply it to the capture.
@njbmartin
Copy link
Author

Corrected myself above.

@filoe
Copy link
Owner

filoe commented Aug 1, 2016

It is technically not possible to change to device after WasapiCapture got initialized because the initialization process initializes the devices and sets up all native objects based on this device.
However you can change the device by selecting the device before you call the Initialize method. If you change it afterwards, you will have to select to stop capturing and call Initialize again.

I can't add the MMDevice to the beginning of the overloads, because it would be modication which makes existing code incompatible with the new release. Maybe I could add this to a new major release.

Allowing the user to modify some properties of WaveFormat is quite tricky. The WaveFormat gets choosen by the Initialize method. You can't modify it after calling Initialize. Anyway, it is not the purpose of a class, implementing the ISoundIn interface, to do lots of format conversion. For that purpose, there are existing classes you can use to convert the format to whatever you want.
You would have to create an IWaveSource objects based on the ISoundIn objects using the SoundInSource class. Afterwards you can use the common conversion extension methods or extra classes. You can do whatever you want. From changing the samplerate to applying a channel conversion matrix, ...

@njbmartin
Copy link
Author

My apologies, I had a feeling that might be confusing.

Let me explain.

Initialise the object:

_capture= new WasapiCapture();

At this point (before you the initialize() method), you can modify the Device it uses with:

_capture.Device = newDevice;

But you currently can't specify the WaveFormat as it doesn't have a set method.

@filoe
Copy link
Owner

filoe commented Aug 1, 2016

Correct, but as I've said before. You can't set the WaveFormat because it depends on the driver. WasapiCapture chooses a WaveFormat, supported by the driver. If you need a specific format, do the conversion outside of WasapiCapture. Do you need a specific format as output format?

@njbmartin
Copy link
Author

Changing the WaveFormat mainly relates to my issue raised in #123 in which I needed to modify the channels.

@filoe
Copy link
Owner

filoe commented Aug 2, 2016

That issue already got resolved by overloading the ctor...?

@njbmartin
Copy link
Author

It did yes, but that assumes the default endpoint is used whereas this issue aims to address the ability to choose any device.

@filoe
Copy link
Owner

filoe commented Aug 2, 2016

What about this code:

var captureDevice = MMDeviceEnumerator.EnumerateDevices().First(); //implement your logic for selecting a device...
var deviceFormat = captureDevice.DeviceFormat;
var waveFormat = new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, Math.Min(deviceFormat.Channels, 2));
_wasapiCapture = new WasapiLoopbackCapture(100, waveFormat);
_wasapiCapture.Device = captureDevice;
_wasapiCapture.Initialize();

_wasapiCapture...

@njbmartin
Copy link
Author

Yep, I've used that code too. Alright, guess I'll close this issue then.

@filoe
Copy link
Owner

filoe commented Aug 2, 2016

I've added a tiny sample that should demonstrate the whole thing...

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

No branches or pull requests

2 participants