how to set PulseAudio streams for accessibility purposes - skype

I have a small Python script that sets up PulseAudio such that the Festival speech synthesis program can pipe synthesised speech into Skype calls. This is to enable someone that is unable to speak to have a voice at regular Skype group meetings.
It works, but getting the setup to work involves a lot of interacting with the PulseAudio Volume Control GUI. How can the PulseAudio streams be set up by the script in the terminal?
The little script is as follows:
import os
import subprocess
import signal
def main():
raw_input(
"\nReady to load a dummy sound card driver...\n" +\
"Press Enter to continue."
)
os.system("sudo modprobe snd-dummy")
raw_input(
"\nReady to set Festival running...\n" +\
"Press Enter to continue."
)
process_Festival = subprocess.Popen(
["festival", "--tts", "/var/log/dmesg"],
preexec_fn = os.setsid
)
raw_input(
"\nReady to open PulseAudio Volume Control...\n" +\
"Press Enter to continue.")
os.system("pavucontrol &")
raw_input(
"\nIn PulseAudio Volume Control, select the tab \"Playback\".\n" +\
"Identify Festival in operaton.\n" +\
"Change the output sink of Festival to \"Dummy Analog Stereo\".\n" +\
"Press Enter to continue."
)
raw_input(
"\nReady to stop Festival running...\n" +\
"Press Enter to continue."
)
os.killpg(os.getpgid(process_Festival.pid), 9)
raw_input(
"\nIn PulseAudio Volume Control, select the tab \"Recording\".\n" +\
"Start a Skype call to \"Skype Test Call\".\n" +\
"In PulseAudio Volume Control, identify Skype in operation.\n" +\
"Change the input source of Skype to \"Monitor of Dummy Analog " +\
"Stereo\"\n" +\
"End the Skype call.\n" +\
"Press Enter to continue."
)
raw_input(
"\nReady for text entry speech synthesis broadcast to Skype...\n" +\
"Press Enter to continue (and then make the Skype call when ready).\n"
)
while True:
text = raw_input("> ")
os.system("echo \"{text}\" | festival --tts".format(text = text))
if __name__ == "__main__":
main()

Related

voice recording using pyaudio not working as expected

This is the code I wrote to record my audio until I stop the program and save it in output.wav. The problem is that the output.wav is all silent and when I print the frames, they are all zeros. I am running it on Mac OS. I tried recording an audio using the Mac voice recorder and it works so there shouldn't be a problem with the microphone, I guess. Any suggestions why that is the case?
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
def record():
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("Start recording")
frames = []
try:
while True:
data = stream.read(CHUNK)
frames.append(data)
except KeyboardInterrupt:
print("Done recording")
except Exception as e:
print(str(e))
sample_width = p.get_sample_size(FORMAT)
stream.stop_stream()
stream.close()
p.terminate()
return sample_width, frames
def record_to_file(file_path):
wf = wave.open(file_path, 'wb')
wf.setnchannels(CHANNELS)
sample_width, frames = record()
wf.setsampwidth(sample_width)
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
if __name__ == '__main__':
print('#' * 80)
print("Please speak word(s) into the microphone")
print('Press Ctrl+C to stop the recording')
record_to_file('output.wav')
print("Result written to output.wav")
print('#' * 80)
Running this code on my Windows 10 machine and python 3.7 produced an audio file. Make sure that your microphone is enabled on your mac

Taking off using dronekit and PX4

I'm using an Intel Aero RTF drone with PX4 and I want to test a simple take off of this drone but the script I followed didn't give me results it just arms the dron and disarms but never takes off
This is the script:
#! /usr/bin/python
from dronekit import connect, VehicleMode, LocationGlobalRelative
import time
vehicle = connect('tcp:127.0.0.1:5760', wait_ready=False)
def arm_and_takeoff(aTarget):
### I commented this lines because the code doesn't pass from
this loop ###
#print 'Pre arm-checks'
#while not vehicle.is_armable:
# print "Initializing...'
# time.sleep(1)
print 'Arming motors'
vehicle.mode = VehicleMode("GUIDED")
vehicle.armed = True
while not vehicle.armed:
print "waiting for arming"
time.sleep(1)
print "Take Off!"
vehicle.simpe_takeoff(aTarget)
while True:
print "Altitude: ",vehicle.location.global_relative_frame.alt
if vehicle.location.global_relative_frame.alt >= aTarget * 0.95:
print "Altitude target reached"
break
time.sleep(1)
arm_and_takeoff(10)
print "Take off complete!"
time.sleep(10)
print "Landing"
vehicle.mode = VehicleMode("LAND")
As I said it just arms for a few seconds and the disarms, what am I doing wrong??
Regards
Dronekit doesn't officially support PX4 flight stack, you should Dronecode SDK for PX4 (https://sdk.dronecode.org/en/) or change your fligh stack to ArduPilot, but there is a limited support for PX4 too you can read about it here https://dev.px4.io/en/robotics/dronekit.html.

Qt5.4 QAudioOutput on Raspberry Pi With PulseAudio on the 3.5mm Audio Jack Doesn't work but Qt 5.3 Does

Qt5.3 sees the default Raspberry Pi also_output.0.analog-mono device ( 3.5 mm headphone jack ) and QAudioOutput from 5.3 successfully writes audio to that device and I can hear the audio with my headphones. This all works with default Raspbian, with PulseAudio 2.0 from apt-get, and no extra configuration. PulseAudio is run as session process and not in the System Daemon mode. Qt 5.4 does not see the device with the exact same source code and Raspbian ( except cross-compiled with Qt 5.4.0 and not Qt 5.3.2 ) and also cannot write data to it.
It gives me this error ( Please note that I've manually assigned both sys default:CARD=ALSA and 'default' but they both return the same 'snd_pcm_hw_params' error ):
Output Device name: "sysdefault:CARD=ALSA"
Output Device name: "default"
Default device is "default"
Output device is: "default"
"QAudioOutput: snd_pcm_hw_params: err = -12"
Pactl sees it:
pactl list sinks
Sink #0
State: SUSPENDED
Name: alsa_output.0.analog-mono
Description: bcm2835 ALSA Analog Mono
Driver: module-alsa-card.c
Sample Specification: u8 1ch 8000Hz
I've tried to modify /etc/pulse/default.pa with this at the bottom to force the output device:
load-module module-alsa-sink sink_name=alsa_output.0.analog-mono device=hw:0
set-default-sink alsa_output.0.analog-mono
Here is my setup code that gives the error:
// Coordinator receives Audio data
m_Format.setSampleRate(8000);
m_Format.setChannelCount(1);
m_Format.setSampleSize(8);
m_Format.setCodec("audio/pcm");
m_Format.setByteOrder(QAudioFormat::BigEndian);
m_Format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo infoOut(QAudioDeviceInfo::defaultOutputDevice());
foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) {
qDebug() << "Output Device name: " << deviceInfo.deviceName();
}
qDebug() << "Default device is" << infoOut.deviceName();
if (!infoOut.isFormatSupported(m_Format))
{
qDebug()<< "Default format not supported - trying to use nearest";
m_Format = infoOut.nearestFormat(m_Format);
}
qDebug() << "Output device is: " << infoOut.deviceName();
m_AudioOutput = new QAudioOutput(infoOut, m_Format, this);
// This data accumulates and dumps data to output
m_DataForOutput.clear();
// Now Start playing
// m_Output gets written to to send data to speakers
m_Output = m_AudioOutput->start();
What in the world is going on? How come the same configuration works with 5.3.2 and not 5.4.1. Assigning the default audio device doesn't work... What can I do here and how can I make it work? Thanks!
The answer was to run in session mode ( not a system-wide PulseAudio daemon ) and edit default.pa to look like this:
## Create the default output device
#load-module module-udev-detect tsched=0
load-module module-alsa-card device_id=0
#load-module module-alsa-card device_id=0 tsched=0 fragments=10 fragment_size=640 tsched_buffer_size=4194384 tsched_buffer_watermark=262144
#load-module module-alsa-card device_id=0 tsched=0 fragments=6 fragment_size=16 tsched_buffer_size=4194384 tsched_buffer_watermark=262144
load-module module-suspend-on-idle timeout=86400
### Load several protocols
load-module module-native-protocol-unix
### Make sure we always have a sink around, even if it is a null sink.
#load-module module-always-sink

RDP session launch applications

I have opened an RDP session using AutoIt. Here is the code:
$host = "" ; <---- IP
$hGUI = GUICreate("Terminal Serveur", 952, 675, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_CLIPSIBLINGS + $WS_CLIPCHILDREN)
$oRDP = ObjCreate("MsTscAx.MsTscAx.2")
$oRDP_Ctrl = GUICtrlCreateObj($oRDP, 64, 44, 800, 600)
GUICtrlSetResizing(-1, $GUI_DOCKALL)
GUICtrlSetStyle($oRDP_Ctrl , $WS_VISIBLE)
$oRDP.DesktopWidth = 800
$oRDP.DesktopHeight = 600
$oRDP.Fullscreen = False
$oRDP.ColorDepth = 16
$oRDP.AdvancedSettings3.SmartSizing = True
$oRDP.Server = $host
$oRDP.UserName = "" ; <--- Username
$oRDP.Domain = ""
$oRDP.AdvancedSettings2.ClearTextPassword = "" ; <--- Password
$oRDP.ConnectingText = "Connecting to " & $host
$oRDP.DisconnectedText = "Disconnected from " & $host
$oRDP.StartConnected = True
$oRDP.Connect()
$oShel = ObjCreate("shell.application")
$oShel_Ctrl = GUICtrlCreateObj($oShel, 64, 44, 800, 600)
GUICtrlSetStyle($oShel_Ctrl , $WS_VISIBLE)
GUISetState(#SW_SHOW, $hGUI)
Send ("#r") ; !!
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
$oRDP.Disconnect()
Exit
EndSwitch
WEnd
Now, I want to launch an application in the RDP session. I tried " Send(#r) " in order to send the path with a function like SendKeys but this command is execute on my computer and not on the remote computer.
How can I do please?
Send alt + home. This open the windows search in the rdp session, which you can then send it text e.g. send("notepad")
send({enter})
Update:
A much simpler alternative:
Change the Remote Desktop Connection Settings (not in the control
code, but in the usual windows shorcut. But it seems that could be done in the AutoIt code with the keyboardhook setting keyboardhook setting ) .
Look for the Options button, in the window when launching remote desktop.
On the Local Resources Tab select Windows key combinations are applied in full-screen mode only.
Change this line in your code:
$oRDP.Fullscreen = True
Include a pause to ensure the control has been loaded
Sleep(5000)
Send ("#r")
Previous answer:
Let my suggest a workaround not very 'elegant' but should work (tested ok):
In the remote desktop make a shorcut to the Windows Virtual Keyword (On-Screen Keyboard or OSK)
Find the position of the shorcut icon
In your code send a double click at this position to start the on-screen keyboard
Then send clicks to the positions of the desired keys
Something like this:
Sleep(5000)
MouseClick("left",512,191,2) ;start virtual keyword
Sleep(1000)
MouseClick("left",553,807,1) ;click
Sleep(100)
MouseClick("left",633,740,1)
Sleep(1000)
Send("notepad")
Sleep(1000)
Send("{ENTER}")
(Aside note: For any executable with a shortcut on the remote desktop simply send double click, without the need of the virtual keyboard)

How do I get the Tor exit node IP address over the control port?

I want to monitor the status of running Tor instances.
I am already able to get information via a TCP connection to the control ports.
E.g. "GETINFO stream-status" returns data, but I am not able to determine the IP address of the currently chosen exit node.
It would be possible to simply request something like whatismyip.org, but that is too slow and does not scale well.
So what is the best way to get the exit node IP address of a Tor connection?
This is a great question! Here's a short script for doing it using stem...
from stem import CircStatus
from stem.control import Controller
with Controller.from_port(port = 9051) as controller:
controller.authenticate()
for circ in controller.get_circuits():
if circ.status != CircStatus.BUILT:
continue
exit_fp, exit_nickname = circ.path[-1]
exit_desc = controller.get_network_status(exit_fp, None)
exit_address = exit_desc.address if exit_desc else 'unknown'
print "Exit relay"
print " fingerprint: %s" % exit_fp
print " nickname: %s" % exit_nickname
print " address: %s" % exit_address
print
Thanks for the question. I've added this to our FAQ.
You can use tor control api. But I don't see the point.
You know the exit node id~name, you know the ip address that it is listening on. You don't know what network interface and what ip address it will use to process your query.
I've just checked that about 5% of tor exit nodes uses unpublished ipv4 addresses.
The world is moving to ipv6. These ip addresses are cheap. Each exit node can have a bag of ipv6 unpiblished addresses.
The exit circuit might be any one of the circuits returned by controller.get_circuits(), the following is how you get the exit circuit and the ip address:
source and tutorial link
## https://stem.torproject.org/tutorials/examples/exit_used.html
import functools
from stem import StreamStatus
from stem.control import EventType, Controller
def main():
print("Tracking requests for tor exits. Press 'enter' to end.")
print("")
with Controller.from_port() as controller:
controller.authenticate()
stream_listener = functools.partial(stream_event, controller)
controller.add_event_listener(stream_listener, EventType.STREAM)
input() # wait for user to press enter
def stream_event(controller, event):
if event.status == StreamStatus.SUCCEEDED and event.circ_id:
circ = controller.get_circuit(event.circ_id)
exit_fingerprint = circ.path[-1][0]
exit_relay = controller.get_network_status(exit_fingerprint)
print("Exit relay for our connection to %s" % (event.target))
print(" address: %s:%i" % (exit_relay.address, exit_relay.or_port))
print(" fingerprint: %s" % exit_relay.fingerprint)
print(" nickname: %s" % exit_relay.nickname)
print(" locale: %s" % controller.get_info("ip-to-country/%s" % exit_relay.address, 'unknown'))
print("")
if __name__ == '__main__':
main()
According to the Tor control protocol spec, the correct syntax is "GETINFO address", which should render the best guess at our external IP address. If we have no guess, return a 551 error. (Added in 0.1.2.2-alpha)".

Resources