spatialaudio / python-sounddevice

:sound: Play and Record Sound with Python :snake:
https://python-sounddevice.readthedocs.io/
MIT License
988 stars 146 forks source link

Deprecation Warning on OSX 10.11 #10

Open ghost opened 8 years ago

ghost commented 8 years ago

When I run on OS X 10.11.1 sd.play(x, fs) I get the next warning. Does it have to do only with sounddevice? Is there a way to remove it?

WARNING: 140: This application, or a library it uses, is using the deprecated Carbon Component Manager for hosting Audio Units. Support for this will be removed in a future release. Also, this makes the host incompatible with version 3 audio units. Please transition to the API's in AudioComponent.h.

mgeier commented 8 years ago

This message is caused by the underlying PortAudio library.

Here's an issue and a mailing list discussion about the topic: https://www.assembla.com/spaces/portaudio/tickets/243-portaudio-support-for-os-x-10-11-el-capitan/details# https://lists.columbia.edu/pipermail/portaudio/2015-October/000092.html

I think we'll just have to wait for a new PortAudio version, until then you'll have to ignore this message.

ghost commented 8 years ago

Thank's a lot!

mgeier commented 8 years ago

You should leave this open until it is fixed.

An alternative approach would be #11, what do you think about that?

ghost commented 8 years ago

I think it would be nice to remove those messages though I am not familiar with that kind of implementation.

On OSX El Capitan I could not compile PortAudio following their instructions (I could in Yosemite) and I get the errors as you showed in the links above. So as you say, the appropriate solution should come from PortAudio. I installed it using brew install portaudio, and so far sounddevice seems to work as I expect/need.

mgeier commented 8 years ago

I made an attempt at silencing PortAudio in the branch "redirect-stdout", see #12.

Can you please try if this works in your case?

ghost commented 8 years ago

I still see the warning. Please let me know if I installed it correctly (I'm sort of a begginer):

mgeier commented 8 years ago

Yes, those are the right steps.

However, you should probably change the installation command (as suggested in the "Contributing" section of the docs) to:

python setup.py develop

... because this way you can change stuff in the code and don't need to re-install the module all the time. You'll have to close and re-start Python, though, for the changes to take effect.

If you are not sure if the correct code is used, you should try to create an obvious error in sounddevice.py and check if this error is raised when you run your test script. Just to be sure ...

Since you still see the warning, maybe it is sent to stdout instead of stderr ...

Can you please try to replace the two occurrences of __stderrp with __stdoutp and run it again?

ghost commented 8 years ago

OK, so I reinstalled as explained and the intentional error is raised!

I see the warning without and with the modification you suggest.

There is something I do not understand in this part of the code (the first occurrence is commented?) Well I though I should do something in OS X about it but do not really what (XD)

mgeier commented 8 years ago

Hmmm ... so it looks like the message doesn't come from the PortAudio library but somehow directly from the OS ... I guess ...

There is no code commented, the only comments are actual comments. The first line is just a hint that the following definitions are taken from the file stdio.h.

/* from stdio.h */

Since this doesn't seem to work in your case, you could now try my suggestion from https://github.com/spatialaudio/python-sounddevice/issues/11#issuecomment-155836787.

You can put the first block of code from the above link before you call sd.play() and the second block of code after it.

If it doesn't work, you should try changing the 2 (which is the file descriptor for stderr) to 1 (which means stdout).

If you don't run the second code block (to undo the redirection), you won't see any stdout/stderr messages for your remaining Python session!

If this works for you, you should actually use a with statement to make sure that the redirection is undone even if an error occurs.

ghost commented 8 years ago

I have followed the instruction on pasting the blocks of code before and after the call to sounddevice and it indeed hides the warning! It worked with the 2.

Could you explain me what you mean by using a with statement?

mgeier commented 8 years ago

I'm glad to hear that this method works for you. I don't think I want to include this into python-sounddevice, but it should be no problem to do this in your own code (see below).

The with statement is part of Python just like the if statement and the for loop. It should be part of your favorite Python tutorial ...

You can read up on it, e.g.: http://stackoverflow.com/questions/3012488/what-is-the-python-with-statement-designed-for https://docs.python.org/3/reference/compound_stmts.html#with https://www.python.org/dev/peps/pep-0343/

In your case, I would suggest to use the contextlib module from the standard library: https://docs.python.org/3/library/contextlib.html

import contextlib
import os
import sys

@contextlib.contextmanager
def ignore_stderr():
    devnull = os.open(os.devnull, os.O_WRONLY)
    old_stderr = os.dup(2)
    sys.stderr.flush()
    os.dup2(devnull, 2)
    os.close(devnull)
    try:
        yield
    finally:
        os.dup2(old_stderr, 2)
        os.close(old_stderr)

You only need to define this once, then you can use it for all the calls where you want to get rid of the warning message. You can use it like this:

import sounddevice as sd

with ignore_stderr():
    sd.play(mydata, fs)

This makes sure that after the with statement the old behavior of stderr is restored. And the important part is that it is also restored if an exception is raised in sd.play() (or in whatever you are doing inside of the with statement).

There are probably some edge cases i'm missing, for more details have a look at: http://eli.thegreenplace.net/2015/redirecting-all-kinds-of-stdout-in-python/

ghost commented 8 years ago

Thank's a lot for your help! That solution is good enough for me ;)

mgeier commented 8 years ago

Just for reference, there is another issue in the PortAudio issue tracker: https://www.assembla.com/spaces/portaudio/tickets/218-pa-coreaudio-uses-some--quot-deprecated-quot--apis----this-is-by-design-but-needs-to-be-monitored

it looks like the warning message will stay for some time ...