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.17k stars 450 forks source link

Redirecting existing playback to another device #83

Closed IliasP91 closed 8 years ago

IliasP91 commented 8 years ago

Hello.

I am trying to re route an existing audio session to a different playback device than the default one it is initialized on.

I am using C# and naudio library that wraps wasapi, but until now i am unable to do it. The api does not offer the implementation to do that.

So i was wondering if i can achieve it with your library.

Kindly waitting for your reply.

filoe commented 8 years ago

I don't know an api which would make that possible. After initializing the AudioRenderClient, you can't redirect it to another device. That behaviour makes sense, because you don't know which formats the target device support. You have to check all these things again before playing it on another device. Hopefully that answers your questions.

IliasP91 commented 8 years ago

Hello again and thank you for your time.

Yeah after some exxtensive search on win api's I though it too.

A way to achieve that effect could be if somehow I can get a refference of an existing session's output stream, then initialize a new session on another device from MY application, with the existing session's icon, title and stream and start it.

I don't know if it's the correct approach on it.

I do know 2 programmers that have done it, the one is in C++ (where I have zero experience) and the other one is unknown, propably .net 3.5.

They both wont disclose any info further than "you have to add the functionality in wasapi in the runtime" which gives me no leads.

I've been smashing my head for around a 2 weeks now and ive got no solution so far..

Any help would be most welcome!

filoe commented 8 years ago

In theory, you are able to play audio on any audio session you want. See https://msdn.microsoft.com/en-us/library/windows/desktop/dd370875(v=vs.85).aspx

IliasP91 commented 8 years ago

Good morning.

Yeah I though a little more about the procedure last night.

I ended up with a way to fake the routing.

I could create a "clone" of an existing audio session through my application with the help of audioclient:initialize method.

I can get the icon and name of an existing session, and pass them to the new one. After that i come up to 2 problems, 1st I do now know how to get a reference to a session's stream, in order to start it on the new session I will create, and 2nd what is the best way to silence the old session. (Turn its state to expired/invalid? Mute it? Find a way to force kill the session?)

Do you have any ideas on those issues?

Thanks a lot again for your time.

filoe commented 8 years ago

Well, you can specify an AudioSessionGuid while calling Initialize. I have never tried it but there is something like cross process sessions. So you it maybe could be possible to use an existing session from another process and call stream to it.

IliasP91 commented 8 years ago

Hi again. Hm probably you misunderstood what I am trying to achieve or I dont know well the api as you do. Let me provide an example to be more clear.

Lets say I have an audio management app that uses cscore (wasapi wrapper) from where I want to manage the current audio sessions.

My audio output devices are: 1: Realtek Device(Default Playback Device) 2: Asus Device(Which can play same audio formats as the default one)

We have a running audio session for example Google Chrome that plays audio on the default playback device, Realtek Device.

I would like to provide 2 functions on that, first to be able to "route" it to another device than the one its currently playing, and secondly to be able to "clone" it to a second device to play simultaneously alongside the default one.

The way I thought to achieve it is:

Obtain the current google chrome audio session info (title,icon and audio stream), initialize a new session with a new GUID on ASUS device, give it the info from google chrome session which plays on the default device and start it.

After that optionally i could either mute or stop the session on the default device.

That way i will virtually reroute the playback to another device without messing with the apis internals.

Through the audioclient:initialize method i can create a new session and assign it to a new GUID or an existing GUID.

My problem as I see it is how can i get a refference to an existing session's stream to pass it on a new session, and secondly how can i stop an existing session.

Thanks again.

filoe commented 8 years ago

To be honest, I don't know whether this is possible at all(without hooking wasapi objects). I really don't know :(.