pygame mixer: No available audio device or no sound when multiprocessing - python-2.7

Here's the simplified example. I have this code:
from pygame import mixer
def say():
mixer.init()
mixer.music.load('/home/orif/Downloads/english.wav')
mixer.music.play()
while mixer.music.get_busy():
time.sleep(0.2)
It displays some warnings but works perfectly. The warnings:
ALSA lib pcm_dsnoop.c:606:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave ALSA
lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA
lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM
cards.pcm.center_lfe ALSA lib pcm.c:2266:(snd_pcm_open_noupdate)
Unknown PCM cards.pcm.side ALSA lib
pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
But if I run it in child process it won't:
def test():
talk_process = Process(target=say)
talk_process.start()
print 'waiting for the process...'
talk_process.join()
print 'done'
It prints the same warnings, then:
waiting for the process...
Process Process-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "/home/orif/Projects/example.py", line 178, in say
mixer.init()
error: No available audio device
done
If I do the same but with threading, it runs fine. I have tried what's written here and here. In the former link the solution in the comments almost helped me. I initialized mixer just before running the subprocess:
mixer.init()
talk_process.start()
But now the sound doesn't play, and the waiting loop while mixer.music.get_busy() is endless
What is happening and how to solve it?

Alright, my bad, I didn't check everything before asking the question. The code snippet above is a bit incomplete. There were also several imports what I thought was irrelevant. I imported my module where I use SpeechRecognition. In the code there was a function declaration which looked like this:
def foo(m = sr.Microphone()):
pass
At the moment of writing that code I thought, since Python executes everything in the last possible moment, it should work too. And when I ran that code, it did, so everything seemed to be fine. I was wrong.
At the moment of function declaration, that method call was not treated as "if no argument given, substitute with the result of this call", but it was actually called and the return value was used as an optional argument. I don't know what exactly went wrong with sound card while multiprocessing, but that's why I got those weird and obscure error messages.
Here's a little example to show what was causing the issue:
def foo():
print 'TRIGGERED'
return 42
def bar(a = foo()):
print a
if __name__ == '__main__':
pass
Though seems it should do nothing, this code actually prints TRIGGERED. So, instead of assigning values to optional arguments like that, I do something like this:
def foo(a = None):
a = 'bar' if a is None else a

Related

Using pyfmi with multiprocessing for simulation of Modelica FMUs

I am trying to simulate multiple Modelica FMUs in parallel using python/pyfmi and multiprocessing. However I am not able to return any pyfmi FMI objects from the subprocesses once the FMUs are initialized. It seems that pyfmi FMI objects (e.g. pyfmi.fmi.FMUModelCS2 or pyfmi.fmi.FMUState2) are not pickable. I also tried dill to pickle, which doesn't work for me eather. With dill the objects are picklable though, meaning no error, but somehow corrupted if I try to reload them afterwards. Does anyone have an idea of how to solve this issue? Thanks!
The problem is that pyfmi.fmiFMUModelCS2 is a Cython class dependent on external libraries which makes it unpickable. So it is not possible unfortunately.
If you want to use multiprocessing the only way forward that I see is that you first create the processes and then load the FMUs into the separate processes. In this way you do not need to pickle the classes.
I faced a similar problem when I created EstimationPy. I ended up creating a wrapper for running parallel simulation of the same FMU using multiple processes.
I suggest you to look at the implementation here
https://github.com/lbl-srg/EstimationPy/blob/master/estimationpy/fmu_utils/fmu_pool.py
And to the example http://lbl-srg.github.io/EstimationPy/modules/examples/first_order.html#run-multiple-simulations
The pathos module allows multiprocessing with a similar interface as the multiprocessing but relies on dill instead of pickle for serialisation.
The Pool method works for parallel execution of model.simulate, provided that results are handled in memory:
n_core = 2
n_simulation = 10
# ====
import pyfmi
model = pyfmi.load_fmu(path_fmu)
def worker(*args):
model.reset()
print "================> %d" % args[0]
return model.simulate(options=dict(result_handling="memory"))["y"]
from pathos.multiprocessing import Pool
pool = Pool(n_core)
out = pool.map(worker, range(n_simulation))
pool.close()
pool.join()
Note in the above snippet that it is necessary to handle results in memory : options=dict(result_handling="memory").
The default is to use temporary files which works for when the amount of simulations is small.
However, the longer the queue, the higher the chance to get something like
Exception in thread Thread-27:
Traceback (most recent call last):
File "/home/USER/anaconda2/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/home/USER/anaconda2/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/USER/anaconda2/lib/python2.7/site-packages/multiprocess/pool.py", line 389, in _handle_results
task = get()
File "/home/USER/anaconda2/lib/python2.7/site-packages/dill/dill.py", line 260, in loads
return load(file)
File "/home/USER/anaconda2/lib/python2.7/site-packages/dill/dill.py", line 250, in load
obj = pik.load()
File "/home/USER/anaconda2/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/home/USER/anaconda2/lib/python2.7/pickle.py", line 1139, in load_reduce
value = func(*args)
TypeError: __init__() takes exactly 2 arguments (1 given)
which I fail to grasp.

How to close file descriptors in python?

I have the following code in python:
import os
class suppress_stdout_stderr(object):
'''
A context manager for doing a "deep suppression" of stdout and stderr in
Python, i.e. will suppress all print, even if the print originates in a
compiled C/Fortran sub-function.
This will not suppress raised exceptions, since exceptions are printed
to stderr just before a script exits, and after the context manager has
exited (at least, I think that is why it lets exceptions through).
'''
def __init__(self):
# Open a pair of null files
self.null_fds = [os.open(os.devnull,os.O_RDWR) for x in range(2)]
# Save the actual stdout (1) and stderr (2) file descriptors.
self.save_fds = (os.dup(1), os.dup(2))
def __enter__(self):
# Assign the null pointers to stdout and stderr.
os.dup2(self.null_fds[0],1)
os.dup2(self.null_fds[1],2)
def __exit__(self, *_):
# Re-assign the real stdout/stderr back to (1) and (2)
os.dup2(self.save_fds[0],1)
os.dup2(self.save_fds[1],2)
# Close the null files
os.close(self.null_fds[0])
os.close(self.null_fds[1])
for i in range(10**6):
with suppress_stdout_stderr():
print 'plop'
if i % 50 == 0:
print i
it fails at 5100 on OSX with OSError: [Errno 24] Too many open files. I'm wondering why and if there is a solution to close the file descriptor. I'm looking for a solution for a context manager which closes stdout and stderr.
I executed your code on a Linux machine and got the same error but at a different number of iterations.
I added the following two lines in the __exit__(self, *_) function of your class:
os.close(self.save_fds[0])
os.close(self.save_fds[1])
With this change I do not get an error and the script returns successfully. I assume that the duplicated file descriptors stored in self.save_fds are kept open if you don't close them with os.close(fds) and so you get the too many files open error.
Anyway my console printed "plop", but maybe this depends on my platform.
Let me know if it works :)

xlwings Workbook() call returns AttributeError: Open.Application

Hope you can help me out, first question I ask myself but I am always impressed by the professional answers I find here!
I am using xlwings to both read and write data from .xls files. I am not a seasoned programmer, and I make mistakes. From time to time, this means rebooting processes, Python and what-not.
Every now and again, I would get the following AttributeError upon calling Workbook(). The real problem is not that I don't have a clue what is happening (I tried reading the modules the error diagnostics reference to, but they are written on a level of Python that is beyond my skills), but that restarting and even rebooting(!) my laptop don't (always) solve the problem.
I wish I could give some clues as to what is happening, but it appears to be a randomly occurring problem and right now, three reboots and several restarts didn't fix it. Google can't help either. I must have run my program a hundred times by now and it wasn't always a problem! The error message, upon simply calling Workbook():
wb = Workbook()
Traceback (most recent call last):
File "<ipython-input-22-4a3c36eb9bf9>", line 1, in <module>
wb = Workbook()
File "C:\Program Files\Anaconda\lib\site-packages\xlwings\main.py", line 141, in __init__
self.xl_app, self.xl_workbook = xlplatform.new_workbook()
File "C:\Program Files\Anaconda\lib\site-packages\xlwings\_xlwindows.py", line 104, in new_workbook
xl_app = _get_latest_app()
File "C:\Program Files\Anaconda\lib\site-packages\xlwings\_xlwindows.py", line 88, in _get_latest_app
return xl_workbook_current.Application
File "C:\Program Files\Anaconda\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: Open.Application
And as a follow up, the piece of code from 'dyamic.py' raising the error:
[...]
# If we are still here, and have a retEntry, get the OLE item
if not retEntry is None:
invoke_type = _GetDescInvokeType(retEntry, pythoncom.INVOKE_PROPERTYGET)
debug_attr_print("Getting property Id 0x%x from OLE object" % retEntry.dispid)
try:
ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)
except pythoncom.com_error, details:
if details.hresult in ERRORS_BAD_CONTEXT:
# May be a method.
self._olerepr_.mapFuncs[attr] = retEntry
return self._make_method_(attr)
raise
debug_attr_print("OLE returned ", ret)
return self._get_good_object_(ret)
# no where else to look.
raise AttributeError("%s.%s" % (self._username_, attr))
As I mentioned before, the last bit it too much for me :P
I guessed some lingering Excel.exe (or similar) process was interfering with the script after I closed some random window due to some random error, but I cant find one in the task manager. Also, this is the kind of thing a reboot should fix, right?! I also upgraded to xlwings .34 (latest version, as of now).
Windows 8.1 64 bit, Python 2.7 (Anaconda distribution, Spyder IDE), Excel 2013.
Any help is very much appreciated, of course!
Thanks a lot, kind regards,
Gordon.
EDIT:
Following advice given in the comments, I can now report that even at times when wb = Workbook() fails, from win32com.client import dynamic followed by dynamic.Dispatch('Excel.Application') returns <COMObject Excel.Application>.
Hope it helps!
Always check either any issues to open the excel sheet, such as password protected/Licensed issues..
If there is any pop up coming while opening excel, you may get the same error.

PiCamera cannot be initialized as a class member when the script is run from command prompt

on my Raspberry Pi, I encounter a strange behaviour regarding the use of the PiCamera module.
The following code runs smoothly when either started from IDLE (F5) or from the command prompt ($python test.py)
import picamera
if __name__ == "__main__":
camera=picamera.PiCamera()
camera.close()
But when I put the camera object into a class the code will run only when started from IDLE (F5):
import picamera
class VF:
def __init__(self):
self.camera = picamera.PiCamera()
def __del__(self):
self.camera.close()
if __name__ == "__main__":
myvf = VF()
When I start the above code from the command prompt, I get the following error message:
mmal: mmal_vc_component_enable: failed to enable component: ENOSPC
Traceback (most recent call last): File "test.py", line 14, in
myvf = VF()
File "test.py", line 6, in init
self.camera = picamera.PiCamera()
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line
379, in init
camera_num, self.STEREO_MODES[stereo_mode], stereo_decimate)
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line
505, in _init_camera
prefix="Camera component couldn't be enabled")
File "/usr/lib/python2.7/dist-packages/picamera/exc.py", line 133,
in mmal_check
raise PiCameraMMALError(status, prefix)
picamera.exc.PiCameraMMALError: Camera component couldn't be enabled:
Out of resources (other than memory)
The camera module is working correct, I just stripped the code down to the least possible size. Does anybody know this problem, or a similar problem, and can probably provide a solution? The Python Version is 2.7 and the Raspberry Rasbiab-System is completely up to date.
Thanks in advance.
I struggled with this one for hours, and kept getting the "out of resources" error. I finally figured out that in my take-the-picture function, I needed to make sure I did it like this:
camera = PiCamera()
(...camera settings here...)
camera.capture(myfileName)
camera.close()
If I didn't do the close(), I'd get that error every time.
So make sure that camera.close() is getting called right after the 'snap'. It solved the problem for me.
Found out, that the camera-module is not properly shut down when the destructor is not explicitly called (had LED turned off, so didn't see this).
IDLE handles a running camera by somehow resetting it before the script starts, but not the python interpreter.
So everything is ok now when the destructor is called before the script ends.

Simple reading/writing from/to a USB HID device in Python?

I've got a fairly simple USB HID device that I've been trying to figure out how to read from and write to using Python. I've been able to read from it using PyWinUSB, but the problem comes in when I try to write to it. Trying to write to it makes things explode.
For example:
device = hid.HidDeviceFilter(vendor_id = 0x0003, product_id = 0x1001).get_devices()[0]
This works fine. Then for reading raw data, which is all that I care about right now (I'll work with that once I can figure out how to write to the cursed thing):
def readData(data):
print(data)
return None
This works fine (in fact, it was quite exciting when I got to see it work). So I would assign the data handler like so:
device.set_raw_data_handler(readData)
And every time I hit a button, it's fine. The data comes through as you would expect. Which is great!
The problem comes when I want to write to the device.
Following the sample simple_send file as a template (which was probably not the best choice), I would do the following:
report = device.find_output_reports()[0]
Which would return a report object with a dictionary holding 4 entries. Is that correct? Do you write to a device using the output_reports object? Trying to do so by setting the report value to ANYTHING:
report[<key>] = "pneumonoultramicroscopicvolcanoconiosis"
report.send()
This would keep returning some obnoxious error that I can't interpret:
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
report.send()
File "C:\Python27\lib\site-packages\pywinusb-0.3.1-py2.7.egg\pywinusb\hid\core.py", line 1446, in send
self.__prepare_raw_data()
File "C:\Python27\lib\site-packages\pywinusb-0.3.1-py2.7.egg\pywinusb\hid\core.py", line 1401, in __prepare_raw_data
byref(self.__raw_data), self.__raw_report_size) )
File "C:\Python27\lib\site-packages\pywinusb-0.3.1-py2.7.egg\pywinusb\hid\winapi.py", line 382, in __init__
raise helpers.HIDError("hidP error: %s" % self.error_message_dict[error_code])
HIDError: hidP error: data index not found
I'm using Windows 7. I've managed to find (finally) a reference for the HID DLL exported functions, and I don't HAVE to (or, for that matter even really WANT to) use the PyWinUSB library. I just want to make this work, and it didn't seem like it would be that tough, but it has been.
Can someone tell me what it is I've been doing wrong here?
Thanks.
Also, I tried tracing the error call, and made it so far before the program just closed which was kind of disheartening.
i made it work with this
buffer= [0xFF]*33 # 33 = report size + 1 byte (report id)
buffer[0]=0x0 # report id
buffer[1]=0xFE
buffer[2]=0x00
buffer[3]=0xFF
out_report.set_raw_data(buffer)
out_report.send()
dev.close()
For me worked only this:
report.send([0x70, ..., 0x73 ])
The function call sequence with set_raw_data([0x70, ..., 0x73) and subsequent send() didn't work for me.