Avoiding echo feedback when recording with AVAudioEngine without headphones - core-audio

I am using AVAudioEngine to record a user's voice while applying some real-time effects to the voice.
As I need the user to be able to hear his own voice during the session, I've hooked up my AVAudioEngine graph to look like the following:
inputNode -> audio effect node -> mainMixerNode (tap installed here) -> outputNode
I also installed a node tap at the mainMixerNode to pull the processed voice and save it into a buffer.
All these work fine when I have the headphones plugged in. However, when I unplug the headphones halfway during the recording, I experience a lot of sharp echoes and feedback. I guess this is due to the fact that the voice is being sent to the output for playing which in turn reinforces the user's original input voice.
Is there a good way to minimize the feedback in the event that the headphones are unplugged halfway during the recording session? I've thought of dynamically disconnecting the mainMixerNode so that the voice will not route to the output during unplugging, but I am not sure if there is a better way.
Ideally I would like to have a single audio buffer at the end of each recording session, no matter how many times the user plugs and unplugs the headphones within the session.
Any thoughts? Thanks in advance!

use other Node to change volume to 0, then connect to outputNode.
audioEngine.connect(mainMixerNode, to: otherNode, format: yourFormat)
otherNode.volume = 0
audioEngine.connect(otherNode, to: outputNode, format: yourFormat)

Related

Injecting to a DX game and make game idle

I have a DLL that I am injecting to DX games. In the DLL, I am disabling XInput, raw input and also subclass WndProc to filter a bunch of input messages like WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_INPUT etc. Disabling XInput with XInputEnable(FALSE) and register raw devices with RIDEV_REMOVE flag.
While it works great for some games, it doesn't work for all. Certain games still have mouse move/hover input and I can see hover state for some UI when I move over.
My question is what did I miss? Could the game be capturing input some other ways?
Thank you.
I can think of these possible ways the application may still be receiving mouse input:
It re-enables Raw Input notifications
A window other than you one subclassed is receiving the messages
It's polling GetCursorPos
Using the Windows HID API or other user-mode interface to access the mouse device
Hooking mouse events or windows message using SetWindowsHookEx
The are probably others, but these are all I can think of at the moment.

Do device drivers communicate with each other, or are they asynchronously called?

I will paint an example of what I am asking in crystal clear detail.
Say we are in a typical userland app, like painting software or text editing, and we decide to hover the mouse or click a combo box. From this input alone the mice's trackball will need to be fetched from the device driver on the low-level, but the video driver will also need to update the position of the pointer on the screen accordingly at the (seemingly) same time as follows:
As the picture illustrates, not moving the mouse, but calling the driver/updating the screen constantly works. However, what if we choose to both click the menu combo box/drop down list, and update the framebuffer feed constantly? Are both drivers called almost at the same time, and what calls them (the GUI desktop, the app directly, etc.). Because the mouse works ANYWHERE, on an app or not ... that makes me question if the mouse input is indefinitely system called, however, video output depends more on what the app is(like below, texpad).
The mouse driver has nothing to do with the video driver. You're getting the distinction wrong between what happens in the kernel space and user space.
The kernel has no idea of a concept of a 'mouse pointer'. It only exports an interface saying, "I have a input device that gives X and Y coordinates". Likewise with the video driver, it only exports an interface saying, "I have a device where you can output pictures" - it doesn't know what a mouse pointer is.
The GUI is all handled in user space and that's where you get the concept of drop down boxes, mouse pointers etc... Whatever program handles your GUI takes the kernel interfaces and does stuff with it, such as associating the input device with a mouse pointer and outputting video to the screen.
How the contents of the screen is actually pushed to the hardware will be driver dependent and doesn't involve user space. The GUI just tells the kernel, "I want the screen to look like this" and the kernel handles the rest.
Both drivers can certainly run in parallel if you have a multi-core CPU but, unless you're implementing the driver or scheduler, you don't need to know the details.

Chromecast Receiver App - Media state changed: time_progress event

When testing my Receiver app and watching the console, I see a line created by cast_receiver.js that says:
[ 3.034s] [cast.receiver.RemoteMedia] Media state changed: time_progress=false
Eventually, when the video is playing, I get a message that says:
[ 3.034s] [cast.receiver.RemoteMedia] Media state changed: time_progress=true
Is there an event I can monitor from the RemoteMedia API that will allow me to tie in to this 'time_progress' event? I am trying to hide and show a loader when the video is loading. Currently i show and hide the loader based on the 'timeupdate' event from the video element, however, this event has proven to not be reliable for me.
Thanks
Rather than trying to attach to the the status message above, you will be better off just attaching to the playing event for the video media element.
On the sender side, you will get status update if time_progress changes. On the receiver side, you can't directly register to be notified if time_progress is updated but there are ways around that if it is absolutely needed. As Les mentioned, listening on the video element's events is the best way to go.
Mike, I had a similar issue at one point and I used a counter inside the time_update listener to basically keep track of how many times time_update has been called before removing the spinner. Generally I found that 2-4 calls and then you can be sure that the video is playing. Once the counter reaches it's goal then I remove the listener from within the listener. The downside is you have to reattach the listener anytime the video pauses, etc.

Is it possible to programmatically prevent a game from pausing when its window loses focus?

I'm playing Skyrim in windowed mode and I am trying to create a bot for this game for personal use. I would like to have the bot play the game in the background, while I do other things, the only problem is that the game window pauses when it loses focus. Is there a way to make the Skyrim process think that it still has the focus, so it continues to run while I do something else on another window? I'm not a windows programming expert but would this be possible if I could somehow intercept the message that says unfocused or minimized to the process, and thus let the process think its still focused?
It's possible. You need to find the mechanism through which the game checks whether it's in the foreground then trick it into thinking the switch has not occurred. This will require a certain amount of reverse engineering on your part. There are many different ways that this checking can actually be done by the game.
You can try to play with hooking one of the following messages/functions: WM_KILLFOCUS, WM_ACTIVATE, GetForegroundWindow. On the other hand, the game might be doing something funky with DirectX. I don't have much experience there.
To re-iterate, to do this properly you are really going to have to find out exactly how the game does the checking (and then subvert that).

Using control send on windows live messenger For auto typing text

Hi i want to make a sort of a bot for WLM,
But the normal controlsend in autoit wont work
the basic question is how can i send a text to the windows live messenger window Without activating it?
Example:
There is someone in WLM with the window active called "Joop" I do:
ControlClick("Joop","","[CLASS:DirectUIHWND; INSTANCE:2]","Left",1,322,507)
ControlSend("Joop","","[CLASS:DirectUIHWND; INSTANCE:2]","Hi Joop")
this doesn't work however when I do this
WinActivate("Joop","")
ControlClick("Joop","","[CLASS:DirectUIHWND;INSTANCE:2]","Left",1,322,507)
ControlSend("Joop","","[CLASS:DirectUIHWND; INSTANCE:2]","Hi Joop")
it does work however now its activated what i dont want.
there is a problem with the window the whole msn talk window is one window so no extra control to type in thats why i tried the contolClick on the coordinates of the typing screen without succ6
this is the summary.
Text:
Position: 0, 28
Size: 882, 607
ControlClick Coords: 282, 180
Style: 0x56000000
ExStyle: 0x00010000
Handle: 0x00190916
>>>> Mouse <<<<
Position: 1885, 557
Cursor ID: 0
Color: 0xFFFFFF
>>>> StatusBar <<<<
>>>> Visible Text <<<<
>>>> Hidden Text <<<<
CVoiceVideoAvatarHostWindow
does anyone know how to get something in that textfield without activating it (so it can run on background) and using a lame function like send.
OR how can i send a text to the windows live messenger window Without activating it
Thanks
Matthy
MSN is purposefully resisting automation. It's not a limitation of the Windows API. If your goal is to automate a MSN chat, you can do so either by directly sending the TCP packets, or by automating another application which supports MSN (Digsby, Pidgin, etc.) and which works better with automation.
By directly sending the TCP packets you are writing your own program, from scratch, which to the outside world behaves just as MSN. There are user-made documentation about the protocol. One that I have used in the past is here: http://www.hypothetic.org/docs/msn/notification/authentication.php but I am entirely unsure whether it is still up-to-date. If you are familiar with networking, TCP, packet capturing and replaying, then I do suggest going this route as it's the most stable, long-term approach. (And I think: The most fun.)
However, not all projects demand a stable and long-term approach. It seems to me like you were just messing with automating some of the applications you happened to have on your computer, and MSN is of course one of the more interesting ones. Microsoft decided that when they built the MSN client it should not be made easy for anyone to try and automate the application. I think this was mostly done to prevent spam. In the early days it worked, because other people hadn't yet publically documented the protocol. And thus anyone who wanted to spam now had to make a costly investment.
If you do decide to continue with automating the official MSN client, or any other application that resists automation, there are a few tricks that you can try:
ControlSend without specifying the control parameter (use empty string "")
ControlClick on the window with specifying coordinates with using empty string for control parameter again
Eventually, simply Send/MouseClick with optional BlockInput
There are a lot more combinations that you can try (especially ControlX functions) that sometimes miraculously will work, but remember that in the end they are all just window messages. You can do everything in automation with the _SendMessage function, provided you know what you're doing.
Certain designs and interfaces make it very difficult, if not virtually impossible, for AutoIt to tap into the interface to read control information. I would suggest either using the WLM protocol manually via your own client, or utilize a client that doesn't make screen grabbing the text hard or impossible.
Ok, maybe finally an answer... at least this test app I coded works as following:
Somewhere in the beginning of your script you have to set the state of your WLM to #SW_HIDE. Later when you try to do ControlXxxx-stuff you first set a variable on your active window. Now you can optionally block your input and activate your hidden window. It now works as you described above and afterwards you reactivate your last active window. Optionally undo the input block again.
That should solve your question with the least breaktime... you could play with your Mouse Cursor Style in the meantime to simulate some CPU load, so the block input is not too offending. But the action is so fast you won't even recognise it... (maybe it will swallow some keypresses though)
Give it a try!
Opt("WinTitleMatchMode", 2)
#include <GuiConstantsEx.au3>
$GUI = GUICreate("Beispiel HiddenApp", 392, 323)
$ed = GUICtrlCreateEdit("nix", 1, 1, 390, 321)
GUISetState()
Sleep(1000)
GUISetState(#SW_HIDE, $GUI)
WinActivate("SciTE")
Sleep(1000)
BlockInput(1)
$act = WinActive("[ACTIVE]")
WinActivate($GUI)
ControlClick($GUI, "", $ed, "primary", 1, 50, 50)
ControlSend($GUI, "", $ed, "before{Alt}{Tab}after")
WinActivate($act)
BlockInput(0)
Sleep(1000)
GUISetState(#SW_SHOW, $GUI)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case Else
;;;
EndSwitch
WEnd

Resources