music.pan_transitions¶
- music.pan_transitions(p=((1, 1), (1, 0), (0, 1), (1, 1)), d=(2, 2, 2), method='lin', sample_rate=None, sonic_vector=None)[source]¶
Applies pan transitions to a sonic vector.
- Parameters:
- p
listoftuples,optional List of pan positions, where each tuple represents the amplitude envelope of each channel, by default [(1,1),(1,0),(0,1),(1,1)]
- d
list,optional The duration of each transition in seconds, by default [2,2,2]. Durations past the last transition are not read.
- method
strorlist,optional How each transition moves: ‘lin’, ‘circ’ or ‘exp’, described below. One name is the law of every transition, and a list holds one for each, by default ‘lin’. Names past the last transition are not read.
- sample_rate
intorNone,optional Sample rate of the audio. None, the default, is the rate
music.get_sample_rate()returns.- sonic_vector
ndarray,optional A mono or stereo sound to pan. Without one, the two envelopes themselves are returned.
- p
- Returns:
ndarrayThe
(2, n)panning envelopes, orsonic_vectorscaled by them: as long as the sound, holding the last position past the end of the transitions.
- Raises:
ValueErrorIf there are fewer durations or methods than transitions, or a method is not one of the three. A short list used to reach an
IndexErrorfrom inside the routine.If a transition by ‘circ’ or ‘exp’ starts or ends at a negative amplitude: they are laws of a channel’s power and loudness, which have no sign.
Notes
Each pan transition i takes the amplitude of channel c from p[i][c] toward p[i+1][c], which the next transition starts at, by the law method[i]. Over progress x from 0 toward 1, from amplitude a to b:
'lin', linear in amplitude: a*(1 - x) + b*x 'circ', linear in power along a quarter circle: sqrt((a*cos(pi*x/2))**2 + (b*sin(pi*x/2))**2) 'exp', linear in decibels: a*(b/a)**x
‘exp’ to or from silence, where decibels run out, is
fade()’s exponential fade: 80 dB of it, then a linear one percent to silence. Across (1, 0) to (0, 1), ‘lin’ keeps the sum of the channels’ amplitudes and lets their power dip 3 dB halfway; ‘circ’ keeps their power, since cos(x)**2 + sin(x)**2 = 1; ‘exp’ changes each channel’s loudness at a steady rate and keeps neither. Until 2.0.0methodwas not read, and every transition was ‘lin’.For now, each channel’s signal are kept from mixing. One immediate possibility is to maintain the expected tessitura of the sample amplitudes. Say p = [.5,1,0,.5] ~ [(1,1),(1,0),(0,1),(1,1)]. Then pi,pj = .5,1 might be performed as:
s1 = s1*.5 -> 0 s2 = s1*.5 -> (s1+s2)*.5
Or through sinusoids and exponentials
Make fast and slow fades and parameter transitions using weber-fechner and steven’s laws. E.g.:
pitch_trans = [pitch0*X**(i/Y) for i in range(12)] pitch_trans = [pitch0 + X*i**Y for i in range(12)]
Examples
>>> p = [(0, 1), (1, 0), (0, 1), (1, 1)] >>> d = [2, 2, 2] >>> method = ['lin', 'circ', 'exp'] >>> sonic_vector = np.random.rand(2, 44100 * 6) # Random stereo signal >>> result = pan_transitions(p, d, method, sonic_vector=sonic_vector)