diff --git a/contrib/python/pyrtaudio/PyRtAudioTest.py b/contrib/python/pyrtaudio/PyRtAudioTest.py index fcf85cb..185caa1 100644 --- a/contrib/python/pyrtaudio/PyRtAudioTest.py +++ b/contrib/python/pyrtaudio/PyRtAudioTest.py @@ -30,6 +30,41 @@ class callback: print('.') return 1 +try: + # if we have numpy, replace the above class + import numpy as np + class callback: + def __init__(self, gen): + print('Using Numpy.') + self.freq = 440. + t = np.arange(256, dtype=np.float32) / 48000.0 + self.phase = 2*np.pi*t + self.inc = 2*np.pi*256/48000 + self.k = 0 + def __call__(self, playback, capture): + # Calculate sinusoid using numpy vector operation, as + # opposed to per-sample computations in the generator + # above that must be collected and packed one at a time. + self.k += 256 + if self.k > 48000: + self.freq *= 2**(1/12.) + self.k = 0 + self.phase += self.inc + samples = 0.5*np.cos(self.phase * self.freq) + + # Ensure result is the right size! + assert samples.shape[0] == 256 + assert samples.dtype == np.float32 + + # Use numpy array view to do a once-copy into memoryview + # (ie. we only do a single byte-wise copy of the final + # result into 'playback') + usamples = samples.view(dtype=np.uint8) + playback_array = np.array(playback, copy=False) + np.copyto(playback_array, usamples) +except ModuleNotFoundError: + print('Numpy not available, using struct.') + dac = rt.RtAudio() n = dac.getDeviceCount()