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