File: ppatest_oldschool.py

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (157 lines) | stat: -rw-r--r-- 5,711 bytes parent folder | download | duplicates (3)
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()