We already had tremolo articulations for the violins, but not for the other string sections. I created them by adding together lots of overlapping staccato notes, staggering the times to create a realistic unmeasured tremolo. I believe that's how Mattias created the violin ones.
For posterity, here is the script I used. It reads the sfz file for a staccato articulation, creates the audio files for the tremolo samples, and outputs an sfz file (which requires minor edits afterward). The variables time_scale and amp_scale are customized for each instrument.
import numpy as np
import scipy.io
import soundfile
import librosa
import sys
import os
def createSample(staccato_name):
sample_rate, stac1 = scipy.io.wavfile.read(staccato_name)
sample_rate, stac2 = scipy.io.wavfile.read(staccato_name.replace('rr1', 'rr2'))
stac1 = stac1/32767
stac2 = stac2/32767
stac2 = [librosa.effects.pitch_shift(stac2[:,0], sr=sample_rate, n_steps=-1), librosa.effects.pitch_shift(stac2[:,1], sr=sample_rate, n_steps=-1)]
stac2 = np.array(stac2).T
stac1[:,0] *= np.linspace(1, 0, stac1.shape[0])
stac1[:,1] *= np.linspace(1, 0, stac1.shape[0])
stac2[:,0] *= np.linspace(1, 0, stac2.shape[0])
stac2[:,1] *= np.linspace(1, 0, stac2.shape[0])
notes = [(0.0, 0, 1.0)]
for i in range(60):
delay = 0.9 + 0.2*np.random.rand()
amp = 0.9 + 0.2*np.random.rand()
notes.append((delay, 1-notes[-1][1], amp))
num_repeated = 30
for i in range(num_repeated):
notes.append(notes[i+1])
time_scale = 0.07*sample_rate
amp_scale = 0.45
output = np.zeros((int(time_scale*len(notes)*2), 2), dtype=np.float32)
start_times = []
last_start = 0
for delay, note, amp in notes:
n = stac1 if note == 0 else stac2
start = last_start + int(time_scale*delay)
length = n.shape[0]
output[start:start+length, 0] += amp_scale*amp*n[:,0]
output[start:start+length, 1] += amp_scale*amp*n[:,1]
start_times.append(start)
last_start = start
output = output[:start_times[-1]+1,:]
output_path = staccato_name.replace('stc-rr1', 'trm').replace('wav', 'flac')
soundfile.write(output_path, output, sample_rate)
return output_path, start_times[num_repeated], start_times[-1]
group = 0
for line in open(sys.argv[1]):
line = line.strip()
if line == '<group>':
if group == 0:
group = 1
else:
break
if line.startswith('loop_mode'):
print('loop_mode=loop_continuous')
elif line.startswith('sample='):
line = line.replace('\\', '/')
output_path, loop_start, loop_end = createSample(line[7:])
print(f'sample={output_path}')
print(f'loop_start={loop_start}')
print(f'loop_end={loop_end}')
else:
print(line)
We already had tremolo articulations for the violins, but not for the other string sections. I created them by adding together lots of overlapping staccato notes, staggering the times to create a realistic unmeasured tremolo. I believe that's how Mattias created the violin ones.
For posterity, here is the script I used. It reads the sfz file for a staccato articulation, creates the audio files for the tremolo samples, and outputs an sfz file (which requires minor edits afterward). The variables
time_scale
andamp_scale
are customized for each instrument.