File: ppatest_pythonic.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 (162 lines) | stat: -rw-r--r-- 6,684 bytes parent folder | download
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
158
159
160
161
162
# 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) 2019 Jon Peirce - Licensed under MIT license.
# (c) 2018 Mario Kleiner - Licensed under MIT license.

from psychtoolbox import audio, hid
from psychtoolbox import GetSecs, WaitSecs  # not yet "Pythonic"
from math import *
import numpy as np


# from soundfile import SoundFile

def printstatus(stream):
    info = stream.status
    print(info)
    return (info['Active'])


def run():
    # Samplerate:
    Fs = 48000

    # Tone frequency:
    f = 500

    ####################################################################
    ############## 1st test: play some tones ###########################
    ####################################################################

    audio.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:
    stream = audio.Stream(freq=Fs, channels=2)
    stream.volume = 0.5  # PsychPortAudio('Volume', pahandle, 0.5)

    if True:
        # Length of audio vector - 1 secs of playback:
        n_samples = 1 * Fs
        # Build sinewave:
        a = np.sin(np.linspace(0, 2 * pi * f * n_samples, n_samples))
        # 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 = np.array([a, a], order='f').transpose().astype('float32')
    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()
    stream.fill_buffer(stereowav)  # PsychPortAudio('FillBuffer', pahandle, stereowav);
    t2 = GetSecs()
    d1 = (1000 * (t2 - t1))
    print('FillBuffer Duration', d1, ' msecs.')

    # Start playback for one repetition (1), 1 seconds from now, wait for onset:
    stream.start(repetitions=1, when=GetSecs() + 1, wait_for_start=1)
    # PsychPortAudio('Start', pahandle, 1, GetSecs() + 1, 1)

    # Go into a loop that prints playback status once a second, while playback
    # is active:

    info = stream.status
    print(info, ' Spec ', info['Active'])
    while printstatus(stream):
        WaitSecs('YieldSecs', 1)  # didn't write a pythonic wrapper yet

    # Wait for sound to stop by itself, block until then:
    startTime, endPositionSecs, xruns, estStopTime = stream.stop()
    print('StartTime', startTime, 'secs. Stop time', estStopTime, 'secs.\n');

    # as before but 1.5*note_freq
    a = np.sin(np.linspace(0, 2 * pi * f*1.5 * n_samples, n_samples))
    # 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 = np.array([a, a], order='f').transpose().astype('float32')

    t1 = GetSecs()

    b1 = audio.Buffer(stream=stream, data=stereowav2)  # PsychPortAudio('CreateBuffer', pahandle, stereowav2);
    t2 = GetSecs()
    d2 = (1000 * (t2 - t1))
    print('CreateBuffer Duration', d2, ' msecs.')
    t1 = GetSecs()
    b1.fill_buffer(stereowav2)  # 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)
    stream.start(when=GetSecs()+1, wait_for_start=1)
    WaitSecs('YieldSecs', 2)
    # [startTime, endPositionSecs, xruns, estStopTime] = PsychPortAudio('Stop', pahandle, 1);
    startTime, endPositionSecs, xruns, estStopTime = stream.stop()
    print('StartTime', startTime, 'secs.xx Stop time', estStopTime, 'secs.\n');

    # Close sound device:
    stream.close()  # PsychPortAudio('Close', pahandle);
    #
    #
    # ####################################################################
    # ############## 2nd test: Audio capture:#############################
    # ####################################################################
    # recording = audio.Stream(mode=2, freq=Fs, channels=2);  # pahandle = PsychPortAudio('Open', [], 2, 0, Fs, 2);
    #
    # # Preallocate an internal audio recording  buffer with a capacity of 10 seconds:
    # recording.get_audio_data(10)  # 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.
    # recording.start(repetitions=0, stop_time=None)  # PsychPortAudio('Start', pahandle, 0, 0, 1);
    #
    # # fetch just under 10s from that buffer
    # # PsychPortAudio('GetAudioData', pahandle, None, 9.9, None);
    # audiodata, a, b, c = recording.get_audio_data(min_secs=9.9)
    # print('Type', type(audiodata), 'Shape', audiodata.shape, 'Datatype',
    #       audiodata.dtype);
    #
    # recording.close()  # PsychPortAudio('Close', pahandle);
    #
    # playback = audio.Stream(freq=Fs, channels=2);
    # playback.volume = 1.0  # PsychPortAudio('Volume', pahandle, 1);
    #
    # # Fill in audio matrix for playback:
    # playback.fill_buffer(audiodata)  # PsychPortAudio('FillBuffer', pahandle, audiodata);
    #
    # # Start playback for one repetition (1), 5 seconds from now, wait for sound onset:
    # playback.start(1, GetSecs() + 1, 1)  #  PsychPortAudio('Start', pahandle, 1, GetSecs() + 1, 1)
    #
    # # Go into a loop that prints playback status once a second, as long as playback
    # # is active:
    # keyboard = hid.Keyboard()
    # info = playback.status  # PsychPortAudio('GetStatus', pahandle);
    # print(info, ' Spec ', info['Active']);
    # while playback.status['Active'] and not keyboard.check()[0]:
    #     WaitSecs('YieldSecs', 1);
    #
    # # Stop playback:
    # # [startTime, endPositionSecs, xruns, estStopTime] = PsychPortAudio('Stop', pahandle)
    # startTime, endPositionSecs, xruns, estStopTime = playback.stop()
    # print('StartTime', startTime, 'secs. Stop time', estStopTime, 'secs.\n');
    #
    # # Close sound device:
    # playback.close()  # PsychPortAudio('Close', pahandle);

if __name__ == '__main__':
    run()