1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
# ppatest.py - Basic test of PsychPortAudio for Python
# Also tests WaitSecs, GetSecs, and PsychHID basics, as
# they are utilized here.
#
# Plays a beep tone, then another beep tone, then records sound for 10 seconds,
# then plays it back until the end, or until a key is pressed.
# The test will be subjec to change without notice, it is throwaway test code.
#
# (c) 2018 Mario Kleiner - Licensed under MIT license.
from psychtoolbox import *
from math import *
import numpy as np
#from soundfile import SoundFile
def printstatus(pahandle):
info = PsychPortAudio('GetStatus', pahandle);
print(info);
return(info['Active']);
def run():
# Samplerate:
Fs = 48000;
# Tone frequency:
f = 500;
# Length of audio vector - 1 secs of playback:
sample = 1 * Fs;
# Build sinewave:
a = [0] * sample;
for n in range(sample):
a[n] = sin(2 * pi * f * n / Fs);
# Replicated into two rows - One row for each stereo-channel, ie.
# m'th row == m'th channel, n'th column = n'th sample frame:
stereowav = [a, a];
PsychPortAudio('Verbosity', 5);
# Open audio device: Default audio device, default opmode (playback), default
# latency/timing-precision (low-latency, high precision), sample rate Fs,
# stereo (2) channel output:
pahandle = PsychPortAudio('Open', [], [], [0], Fs, 2);
PsychPortAudio('Volume', pahandle, 0.5);
if True:
# Fill in audio matrix for playback: columns = audio channels, rows = samples
# Do it step-by-step for performance testing:
stereowav = np.array(stereowav, order='f');
# print('Type', type(stereowav), 'Shape', stereowav.shape, 'Datatype', stereowav.dtype, 'Order', stereowav.flags);
stereowav = np.transpose(stereowav);
# float32 is a tad faster than the default float64:
stereowav = stereowav.astype('float32');
# stereowav = np.zeros([10000,2], dtype='f')
else:
# Make it less boring:
fname = '/home/kleinerm/Music/test.wav';
myfile = SoundFile(fname);
stereowav = myfile.read(dtype='float32', always_2d=True);
#stereowav = myfile.read();
myfile.close();
print('Type', type(stereowav), 'Shape', stereowav.shape, 'Datatype', stereowav.dtype, 'Order', stereowav.flags);
t1 = GetSecs();
PsychPortAudio('FillBuffer', pahandle, stereowav);
t2 = GetSecs();
d1 = (1000 * (t2-t1));
print('FillBuffer Duration', d1, ' msecs.');
# Start playback for one repetition (1), 5 seconds from now, wait for sound onset:
PsychPortAudio('Start', pahandle, 1, GetSecs() + 1, 1)
# Go into a loop that prints playback status once a second, as long as playback
# is active:
info = PsychPortAudio('GetStatus', pahandle);
print(info, ' Spec ', info['Active']);
while printstatus(pahandle):
WaitSecs('YieldSecs', 1);
# Wait for sound to stop by itself, block until then:
[startTime, endPositionSecs, xruns, estStopTime] = PsychPortAudio('Stop', pahandle, 1)
print('StartTime', startTime, 'secs. Stop time', estStopTime, 'secs.\n');
for n in range(sample):
a[n] = sin(2 * pi * f * 1.5 * n / Fs);
# Replicated into two rows - One row for each stereo-channel, ie.
# m'th row == m'th channel, n'th column = n'th sample frame:
stereowav2 = [a, a];
stereowav2 = np.transpose(stereowav2);
stereowav2 = stereowav2.astype('float32');
t1 = GetSecs();
b1 = PsychPortAudio('CreateBuffer', pahandle, stereowav2);
t2 = GetSecs();
d2 = (1000 * (t2-t1));
print('CreateBuffer Duration', d2, ' msecs.');
t1 = GetSecs();
PsychPortAudio('FillBuffer', pahandle, b1);
t2 = GetSecs();
print('FillBuffer Duration', (1000 * (t2-t1)), ' msecs.');
print('d2 / d1 = ', d2 / d1);
PsychPortAudio('Start', pahandle, 1, GetSecs() + 1, 1)
[startTime, endPositionSecs, xruns, estStopTime] = PsychPortAudio('Stop', pahandle, 1);
print('StartTime', startTime, 'secs. Stop time', estStopTime, 'secs.\n');
# Close sound device:
PsychPortAudio('Close', pahandle);
# 2nd test: Audio capture:
pahandle = PsychPortAudio('Open', [], 2, 0, Fs, 2);
# Preallocate an internal audio recording buffer with a capacity of 10 seconds:
PsychPortAudio('GetAudioData', pahandle, 10);
# Start audio capture immediately and wait for the capture to start.
# We set the number of 'repetitions' to zero,
# i.e. record until recording is manually stopped.
PsychPortAudio('Start', pahandle, 0, 0, 1);
[audiodata, a, b, c] = PsychPortAudio('GetAudioData', pahandle, None, 9.9, None);
print('Type', type(audiodata), 'Shape', audiodata.shape, 'Datatype', audiodata.dtype);
PsychPortAudio('Close', pahandle);
pahandle = PsychPortAudio('Open', [], [], [0], Fs, 2);
PsychPortAudio('Volume', pahandle, 1);
# Fill in audio matrix for playback:
PsychPortAudio('FillBuffer', pahandle, audiodata);
# Start playback for one repetition (1), 5 seconds from now, wait for sound onset:
PsychPortAudio('Start', pahandle, 1, GetSecs() + 1, 1)
# Go into a loop that prints playback status once a second, as long as playback
# is active:
info = PsychPortAudio('GetStatus', pahandle);
print(info, ' Spec ', info['Active']);
while printstatus(pahandle) and not PsychHID('KbCheck')[0]:
WaitSecs('YieldSecs', 1);
# Stop playback:
[startTime, endPositionSecs, xruns, estStopTime] = PsychPortAudio('Stop', pahandle)
print('StartTime', startTime, 'secs. Stop time', estStopTime, 'secs.\n');
# Close sound device:
PsychPortAudio('Close', pahandle);
if __name__ == '__main__':
run()
|