5D Library › Psychophysics, the Weber-Fechner Law and Optimal Bayesian Multisensory Integration · 中文
Chapter 8 Practice and a Pre-Registered Trial
Note
The checklist in this chapter is for designing and evaluating learning materials, teaching and products; it is not medical advice. It cannot be used to judge anyone’s hearing, vision, vestibular, vocal or neurological function; if you have symptoms of that kind, see a doctor. The trial protocol involves sustained vocal practice and forearm vibration; it sets out safety provisions for vocal load and vibration and excludes people with voice disorders and similar conditions.
Part 1 A four-step multisensory precision checklist
When designing a skills lesson, a talk, a teaching video or a product, four questions can be asked in turn.
- Assess noise in the main channel and identify high-risk single channels. Which sense does the learner or user mainly rely on? Under real conditions of use (visual clutter, background noise, fatigue, distraction), how far does that sense’s reliability fall? If one channel carries nearly all the “weight” and may degrade at the critical moment, the design is a high-risk single channel and needs a reliable backup channel (Chapter 3).
- Reinforce weak signals across channels, in synchrony. Is the signal in the main channel too weak to make out easily? If so, add a signal in a second sense at the same time and place; the expected gain can be estimated by combining the precisions of the two channels. Do not assume that “the weaker the signal, the more a second channel helps”: superadditivity is mainly a property of single neurons responding to weak stimuli, and in behaviour the gain for audiovisual speech is largest at intermediate signal-to-noise ratios (Chapter 5).
- Align within the audiovisual synchrony window. Is the time difference between sound and picture (or vibration) within acceptable limits? The framework says “about ±100 ms”. On checking, this should become an asymmetric window: sound arriving before the picture is noticed more easily.
- Audit active exploration against passive reception. Of all practice time, how much has the learner spent initiating movements and steering exploration, and how much only watching and listening? Self-generated movement supplies a known input and is a condition for learning the mapping between action and sensation (Chapter 6).
Evidence
How far sound and picture can drift apart. A 1998 broadcasting recommendation of the International Telecommunication Union, based on viewer assessments in Japan, Switzerland and Australia, gives thresholds for the timing difference between sound and picture: the threshold of detectability is about 45 ms with sound early and 125 ms with sound late; the threshold of acceptability about 90 ms early and 185 ms late (ITU-R 1998). In experiments on the fusion of speech, fusion is common from about 30 ms with sound early to about 170 ms with sound late (Chapter 4) (Wassenhove et al. 2007).
Evidence
The temporal window can be trained. Powers, Hillock and Wallace (2009) gave participants training with feedback on audiovisual simultaneity judgements, and the width of the window within which they judged events “simultaneous” narrowed by about 40 % (Powers et al. 2009). The window is thus not a fixed physiological constant; people with different experience may also have windows of different widths, so the values in the checklist are only a starting point.
The checklist is applied to three fictional examples: an online pronunciation-teaching video, a lane-departure alert in a car, and a motor-skill learning app. The standard deviations and values of each channel are assumed; the two lines drawn in step 1 (“one channel carrying more than 80 % of the weight”) and step 4 (“less than 50 % active practice”) were set by the author for the examples and are not published standards.
Calculation
# Four-step multisensory precision checklist applied to three FICTIONAL cases.
# Step 1: reliability weights (MLE); flag a channel carrying > 80 % of the weight, and the
# loss if it is degraded 3-fold (e.g. vision under visual clutter).
# Step 2: weak signals: combined d' = sqrt(d1^2 + d2^2) for independent channels.
# Step 3: sound-picture offset against ITU-R BT.1359 detectability (sound early <= 45 ms,
# late <= 125 ms); for speech, fusion window about -30 to +170 ms (van Wassenhove 2007).
# Step 4: share of practice the learner steers. The 50 % line is an ILLUSTRATIVE choice.
import math
def mle(sds):
w = [1 / s ** 2 for s in sds.values()]
return {k: v / sum(w) for k, v in zip(sds, w)}, 1 / math.sqrt(sum(w))
CASES = {
"A online pronunciation video": dict(
sds={"hearing": 1.0, "lips": 1.5}, dprime={"hearing": 0.8, "lips": 0.6},
offset=+160, speech=True, active=0.2),
"B dashboard lane alert": dict(
sds={"icon": 1.0}, dprime={"icon": 1.2}, offset=None, speech=False, active=None),
"C motor-skill app": dict(
sds={"video": 1.2, "hearing": 1.5, "wrist buzz": 2.0},
dprime={"video": 2.0, "hearing": 1.5, "wrist buzz": 1.0},
offset=-40, speech=False, active=0.6),
}
for name, c in CASES.items():
print(name)
w, sd = mle(c["sds"])
top = max(w, key=w.get)
worse = dict(c["sds"]); worse[top] *= 3
flag = "FLAG single channel" if w[top] > 0.8 else "ok"
print(f" 1 weights {', '.join(f'{k} {v:.2f}' for k, v in w.items())}: {flag}")
print(f" combined sd {sd:.2f}; if {top} gets 3x noisier: {mle(worse)[1]:.2f}")
ds = list(c["dprime"].values())
best, comb = max(ds), math.sqrt(sum(d * d for d in ds))
print(f" 2 best single d' {best:.1f}, combined {comb:.2f}"
+ (" (no second channel)" if len(ds) == 1 else f" (x{comb / best:.2f})"))
off = c["offset"]
if off is None:
print(" 3 one channel: no timing to check")
else:
ok = -45 <= off <= 125
print(f" 3 sound {'late' if off > 0 else 'early'} by {abs(off)} ms:"
f" {'within' if ok else 'OUTSIDE'} the -45/+125 ms detectability limits")
if c["speech"]:
fuse = -30 <= off <= 170
where = "inside" if fuse else "outside"
print(f" speech fusion window -30/+170 ms: {where}")
a = c["active"]
if a is None:
print(" 4 not applicable")
else:
print(f" 4 learner steers {a:.0%} of practice:"
f" {'ok' if a >= 0.5 else 'FLAG mostly passive'}")
# A online pronunciation video
# 1 weights hearing 0.69, lips 0.31: ok
# combined sd 0.83; if hearing gets 3x noisier: 1.34
# 2 best single d' 0.8, combined 1.00 (x1.25)
# 3 sound late by 160 ms: OUTSIDE the -45/+125 ms detectability limits
# speech fusion window -30/+170 ms: inside
# 4 learner steers 20% of practice: FLAG mostly passive
# B dashboard lane alert
# 1 weights icon 1.00: FLAG single channel
# combined sd 1.00; if icon gets 3x noisier: 3.00
# 2 best single d' 1.2, combined 1.20 (no second channel)
# 3 one channel: no timing to check
# 4 not applicable
# C motor-skill app
# 1 weights video 0.50, hearing 0.32, wrist buzz 0.18: ok
# combined sd 0.85; if video gets 3x noisier: 1.14
# 2 best single d' 2.0, combined 2.69 (x1.35)
# 3 sound early by 40 ms: within the -45/+125 ms detectability limits
# 4 learner steers 60% of practice: okPronunciation video: hearing and lip-reading have weights of 0.69 and 0.31, so this is not a single-channel design; but if the learner watches in a noisy place and hearing becomes three times noisier, the combined standard deviation rises from 0.83 to 1.34. The two weak signals together lift from 0.8 to 1.00. The problem is step 3: a Bluetooth headset or similar makes sound arrive 160 ms late, beyond the threshold of detectability, so viewers will notice that lips and sound do not match; it is still within the fusion window for speech, so it need not break fusion, but it distracts and should be corrected at the production or playback end. Step 4: the learner spends only 20 % of the time speaking and the rest watching and listening, and is flagged as too passive.
Lane-departure alert: a single visual icon with weight 1.00 is flagged as a high-risk single channel. Driving loads vision heavily, and when the icon’s reliability falls threefold there is no backup at all. Adding a sound or a seat vibration is the change that steps 1 and 2 jointly recommend.
Motor-skill app: video, sound and wrist vibration carry weights of 0.50, 0.32 and 0.18; when the video becomes three times noisier, the combined standard deviation rises only from 0.85 to 1.14, so the design degrades gracefully. Sound leads the picture by 40 ms, within the threshold of detectability; the learner practises actively 60 % of the time.
Part 2 A pre-registered randomised controlled trial
Question
When adult beginners practise imitating pitches and vowels, does adding vibrotactile feedback that encodes their real-time pitch or formant error, under otherwise identical audiovisual conditions, reduce their pitch-imitation error 24 hours later, with no feedback of any kind, compared with wearing the same device switched off?
The framework’s question concerns “imitation learning of complex pronunciation or movement”. This protocol chooses vocal production: pitch (fundamental frequency) and vowel formants can both be measured objectively and automatically from recordings, with well-established algorithms (see the program below). Because a vocal task is closer to the author’s singing-training business, the protocol strengthens its arrangements for independence (see the ethics section).
Placing the primary outcome after feedback is withdrawn is deliberate. The “guidance hypothesis” from research on motor learning holds that frequent, immediate augmented feedback can raise performance during practice yet make learners depend on it, so that retention is worse once it is removed (Salmoni et al. 1984). The trial therefore looks not at how accurately people sing during training but at how they perform 24 hours later, without the device and without feedback.
The trial tests the idea in the hypothesis box of Chapter 3. It borders on the subjects of volume 10 (the biomechanics of phonation), volume 23 (deliberate practice) and volume 29 (auditory–motor feedback); it only cross-refers to them and does not repeat their material.
Measurement
On each trial the participant hears through headphones a target tone of about 1.5 s (a synthesised voice in the register of the participant’s sex, on the vowel /a/), and after a cue sings the same pitch on /a/ for about 2 s. The fundamental frequency is estimated over the stable middle second of each trial with the YIN algorithm (Cheveigné and Kawahara 2002), the median is taken and compared with the target:
where is the fundamental of the target and is in cents, with 100 cents to a semitone. This measure (the stable middle, its median, conversion to cents, then the mean of the absolute values) is the one used in the pitch assessment of Chapter 8 of volume 10, which read the fundamental in Praat; it is not repeated here, and only the estimation algorithms for the fundamental and the formants are added as a sketch. Formants are estimated from the peaks of a linear-prediction (LPC) envelope (Makhoul 1975), and the vowel error is the Euclidean distance of the deviations of F1 and F2, each measured in semitones. The program below uses only the standard library to show how the two steps work: it synthesises a vowel with known fundamental frequency and formants, then estimates them back.
Calculation
# How the Chapter 8 outcomes are measured: a SIMPLIFIED sketch, not lab software.
# A vowel is synthesised (pulse train -> glottal low-pass -> 4 formant resonators,
# sampling rate 10 kHz); f0 is recovered with YIN (de Cheveigne & Kawahara 2002:
# difference function, cumulative-mean normalisation, threshold 0.1, parabolic
# interpolation) and F1/F2 from the peaks of an order-12 LPC envelope (autocorrelation
# method, Levinson-Durbin; Makhoul 1975). Pitch error in cents = 1200 log2(f0 / target).
# Formant distance = Euclidean distance of F1 and F2 in semitones (st). Formant values and
# the "sung" errors are ILLUSTRATIVE; a real trial would use validated software.
import cmath, math, random, statistics
FS = 10000
def vowel(f0, formants, rng, dur=0.25):
n = int(FS * dur); x = [0.0] * n; t = 0.0
while t < n:
x[int(t)] = 1.0; t += FS / f0
for _ in range(2): # glottal roll-off
y = 0.0
for i in range(n):
y = 0.9 * y + x[i]; x[i] = y
for f, bw in formants: # cascade of resonators
r = math.exp(-math.pi * bw / FS); c = 2 * r * math.cos(2 * math.pi * f / FS)
y1 = y2 = 0.0
for i in range(n):
y = x[i] + c * y1 - r * r * y2; y2, y1 = y1, y; x[i] = y
peak = max(abs(v) for v in x)
return [v / peak + rng.gauss(0, 0.002) for v in x]
def yin(x, start, fmin=70, fmax=600, w=300, thr=0.1):
tmin, tmax = int(FS / fmax), int(FS / fmin) + 1
d = [0.0] + [sum((x[start + j] - x[start + j + t]) ** 2 for j in range(w))
for t in range(1, tmax + 2)]
cm, run = [1.0], 0.0
for t in range(1, len(d)):
run += d[t]; cm.append(d[t] * t / run)
t = next((t for t in range(tmin, tmax) if cm[t] < thr), None)
if t is None:
t = min(range(tmin, tmax), key=lambda k: cm[k])
while t + 1 < tmax and cm[t + 1] < cm[t]:
t += 1
a, b, c = cm[t - 1], cm[t], cm[t + 1]
return FS / (t + 0.5 * (a - c) / (a - 2 * b + c))
def lpc_formants(x, start, p=12, w=300):
s = [x[start + i] - 0.97 * x[start + i - 1] for i in range(w)]
s = [v * (0.54 - 0.46 * math.cos(2 * math.pi * i / (w - 1))) for i, v in enumerate(s)]
r = [sum(s[i] * s[i + k] for i in range(w - k)) for k in range(p + 1)]
a, e = [1.0] + [0.0] * p, r[0]
for i in range(1, p + 1): # Levinson-Durbin recursion
k = -sum(a[j] * r[i - j] for j in range(i)) / e
a = [a[j] + k * a[i - j] if 0 < j < i else a[j] for j in range(p + 1)]
a[i] = k; e *= 1 - k * k
def gain(f):
w0 = -2j * math.pi * f / FS
return 1 / abs(sum(aj * cmath.exp(w0 * j) for j, aj in enumerate(a)))
fs_ = list(range(150, 4000, 5)); g = [gain(f) for f in fs_]
peaks = [fs_[i] for i in range(1, len(g) - 1) if g[i - 1] < g[i] > g[i + 1]]
return peaks[0], peaks[1]
def semis(a, b):
return 12 * math.log2(a / b)
if __name__ == "__main__":
rng = random.Random(34)
A = [(700, 80), (1200, 90), (2500, 120), (3500, 150)] # illustrative /a/-like vowel
comfort = 150.0 # participant's comfortable f0
sung_err = [+35, -20, +60, -45, +10] # illustrative "true" errors
print("target steps true err YIN f0 measured err (cents)")
meas = []
for st, err in zip((-4, -2, 0, 2, 4), sung_err):
target = comfort * 2 ** (st / 12); sung = target * 2 ** (err / 1200)
x = vowel(sung, A, rng)
f0 = statistics.median(yin(x, s) for s in (800, 1100, 1400)) # stable middle
meas.append(1200 * math.log2(f0 / target))
print(f"{target:6.1f} {st:+4d} {err:+8d} {f0:6.1f} {meas[-1]:+8.1f}")
print(f"mean absolute error: true {statistics.mean(map(abs, sung_err)):.1f},"
f" measured {statistics.mean(map(abs, meas)):.1f} cents")
print("formants of the same vowel (true F1 700, F2 1200) as f0 rises:")
for f0 in (110, 220, 330, 440):
f1, f2 = lpc_formants(vowel(f0, A, rng), 1200)
dist = math.hypot(semis(f1, 700), semis(f2, 1200))
print(f" f0 {f0:3d} Hz: LPC F1 {f1:4d}, F2 {f2:4d}; distance {dist:4.2f} st")
# target steps true err YIN f0 measured err (cents)
# 119.1 -4 +35 121.6 +36.1
# 133.6 -2 -20 132.0 -21.0
# 150.0 +0 +60 155.4 +61.6
# 168.4 +2 -45 164.0 -46.0
# 189.0 +4 +10 189.9 +8.1
# mean absolute error: true 34.0, measured 34.6 cents
# formants of the same vowel (true F1 700, F2 1200) as f0 rises:
# f0 110 Hz: LPC F1 690, F2 1200; distance 0.25 st
# f0 220 Hz: LPC F1 665, F2 1175; distance 0.96 st
# f0 330 Hz: LPC F1 665, F2 1225; distance 0.96 st
# f0 440 Hz: LPC F1 455, F2 895; distance 9.02 stThe five targets in the program lie 2 and 4 semitones above and below the participant’s comfortable pitch (150 Hz in the example), and the “sung” errors are illustrative settings. The errors estimated by YIN differ from the settings by 1.0 to 1.9 cents (from simplifications in both synthesis and estimation, for instance pulses that can fall only on whole samples), and the mean absolute error over the five trials is 34.6 cents against a true 34.0, far below the smallest effect of interest of 20 cents used below. Formants are another matter: at a fundamental of 110 Hz the LPC estimates of F1/F2 are off by only 0.25 semitones, but at 440 Hz the harmonics are sparse and the envelope peaks are “captured” by them (F1 455 Hz, F2 895 Hz, close to the harmonics at 440 and 880 Hz), a distance of 9.02 semitones. The protocol therefore keeps formants as a secondary outcome, has every vowel trial sung at the participant’s comfortable pitch, and specifies in advance that estimates are spot-checked against spectrograms by staff unaware of allocation. The real trial uses validated speech-analysis software, with all settings published before enrolment.
Design
| Element | Specification |
|---|---|
| Participants | Adults aged 18 to 45, recruited through channels unconnected with the author; none from the author’s students, community, customers or card-deck users; excluded: more than two years of formal singing or voice training, professional singers or professional voice users, hearing loss found at screening, a current voice disorder or hoarseness lasting more than two weeks, laryngeal surgery, neurological or movement disorders, broken skin or sensory loss on the forearm or wrist, implanted electronic medical devices; anyone with an acute upper respiratory infection on a test day is rescheduled |
| Task | Pitch trials: five targets, 2 and 4 semitones above and below the participant’s comfortable pitch, imitated on /a/. Vowel trials: two vowels absent from the participant’s native language, with target F1/F2 taken from recordings of a model speaker of the same sex and scaled to the participant’s own baseline /i/, /a/ and /u/ (method registered before enrolment). Everyone first completes a baseline test without feedback |
| Randomisation | Individuals allocated 1:1, stratified by sex and by whether baseline pitch error reaches 100 cents; the sequence generated by computer by staff not involved in recruitment and revealed only after the baseline test |
| Conditions common to both arms | The same headphones play the same targets, and participants hear their own natural voice (no masking or pitch shifting); the screen shows only the target symbol and a countdown, with no real-time pitch trace in either arm, and no scores are given during or after training; a vibration band of the same model is worn on each forearm near the wrist, switched on, with the same indicator light |
| Arm A (vibrotactile error feedback) | On pitch trials the device estimates the fundamental in real time: the left band vibrates when the voice is flat and the right when it is sharp, with no vibration within ±15 cents and a pulse rate that rises with the error beyond that (top rate at 100 cents or more); on vowel trials both bands vibrate together, with a pulse rate that rises with the F1/F2 distance and no vibration within 1 semitone; the device log records the delay from voice to vibration |
| Arm B (control) | Wears the same bands, switched on but not vibrating; everything else as in arm A |
| Site of the bands | The forearm near the wrist, because hands and face stay free; not the neck, where vibration would mix with the larynx’s own vibration during phonation, could press on the throat and could be picked up by the microphone; and real-time pitch information encoded as vibration on the forearm has improved pitch discrimination in normal-hearing listeners hearing simulated cochlear-implant sound (Fletcher et al. 2020) |
| Training dose | Three 10-minute blocks on one day with 5-minute breaks; the number and order of pitch and vowel trials in each block are the same in both arms |
| Blinding | Participants cannot be blinded to whether they feel vibration; they are told only that the study compares two settings of a wristband, not the hypothesis; at the 24-hour test the bands are removed, the test procedure is identical and run by staff unaware of allocation; the outcome is computed automatically by pre-written code; analysts are blind to arm until data and code are locked |
| Primary outcome | 24 hours (±2 hours) after training, without the device and with no feedback of any kind, each of the five targets is sung 4 times (20 trials in random order); the outcome is the mean of the absolute pitch errors over the 20 trials, in cents; lower is better |
| Secondary outcomes | F1/F2 distance (semitones) for the vowels at 24 hours; error at the end of training; error at 7 days; consistency across repeats of the same target (SD of the signed error); error on untrained targets (1 and 3 semitones above and below comfortable pitch); proportion of trials within ±50 cents; self-rated vocal discomfort and effort |
| Analysis | Analysis of covariance with the primary outcome as dependent variable, arm as factor, and baseline error and strata as covariates; the difference B − A with its 95 % confidence interval is reported, positive values meaning arm A is more accurate; two-sided . Because pitch errors are right-skewed, a sensitivity analysis on the log scale is pre-registered; it is reported but does not change the verdict |
The mean absolute error in cents was chosen as the single primary outcome because it is a common measure of imitation accuracy in research on singing, computed automatically with algorithms such as YIN and needing no raters (Hutchins et al. 2014); and because, as a continuous measure, it keeps more information than a dichotomous measure such as “the proportion within ±50 cents” and does not hit a ceiling for people who already sing fairly accurately. Formant measurement depends on the fundamental (see the program above), so formants are a secondary outcome.
Pilot and re-estimation of the sample size
The author found no published effect size for “training pitch with vibrotactile feedback” that could be borrowed, and the between-person standard deviation of the error can only be roughly inferred from published means. Most published studies report means: 78 adults imitating single pitches had a mean absolute error of about 66 cents (Demorest and Pfordresher 2015); in the second experiment of Pfordresher and Brown (2007), 7 of 45 people (16 %) were poor-pitch singers, with a mean absolute error of 229 cents against about 30 cents for 7 matched accurate singers (Pfordresher and Brown 2007). In another study, 22 participants imitating five target pitches with their voices had a mean absolute error of about 38 cents (Hutchins et al. 2014). Such distributions are strongly right-skewed: a minority of poor-pitch singers raises both the mean and the standard deviation. The trial in Chapter 8 of volume 10 used the same outcome (mean absolute pitch error over five target notes) and assumed a between-person standard deviation of 20 cents, to be checked in a pilot; on the figures above that assumption is probably too low for unselected adult beginners, so this book takes a more cautious planning value (below) and leaves it to the pilot to re-estimate.
The protocol therefore has two steps. First, a small external pilot with n = 20 (10 per arm, same protocol as the main trial) tests the procedures and estimates the standard deviation of the 24-hour error and its correlation with baseline. Pilot data do not enter the main analysis. Second, the sample size of the main trial is recalculated by a rule written as code in advance:
- The standard deviation is the one-sided 80 % upper confidence limit of the pooled within-arm pilot standard deviation (18 degrees of freedom) (Browne 1995). Sim and Lewis (2012) also used the upper-confidence-limit approach, but with a 95 % limit, and argued that the size of a pilot should be set by considerations of precision and overall efficiency; their analysis points to pilots of about 55 people or more in total (Sim and Lewis 2012). By the author’s decision this protocol uses only 20, at the cost that the upper limit inflates the standard deviation 1.183-fold and the sample size about 1.40-fold.
- The correlation with baseline is the pilot estimate, but no higher than the planned 0.6 and no lower than 0.
- The effect size is not estimated from the pilot. The smallest effect of interest is fixed in advance at 20 cents (about one fifth of a semitone) and does not change with the pilot. With 10 per arm the standard error of the difference between arms is about 27 cents, larger than the smallest effect of interest itself; a sample size based on such an estimate would be randomly too large or too small, and proceeding only when a pilot “looks effective” leads later studies systematically to overestimate the effect and underestimate the numbers needed (Kraemer et al. 2006). The pilot statistician therefore reports only the pooled standard deviation and the correlation, and neither computes nor reports the difference between arms.
- The final number of analysable participants per arm is bounded between 150 and 350: the lower bound protects against a pilot standard deviation that happens to be small making the trial too small; the upper bound is a constraint of feasibility. If the rule gives more than the upper bound, the trial runs with 350 per arm, and the registration states that the actual power at the pilot values is below 90 %.
Calculation
# Sample size for the Chapter 8 trial, with a pre-registered re-estimation rule.
# Primary outcome: mean absolute pitch error (cents) when imitating 5 target notes,
# 24 h after training, without feedback. Planning values, all ASSUMED:
# SD between people 75 cents (published means only; see the check below),
# correlation with baseline r 0.6, smallest effect of interest (SESOI) 20 cents,
# two-sided alpha 0.05, 90 % power, 15 % loss. ANCOVA on the baseline shrinks the
# variance by (1 - r^2) (Borm, Fransen & Lemmens 2007).
# Pilot rule: external pilot, n = 20 (10 per arm), never in the main analysis. An
# independent statistician reports only the pooled within-arm SD (df 18) and r.
# SD used = one-sided 80 % upper confidence limit (Browne 1995); r used = pilot r, but
# never above the planned 0.6 nor below 0. SESOI stays 20: the pilot never estimates
# the effect. Final n is clamped to [150, 350] analysable per arm.
import math, random
from statistics import NormalDist
N = NormalDist()
SESOI, LOSS, N_MIN, N_MAX = 20.0, 0.15, 150, 350
def per_arm(sd, delta, r, alpha=0.05, power=0.90):
z = N.inv_cdf(1 - alpha / 2) + N.inv_cdf(power) # +1 below ~ t correction z_a^2/4
return math.ceil(2 * z ** 2 * sd ** 2 * (1 - r ** 2) / delta ** 2) + 1
def chi2_cdf(x, k): # regularised lower gamma P(k/2, x/2), series
a, y = k / 2, x / 2
term = total = 1 / a
for i in range(1, 500):
term *= y / (a + i); total += term
return total * math.exp(-y + a * math.log(y) - math.lgamma(a))
def chi2_ppf(p, k):
lo, hi = 1e-9, 10 * k + 100
for _ in range(100):
mid = (lo + hi) / 2
lo, hi = (mid, hi) if chi2_cdf(mid, k) < p else (lo, mid)
return (lo + hi) / 2
def reestimate(s, r, df=18, conf=0.80):
s_up = s * math.sqrt(df / chi2_ppf(1 - conf, df))
r_use = min(max(r, 0.0), 0.6)
n = per_arm(s_up, SESOI, r_use)
return s_up, r_use, n, min(max(n, N_MIN), N_MAX)
def simulate(rng, n, true_diff, sd=75.0, r=0.6, sims=3000):
benefit = strongest = 0
for _ in range(sims):
arms = []
for shift in (0.0, -true_diff): # arm A lowers the error
xs = [rng.gauss(0, sd) for _ in range(n)]
ys = [r * x + rng.gauss(shift, sd * math.sqrt(1 - r * r)) for x in xs]
arms.append((xs, ys))
cx = [[x - sum(xs) / n for x in xs] for xs, _ in arms] # centre within arms
cy = [[y - sum(ys) / n for y in ys] for _, ys in arms]
b = sum(x * y for a, c in zip(cx, cy) for x, y in zip(a, c)) \
/ sum(x * x for a in cx for x in a)
adj = [sum(y - b * x for x, y in zip(xs, ys)) / n for xs, ys in arms]
d = adj[0] - adj[1] # B minus A: positive = A better
rss = sum((y - b * x) ** 2 for a, c in zip(cx, cy) for x, y in zip(a, c))
lo = d - 1.96 * math.sqrt(rss / (2 * n - 3) * 2 / n)
benefit += lo > 0; strongest += lo >= SESOI
return benefit / sims, strongest / sims
if __name__ == "__main__":
p, good, poor = 7 / 45, 30.0, 229.0 # Pfordresher & Brown 2007, Exp. 2
print(f"check: {p:.0%} poor-pitch singers (229 c), rest 30 c -> mean"
f" {p * poor + (1 - p) * good:.0f} c; split alone gives SD"
f" {math.sqrt(p * (1 - p)) * (poor - good):.0f} c")
n = per_arm(75, SESOI, 0.6); rec = math.ceil(n / (1 - LOSS))
print(f"plan: SD 75, r 0.6, SESOI 20 (d = {20 / 75:.2f}), 90 % power: {n} per arm,"
f" recruit {rec} ({2 * rec})")
print("analysable per arm SESOI 15 20 30")
for sd in (60, 75, 90):
for r in (0.4, 0.6):
print(f" SD {sd}, r {r:.1f} {'':8s}"
+ "".join(f"{per_arm(sd, dl, r):7d}" for dl in (15, 20, 30)))
se = 75 * math.sqrt(2 / 10) * math.sqrt(1 - 0.36)
print(f"pilot of 10 per arm: SE of an arm difference about {se:.0f} c (SESOI 20)")
k = math.sqrt(18 / chi2_ppf(0.20, 18))
print(f"80 % upper limit with df 18: SD x {k:.3f}, so n x {k * k:.2f}")
print("pilot SD, r -> SD used, r used -> n per arm -> clamped -> recruit (all)")
for s, r in ((50, 0.65), (60, 0.70), (75, 0.60), (90, 0.45)):
s_up, r_lo, raw, n2 = reestimate(s, r)
rec2 = math.ceil(n2 / (1 - LOSS))
print(f" {s:4d}, {r:.2f} -> {s_up:5.1f}, {r_lo:.2f} -> {raw:4d} -> {n2:3d}"
f" -> {rec2} ({2 * rec2})")
rng = random.Random(2026)
for true in (0.0, 20.0, 40.0):
p_any, p_top = simulate(rng, n, true)
print(f"true benefit {true:4.1f}: P(some benefit verdict) {p_any:.3f},"
f" P(benefit >= SESOI shown) {p_top:.3f}")
# check: 16% poor-pitch singers (229 c), rest 30 c -> mean 61 c; split alone gives SD 72 c
# plan: SD 75, r 0.6, SESOI 20 (d = 0.27), 90 % power: 191 per arm, recruit 225 (450)
# analysable per arm SESOI 15 20 30
# SD 60, r 0.4 284 160 72
# SD 60, r 0.6 217 123 55
# SD 75, r 0.4 443 250 112
# SD 75, r 0.6 338 191 86
# SD 90, r 0.4 637 359 160
# SD 90, r 0.6 486 274 123
# pilot of 10 per arm: SE of an arm difference about 27 c (SESOI 20)
# 80 % upper limit with df 18: SD x 1.183, so n x 1.40
# pilot SD, r -> SD used, r used -> n per arm -> clamped -> recruit (all)
# 50, 0.65 -> 59.2, 0.60 -> 119 -> 150 -> 177 (354)
# 60, 0.70 -> 71.0, 0.60 -> 171 -> 171 -> 202 (404)
# 75, 0.60 -> 88.7, 0.60 -> 266 -> 266 -> 313 (626)
# 90, 0.45 -> 106.5, 0.45 -> 477 -> 350 -> 412 (824)
# true benefit 0.0: P(some benefit verdict) 0.028, P(benefit >= SESOI shown) 0.000
# true benefit 20.0: P(some benefit verdict) 0.908, P(benefit >= SESOI shown) 0.026
# true benefit 40.0: P(some benefit verdict) 1.000, P(benefit >= SESOI shown) 0.894The first line of the program makes a rough check with Pfordresher and Brown’s numbers: if 16 % of people have a mean error of 229 cents and the rest 30 cents, the overall mean is about 61 cents (of the same order as the 66 cents reported by Demorest and Pfordresher), and the difference between these two kinds of singer alone produces a standard deviation of about 72 cents. On this basis the book takes as planning values a standard deviation of 75 cents, a correlation with baseline of 0.6, and a smallest effect of interest of 20 cents (about 0.27 standard deviations). All three are the author’s assumptions, not published estimates. Analysis of covariance uses the baseline to multiply the required number by (Borm et al. 2007). Under these assumptions 191 analysable participants are needed per arm; allowing for about 15 % loss and exclusion, 225 per arm are recruited, 450 in all. The sensitivity table shows that with a standard deviation of 90 and a correlation of 0.4, 359 per arm would be needed; with 60 and 0.6, only 123.
In the re-estimation examples, a pilot that returns exactly the planning values (standard deviation 75, correlation 0.6) yields 266 per arm (313 recruited, 626 in all), more than the plan, because the upper confidence limit is deliberately conservative; a pilot standard deviation of 50 yields 119, raised to the lower bound of 150; a pilot with 90 and 0.45 yields 477, cut to the upper bound of 350 (412 recruited, 824 in all).
The last three lines of the program check the statistical properties of the decision rule with 3,000 simulations, consistent with the conclusion of volume 33: “90 % power” means the probability of reaching some verdict of benefit when the true effect equals the smallest effect of interest (simulated: 0.908); in that case the strongest verdict, “at least the smallest effect of interest”, appears only about 2.5 % of the time (simulated: 0.026, with Monte Carlo error of about 0.003); to reach the strongest verdict with about 90 % probability, the true effect must be about twice the smallest effect of interest (simulated at 40 cents: 0.894). When the true effect is zero, the probability of wrongly reaching a verdict of benefit is 0.028, close to the nominal 2.5 %. The simulation assumes normally distributed errors; real data are right-skewed, which is one reason for the pilot and the sensitivity analysis.
Decision rule
Calculation
# Decision rule fixed before enrolment. D = arm B minus arm A in 24-h pitch error (cents),
# adjusted for baseline and stratum; 95 % CI; positive = arm A (vibrotactile error
# feedback) more accurate. SESOI 20 cents. Gates: more than 25 % of randomised people
# excluded, or a fidelity check fails (median voice-to-vibration latency above 60 ms in
# the device log, or under 90 % of planned training minutes delivered in either arm)
# -> NOT INTERPRETABLE. Secondary outcomes never decide the verdict.
SESOI = 20
def verdict(d, lo, hi, excluded=0.10, fidelity_ok=True):
if excluded > 0.25:
return f"D = {d:+.0f}: NOT INTERPRETABLE - {excluded:.0%} excluded (limit 25 %)"
if not fidelity_ok:
return f"D = {d:+.0f}: NOT INTERPRETABLE - fidelity check failed"
if lo >= SESOI: v = "A beats B by at least the SESOI (20 cents)"
elif lo > 0: v = "A beats B; size not shown to reach 20 cents"
elif hi < 0: v = "A is WORSE than B"
elif lo >= -SESOI and hi <= SESOI: v = "no difference worth acting on"
else: v = "unclear: the interval is too wide to decide"
return f"D = {d:+.0f} ({lo:+.0f} to {hi:+.0f}): {v}"
for case in ((36, 24, 48), (19, 7, 31), (2, -10, 14), (-18, -30, -6),
(10, -22, 42), (30, 18, 42, 0.31), (25, 13, 37, 0.12, False)):
print(verdict(*case))
# D = +36 (+24 to +48): A beats B by at least the SESOI (20 cents)
# D = +19 (+7 to +31): A beats B; size not shown to reach 20 cents
# D = +2 (-10 to +14): no difference worth acting on
# D = -18 (-30 to -6): A is WORSE than B
# D = +10 (-22 to +42): unclear: the interval is too wide to decide
# D = +30: NOT INTERPRETABLE - 31% excluded (limit 25 %)
# D = +25: NOT INTERPRETABLE - fidelity check failedThe example results are invented. If more than 25 % of those randomised are excluded, or a fidelity check fails (the device log shows a median delay from voice to vibration above 60 ms, or either arm completes less than 90 % of the planned training time), the report says “not interpretable” whatever the primary outcome. Only when the lower bound of the confidence interval for the difference is at least 20 cents does the report say “arm A is better by at least the smallest effect of interest”. Secondary outcomes are reported only as estimates with confidence intervals and do not change the verdict.
What this trial cannot show
First, it compares “vibrotactile error feedback” with “the same device not vibrating”, all else equal, so it can say whether adding this tactile feedback helps; but it cannot compare it with other kinds of feedback, such as a visual pitch trace or a teacher’s guidance, nor separate the effect of the error information carried by the vibration from the attention or expectation that “something vibrating” may itself produce; that would need a further control arm receiving vibration unrelated to the error. Second, a sustained /a/ on five pitches in the comfortable range and two unfamiliar vowels cannot stand for singing, speech intonation or foreign-language pronunciation as a whole. Third, retention in the laboratory at 24 hours and 7 days says nothing about the level reached months later. Fourth, the participants are adults without formal vocal training, and the results cannot be extended to children, professional singers, or people with voice disorders or hearing impairment (including cochlear-implant users). Fifth, participants know whether they feel vibration, so expectation effects cannot be wholly excluded. Sixth, whatever the result, it cannot be used to support or oppose any particular course, device or the author’s teaching methods.
Ethics and conflicts of interest
The trial carries little risk but must still be approved by an independent ethics committee, with informed consent from participants.
Vocal load. No training block lasts more than 10 minutes and training totals no more than 30 minutes a day, with 5-minute breaks between blocks; drinking water is provided and participants are encouraged to drink during breaks; every target lies within 4 semitones of the participant’s comfortable pitch and is sung at a comfortable loudness, with no demand to sing loudly or with effort; people with a voice disorder, persistent hoarseness or laryngeal surgery do not take part, and anyone with an acute upper respiratory infection on a test day is rescheduled; participants stop at once, without consequence, if they notice a sore throat, hoarseness, coughing or any discomfort; anyone still hoarse the next day is followed up by the research staff and advised to see a doctor.
Vibration safety. The bands use low-power vibration elements of the kind found in the haptic alerts of phones and smartwatches; pulses are brief, and total vibration time is a small fraction of the 30 minutes of training, far below the levels that occupational limits for hand–arm vibration address (EU Directive 2002/44/EC sets an action value of 2.5 m/s² as an 8-hour equivalent); people with broken skin or sensory loss on the forearm or wrist, or with implanted electronic medical devices, do not take part; and participants may remove the bands or withdraw at any time without consequence.
Independence. Because the vocal task is closer to the author’s singing-training business, the training materials use no content from the author’s courses, no participants are recruited from the author’s students, and the trial is run and analysed by independent researchers. The protocol, the target and vowel materials, the device’s encoding program and the analysis code are publicly registered before the first participant is enrolled; if possible the study is submitted as a Registered Report, so that publication does not depend on the result. After the trial, participants in arm B are offered arm A’s training. Recordings and data are stored anonymously.
Disclosure
The author teaches singing at vocal.guru and singingasia.com, founded the 耳根圆通法 (Ergen Yuantong) auditory-feedback training method and develops related perceptual-training courses, and therefore has a direct commercial interest in the subject of this book and in the result of this chapter’s trial. In addition, the author uses the works of 5D Library, including this book, as the methodological basis of his community courses, the 5D Ascension Cards (Dimensional Shift Card Decks) and the Yafu AI knowledge base, and therefore has a commercial interest in the subject of this book. The book promotes no course, card deck or service; this chapter’s trial is designed to be run and analysed by researchers independent of the author’s businesses and does not recruit from the author’s students, community or customers. Because the vocal task of this chapter’s trial is closer to the author’s singing-training business, its training materials use no content from the author’s courses, no participants are recruited from the author’s students, and the trial is run and analysed by independent researchers. All the code and the study protocol are published openly for anyone to check. To limit the influence of these interests, the training materials, test procedure and analysis code will be published before enrolment, and the results, data and code will be published whatever the outcome.
Chapter summary
The four-step checklist asks in turn whether a design depends on a single channel that may fail, whether weak signals have synchronous support from a second channel, whether the audiovisual timing difference lies within the asymmetric window (sound no more than about 45 ms early or 125 ms late), and how much of the time the learner explores actively. The pre-registered trial compares, under identical audiovisual conditions, “real-time pitch or formant error encoded as forearm vibration” with “the same device not vibrating”, measured by pitch-imitation error without feedback 24 hours later. It has a single primary outcome in cents; an external pilot of 20 people followed by a sample-size rule written as code (standard deviation at its 80 % upper confidence limit, smallest effect of interest fixed at 20 cents, 150 to 350 per arm), with a plan of 191 analysable participants per arm (225 recruited); a decision rule written as code; safety provisions for vocal load and vibration; and it will be published whatever the result.
References
Fan, Y. (2026). Psychophysics, the Weber-Fechner Law and Optimal Bayesian Multisensory Integration: From Stevens's Power Law and the McGurk Effect to Sensory Substitution, Read Beside Classical Chinese Thought on the Six Senses [心理物理学、韦伯-费希纳定律与多感官贝叶斯整合的数学模型] (Version 1.0.0). 5D Library. https://doi.org/10.5281/zenodo.23788548 · Licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).