1 #include "Sfz.hpp"
2 #include <iostream>
3 #include <fstream>
4 #include <string>
5 
remapvelocityranges(::sfz::Instrument * inst)6 void Sfz::remapvelocityranges(::sfz::Instrument *inst)
7 {
8 	int i, k, r, key, oldkey, l, lowest, idx;
9 	::sfz::SFZRegion *reg;
10 	std::vector< ::sfz::SFZRegion > tmp;
11 	std::vector< ::sfz::SFZRegion* > remap;
12 	int layer[128] = {0};
13 
14 	if (!inst)
15 		return;
16 
17 	for (i = 0; i < inst->regions.size(); i++) {
18 		if (inst->regions[i]->lokey == inst->regions[i]->hikey) {
19 			key = inst->regions[i]->lokey;
20 		} else {
21 			key = inst->regions[i]->pitch_keycenter;
22 		}
23 		layer[key]++;
24 	}
25 
26 	for (key = 0; key < 128; key++) {
27 		lowest = 2;
28 		idx = -1;
29 		for (i = 0; i < layer[key]; i++) {
30 			// find next region with correct key
31 			for (r = idx+1; r < inst->regions.size(); r++) {
32 				if (inst->regions[r]->lokey == inst->regions[r]->hikey) {
33 					k = inst->regions[r]->lokey;
34 				} else {
35 					k = inst->regions[r]->pitch_keycenter;
36 				}
37 				if (k != key)
38 					continue;
39 
40 				if (inst->regions[r]->lovel <= lowest) {
41 					idx = r;
42 					lowest = inst->regions[r]->hivel + 2;
43 					break;
44 				}
45 			}
46 			if (idx >= 0) {
47 				// push found region to new vector
48 				tmp.push_back(*(inst->regions[idx]));
49 			}
50 		}
51 	}
52 
53 	oldkey = -1;
54 	for (i = 0; i < tmp.size(); i++) {
55 		if (tmp[i].lokey == tmp[i].hikey) {
56 			key = tmp[i].lokey;
57 		} else {
58 			key = tmp[i].pitch_keycenter;
59 		}
60 		if (key != oldkey) {
61 			if (layer[key] > MAX_LAYERS) {
62 				// Remap velocities
63 				// Choose staggered layers
64 				int chosen, lo, hi;
65 				lo = 0;
66 				hi = 0;
67 				for (k = 1; k <= MAX_LAYERS; k++) {
68 					chosen = k * layer[key] / MAX_LAYERS;
69 					lo = hi + 1;
70 					hi = k * 127 / MAX_LAYERS;
71 					reg = new ::sfz::SFZRegion(inst);
72 
73 					tmp[(chosen - 1) + i].lovel = lo;
74 					tmp[(chosen - 1) + i].hivel = hi;
75 					*reg = tmp[(chosen - 1) + i];
76 					remap.push_back(reg);
77 				}
78 			} else {
79 				// 1:1 mapping
80 				for (k = 0; k < layer[key]; k++) {
81 					reg = new ::sfz::SFZRegion(inst);
82 					*reg = tmp[k + i];
83 					remap.push_back(reg);
84 				}
85 			}
86 		}
87 		oldkey = key;
88 	}
89 
90 	inst->regions.clear();
91 	for (i = 0; i < remap.size(); i++) {
92 		inst->regions.push_back(remap[i]);
93 		//printf("k:%d (%d, %d) %s\n", remap[i]->lokey, remap[i]->lovel, remap[i]->hivel, remap[i]->sample.c_str());
94 	}
95 }
96 
readsamples_resample(SNDFILE * infile,SF_INFO * sfinfo,int note,int layer,int target_rate)97 void Sfz::readsamples_resample(SNDFILE *infile, SF_INFO *sfinfo, int note, int layer, int target_rate)
98 {
99 	float buf[sfinfo->channels * BLOCK_SIZE];
100 	float tmpbuf_pre[2][MAX_SAMPLES] = {0.f};
101 	float tmpbuf_post[2][MAX_SAMPLES] = {0.f};
102 	SRC_DATA src;
103 	int k, m, readcount, i;
104 	int maxch = std::min(sfinfo->channels, 2);
105 
106 	// Read samples in blocks to a flat buffer
107 	i = 0;
108 	while (i < MAX_SAMPLES && (readcount = sf_readf_float (infile, buf, BLOCK_SIZE)) > 0) {
109 		for (k = 0 ; k < readcount ; k++) {
110 			for (m = 0; m < maxch; m++) {
111 				tmpbuf_pre[m][i+k] = buf[k*sfinfo->channels + m];
112 			}
113 		}
114 		i += readcount;
115 	}
116 
117 	// Resample...
118 	src.data_in = &tmpbuf_pre[0][0];
119 	src.data_out = &tmpbuf_post[0][0];
120 	src.input_frames = MAX_SAMPLES;
121 	src.output_frames = MAX_SAMPLES;
122 	src.src_ratio = (double)target_rate / (double)sfinfo->samplerate;
123 	if (!src_simple(&src, CONVERTER_TYPE, 1)) {
124 		// Write left samples out to sample buffer
125 		for (i = 0; i < src.output_frames_gen; i++) {
126 			sample[note][layer][0][i] = tmpbuf_post[0][i];
127 		}
128 	}
129 
130 	if (maxch == 2) {
131 		src.data_in = &tmpbuf_pre[1][0];
132 		src.data_out = &tmpbuf_post[1][0];
133 		src.input_frames = MAX_SAMPLES;
134 		src.output_frames = MAX_SAMPLES;
135 		src.src_ratio = (double)target_rate / (double)sfinfo->samplerate;
136 		if (!src_simple(&src, CONVERTER_TYPE, 1)) {
137 			// Write right samples out to sample buffer
138 			for (i = 0; i < src.output_frames_gen; i++) {
139 				sample[note][layer][1][i] = tmpbuf_post[1][i];
140 			}
141 		}
142 	}
143 }
144 
readsamples(SNDFILE * infile,int channels,int note,int layer)145 void Sfz::readsamples(SNDFILE *infile, int channels, int note, int layer)
146 {
147 	float buf[channels*BLOCK_SIZE];
148 	int k, m, readcount, i;
149 
150 	i = 0;
151 	while (i < MAX_SAMPLES && (readcount = sf_readf_float (infile, buf, BLOCK_SIZE)) > 0) {
152 		for (k = 0 ; k < readcount ; k++) {
153 			for (m = 0; m < std::min(channels, 2); m++) {
154 				sample[note][layer][m][i+k] = buf[k*channels + m];
155 			}
156 		}
157 		i += readcount;
158 	}
159 }
160 
Sfz()161 Sfz::Sfz()
162 {
163 }
164 
clearsamples()165 void Sfz::clearsamples()
166 {
167 	int i,j,k;
168 	for (i = 0; i < 128; i++) {
169 		for (j = 0; j < MAX_LAYERS; j++) {
170 			for (k = 0; k < MAX_SAMPLES; k++) {
171 				sample[i][j][0][k] = 0.f;
172 				sample[i][j][1][k] = 0.f;
173 			}
174 		}
175 	}
176 	for (i = 0; i < 128; i++) {
177 		layers[i].max = 0;
178 		for (j = 0; j < MAX_LAYERS; j++) {
179 			layers[i].l[j].lovel = 0;
180 			layers[i].l[j].hivel = 0;
181 			layers[i].l[j].lokey = 0;
182 			layers[i].l[j].hikey = 0;
183 		}
184 	}
185 }
186 
loadsamples(std::string path,std::string filename,int target_rate)187 void Sfz::loadsamples(std::string path, std::string filename, int target_rate)
188 {
189 	int note, i, j, k, key;
190 	::sfz::SFZParser sfzfile;
191 	std::string fullsfzpath = path + std::string("/") + filename;
192 	if (sfzfile.readsfz(fullsfzpath) == -1) {
193 		printf("Can't open SFZ\n");
194 		return;
195 	}
196 	::sfz::Instrument* sfzinstrument = &sfzfile.instrument;
197 
198 	remapvelocityranges(sfzinstrument);
199 
200 	SNDFILE *infile = NULL;
201 	SF_INFO sfinfo;
202 
203 	int maxregions = sfzinstrument->regions.size();
204   if (maxregions == 0) {
205 	printf("No samples found\n");
206   } else {
207 	for (i = 0; i < maxregions; i++) {
208 		for (note = 0; note < 128; note++) {
209 			if (sfzinstrument->regions[i]->lokey == sfzinstrument->regions[i]->hikey) {
210 				key = sfzinstrument->regions[i]->lokey;
211 			} else {
212 				key = sfzinstrument->regions[i]->pitch_keycenter;
213 			}
214 			if (note == key) {
215 				layers[note].keymiddle = key;
216 				layers[note].dsemitones = 0;
217 				infile = NULL;
218 				std::string fullsamplepath = path + std::string("/") + sfzinstrument->regions[i]->sample;
219 				if ((infile = sf_open(fullsamplepath.c_str(), SFM_READ, &sfinfo)) == NULL) {
220 						printf("Missing samples\n");
221 						puts (sf_strerror (NULL));
222 						printf("File: %s\n",fullsamplepath.c_str());
223 				}
224 				k = layers[note].max;
225 				if ((int)sfinfo.samplerate == target_rate) {
226 					readsamples (infile, sfinfo.channels, note, k);
227 				} else {
228 					readsamples_resample (infile, &sfinfo, note, k, target_rate);
229 				}
230 				layers[note].l[k].lovel = sfzinstrument->regions[i]->lovel;
231 				layers[note].l[k].hivel = sfzinstrument->regions[i]->hivel;
232 				layers[note].l[k].lokey = sfzinstrument->regions[i]->lokey;
233 				layers[note].l[k].hikey = sfzinstrument->regions[i]->hikey;
234 				sf_close (infile);
235 				printf("N-%d V-%d %s\n", note, k, sfzinstrument->regions[i]->sample.c_str());
236 				layers[note].max++;
237 				continue;
238 			} else if (sfzinstrument->regions[i]->lokey <= note && sfzinstrument->regions[i]->hikey >= note) {
239 				layers[note].keymiddle = key;
240 				layers[note].dsemitones = note - key;
241 				//printf("MainKey=%d NoteShiftTo=%d\n", key, note);
242 			}
243 		}
244 	}
245 	printf("All samples loaded, Woot!\n");
246   }
247   for (i = 0; i < 128; i++) {
248   	if (!(layers[i].keymiddle == i)) {
249 		k = layers[i].keymiddle;
250 		layers[i].max = layers[k].max;
251 		for (j = 0; j < layers[i].max; j++) {
252 			layers[i].l[j].lovel = layers[k].l[j].lovel;
253 			layers[i].l[j].hivel = layers[k].l[j].hivel;
254 		}
255 	}
256   }
257 }
258 
pitchshiftsamples(int srate)259 void Sfz::pitchshiftsamples(int srate)
260 {
261 	::RubberBand::RubberBandStretcher* rbl = NULL;
262 	::RubberBand::RubberBandStretcher* rbr = NULL;
263 	int i,j;
264 	for (i = 0; i < 128; i++) {
265 		//printf("i=%d ds=%d\n", i, layers[i].dsemitones);
266 		if (!(layers[i].dsemitones == 0)) {
267 			int ii = layers[i].keymiddle;
268 			printf("Pitch shifting... %d\n", layers[i].dsemitones);
269 			for (j = 0; j < layers[ii].max; j++) {
270 				float const * const inl[] = {sample[ii][j][0]};
271 				float const * const inr[] = {sample[ii][j][1]};
272 				float * const outl[] = {sample[i][j][0]};
273 				float * const outr[] = {sample[i][j][1]};
274 				rbl = new ::RubberBand::RubberBandStretcher(srate, 1, 0, 1.0, pow(2.0, layers[i].dsemitones / 12.));
275 				rbr = new ::RubberBand::RubberBandStretcher(srate, 1, 0, 1.0, pow(2.0, layers[i].dsemitones / 12.));
276 
277 				rbl->setMaxProcessSize(MAX_SAMPLES);
278 				rbr->setMaxProcessSize(MAX_SAMPLES);
279 				rbl->setExpectedInputDuration(MAX_SAMPLES);
280 				rbr->setExpectedInputDuration(MAX_SAMPLES);
281 				rbl->process(inl, MAX_SAMPLES, true);
282 				rbr->process(inr, MAX_SAMPLES, true);
283 				rbl->retrieve(outl, MAX_SAMPLES);
284 				rbr->retrieve(outr, MAX_SAMPLES);
285 				delete rbl;
286 				delete rbr;
287 			}
288 		}
289 	}
290 }
291