bastibe / PySoundCard

PySoundCard is an audio library based on PortAudio, CFFI and NumPy
BSD 3-Clause "New" or "Revised" License
87 stars 9 forks source link

Use float64 by default? #38

Open mgeier opened 9 years ago

mgeier commented 9 years ago

Currently, np.float32 is the default data type when creating a Stream. This makes sense, because many audio applications use that data type and it is supported by PortAudio.

On the other hand, everything in the NumPy world uses float64 as default and people might be surprised to get float32 back. PortAudio doesn't actually support float64, but I guess the casting operations should be automatic and fast.

I think it would be good to make float64 the default, but I'm not 100% sure yet ...

bastibe commented 9 years ago

I'm not sure either. Since portaudio can't meaningfully work with float64 data, it seems like lying to return float64 values. On the other hand, we have to copy the data anyway when interfacing with portaudio, so some additional data conversion won't matter from a performance standpoint. Yet, float32 data might be unexpected, but it does not have much disadvantages except for reduced precision (in contrast to, say, int16 data).

Thus, I agree with you on both points: going ahead with float64, and not being 100% sure about it.

mgeier commented 9 years ago

During the development of https://github.com/spatialaudio/python-sounddevice I thought about this issue again, and I came to the conclusion that a default dtype='float64' doesn't make sense.

The low-level functions don't copy any audio data at all (BTW, the Stream.write() method still makes a copy in PySoundCard), therefore it's not possible to change the data type to 'float64' (except by copying audio data, which I would definitely want to avoid).

The high level functions (like play()) do copy audio data, therefore it's no problem to support 'float64' there.

The function playrec() just uses the dtype of the input array, therefore there is no default dtype.

The only place where dtype can have a default value, is the rec() function, but I think to be consistent with the low-level functions, it makes most sense to use a default dtype='float32' here, too.