1 module pxtone.pulse.noisebuilder;
2 
3 import pxtone.pxtn;
4 
5 import pxtone.error;
6 import pxtone.pulse.frequency;
7 import pxtone.pulse.oscillator;
8 import pxtone.pulse.pcm;
9 import pxtone.pulse.noise;
10 
11 enum _BASIC_SPS = 44100.0;
12 enum _BASIC_FREQUENCY = 100.0; // 100 Hz
13 enum _SAMPLING_TOP = 32767; //  16 bit max
14 enum _KEY_TOP = 0x3200; //  40 key
15 
16 enum _smp_num_rand = 44100;
17 enum _smp_num = cast(int)(_BASIC_SPS / _BASIC_FREQUENCY);
18 
19 enum _RANDOMTYPE {
20 	None = 0,
21 	Saw,
22 	Rect,
23 }
24 
25 struct _OSCILLATOR {
26 	double incriment;
27 	double offset;
28 	double volume;
29 	const(short)[] p_smp;
30 	bool bReverse;
31 	_RANDOMTYPE ran_type;
32 	int rdm_start;
33 	int rdm_margin;
34 	int rdm_index;
35 }
36 
37 struct _POINT {
38 	int smp;
39 	double mag;
40 }
41 
42 struct _UNIT {
43 	bool bEnable;
44 	double[2] pan;
45 	int enve_index;
46 	double enve_mag_start;
47 	double enve_mag_margin;
48 	int enve_count;
49 	int enve_num;
50 	_POINT[] enves;
51 
52 	_OSCILLATOR main;
53 	_OSCILLATOR freq;
54 	_OSCILLATOR volu;
55 }
56 
57 void _set_ocsillator(_OSCILLATOR* p_to, pxNOISEDESIGN_OSCILLATOR* p_from, int sps, const(short)[] p_tbl, const(short)[] p_tbl_rand) nothrow @safe {
58 	const(short)[] p;
59 
60 	switch (p_from.type) {
61 	case pxWAVETYPE.Random:
62 		p_to.ran_type = _RANDOMTYPE.Saw;
63 		break;
64 	case pxWAVETYPE.Random2:
65 		p_to.ran_type = _RANDOMTYPE.Rect;
66 		break;
67 	default:
68 		p_to.ran_type = _RANDOMTYPE.None;
69 		break;
70 	}
71 
72 	p_to.incriment = (_BASIC_SPS / sps) * (p_from.freq / _BASIC_FREQUENCY);
73 
74 	// offset
75 	if (p_to.ran_type != _RANDOMTYPE.None) {
76 		p_to.offset = 0;
77 	} else {
78 		p_to.offset = cast(double) _smp_num * (p_from.offset / 100);
79 	}
80 
81 	p_to.volume = p_from.volume / 100;
82 	p_to.p_smp = p_tbl;
83 	p_to.bReverse = p_from.b_rev;
84 
85 	p_to.rdm_start = 0;
86 	p_to.rdm_index = cast(int)(cast(double)(_smp_num_rand) * (p_from.offset / 100));
87 	p = p_tbl_rand;
88 	p_to.rdm_margin = p[p_to.rdm_index];
89 
90 }
91 
92 void _incriment(_OSCILLATOR* p_osc, double incriment, const(short)[] p_tbl_rand) nothrow @safe {
93 	p_osc.offset += incriment;
94 	if (p_osc.offset > _smp_num) {
95 		p_osc.offset -= _smp_num;
96 		if (p_osc.offset >= _smp_num) {
97 			p_osc.offset = 0;
98 		}
99 
100 		if (p_osc.ran_type != _RANDOMTYPE.None) {
101 			const(short)[] p = p_tbl_rand;
102 			p_osc.rdm_start = p[p_osc.rdm_index];
103 			p_osc.rdm_index++;
104 			if (p_osc.rdm_index >= _smp_num_rand) {
105 				p_osc.rdm_index = 0;
106 			}
107 			p_osc.rdm_margin = p[p_osc.rdm_index] - p_osc.rdm_start;
108 		}
109 	}
110 }
111 
112 struct pxtnPulse_NoiseBuilder {
113 private:
114 	static immutable short[][pxWAVETYPE.num] _p_tables = genTables();
115 
116 	pxtnPulse_Frequency _freq;
117 
118 public:
119 	pxtnPulse_PCM BuildNoise(ref pxtnPulse_Noise p_noise, int ch, int sps, int bps) const @system {
120 		int offset = 0;
121 		double work = 0;
122 		double vol = 0;
123 		double fre = 0;
124 		double store = 0;
125 		int byte4 = 0;
126 		int unit_num = 0;
127 		ubyte* p = null;
128 		int smp_num = 0;
129 
130 		_UNIT[] units = null;
131 		pxtnPulse_PCM p_pcm;
132 
133 		p_noise.Fix();
134 
135 		unit_num = p_noise.get_unit_num();
136 
137 		units = new _UNIT[](unit_num);
138 		scope(exit) {
139 			units = null;
140 		}
141 
142 		for (int u = 0; u < unit_num; u++) {
143 			_UNIT* pU = &units[u];
144 
145 			pxNOISEDESIGN_UNIT* p_du = p_noise.get_unit(u);
146 
147 			pU.bEnable = p_du.bEnable;
148 			pU.enve_num = p_du.enve_num;
149 			if (p_du.pan == 0) {
150 				pU.pan[0] = 1;
151 				pU.pan[1] = 1;
152 			} else if (p_du.pan < 0) {
153 				pU.pan[0] = 1;
154 				pU.pan[1] = cast(double)(100.0f + p_du.pan) / 100;
155 			} else {
156 				pU.pan[1] = 1;
157 				pU.pan[0] = cast(double)(100.0f - p_du.pan) / 100;
158 			}
159 
160 			pU.enves = new _POINT[](pU.enve_num);
161 
162 			// envelope
163 			for (int e = 0; e < p_du.enve_num; e++) {
164 				pU.enves[e].smp = sps * p_du.enves[e].x / 1000;
165 				pU.enves[e].mag = cast(double) p_du.enves[e].y / 100;
166 			}
167 			pU.enve_index = 0;
168 			pU.enve_mag_start = 0;
169 			pU.enve_mag_margin = 0;
170 			pU.enve_count = 0;
171 			while (pU.enve_index < pU.enve_num) {
172 				pU.enve_mag_margin = pU.enves[pU.enve_index].mag - pU.enve_mag_start;
173 				if (pU.enves[pU.enve_index].smp) {
174 					break;
175 				}
176 				pU.enve_mag_start = pU.enves[pU.enve_index].mag;
177 				pU.enve_index++;
178 			}
179 
180 			_set_ocsillator(&pU.main, &p_du.main, sps, _p_tables[p_du.main.type], _p_tables[pxWAVETYPE.Random]);
181 			_set_ocsillator(&pU.freq, &p_du.freq, sps, _p_tables[p_du.freq.type], _p_tables[pxWAVETYPE.Random]);
182 			_set_ocsillator(&pU.volu, &p_du.volu, sps, _p_tables[p_du.volu.type], _p_tables[pxWAVETYPE.Random]);
183 		}
184 
185 		smp_num = cast(int)(cast(double) p_noise.get_smp_num_44k() / (44100.0 / sps));
186 
187 		p_pcm = pxtnPulse_PCM.init;
188 		p_pcm.Create(ch, sps, bps, smp_num);
189 		p = p_pcm.get_p_buf().ptr;
190 
191 		for (int s = 0; s < smp_num; s++) {
192 			for (int c = 0; c < ch; c++) {
193 				store = 0;
194 				for (int u = 0; u < unit_num; u++) {
195 					_UNIT* pU = &units[u];
196 
197 					if (pU.bEnable) {
198 						_OSCILLATOR* po;
199 
200 						// main
201 						po = &pU.main;
202 						switch (po.ran_type) {
203 						case _RANDOMTYPE.None:
204 							offset = cast(int) po.offset;
205 							if (offset >= 0) {
206 								work = po.p_smp[offset];
207 							} else {
208 								work = 0;
209 							}
210 							break;
211 						case _RANDOMTYPE.Saw:
212 							if (po.offset >= 0) {
213 								work = po.rdm_start + po.rdm_margin * cast(int) po.offset / _smp_num;
214 							} else {
215 								work = 0;
216 							}
217 							break;
218 						case _RANDOMTYPE.Rect:
219 							if (po.offset >= 0) {
220 								work = po.rdm_start;
221 							} else {
222 								work = 0;
223 							}
224 							break;
225 						default:
226 							break;
227 						}
228 						if (po.bReverse) {
229 							work *= -1;
230 						}
231 						work *= po.volume;
232 
233 						// volu
234 						po = &pU.volu;
235 						switch (po.ran_type) {
236 						case _RANDOMTYPE.None:
237 							offset = cast(int) po.offset;
238 							vol = cast(double) po.p_smp[offset];
239 							break;
240 						case _RANDOMTYPE.Saw:
241 							vol = po.rdm_start + po.rdm_margin * cast(int) po.offset / _smp_num;
242 							break;
243 						case _RANDOMTYPE.Rect:
244 							vol = po.rdm_start;
245 							break;
246 						default:
247 							break;
248 						}
249 						if (po.bReverse) {
250 							vol *= -1;
251 						}
252 						vol *= po.volume;
253 
254 						work = work * (vol + _SAMPLING_TOP) / (_SAMPLING_TOP * 2);
255 						work = work * pU.pan[c];
256 
257 						// envelope
258 						if (pU.enve_index < pU.enve_num) {
259 							work *= pU.enve_mag_start + (pU.enve_mag_margin * pU.enve_count / pU.enves[pU.enve_index].smp);
260 						} else {
261 							work *= pU.enve_mag_start;
262 						}
263 						store += work;
264 					}
265 				}
266 
267 				byte4 = cast(int) store;
268 				if (byte4 > _SAMPLING_TOP) {
269 					byte4 = _SAMPLING_TOP;
270 				}
271 				if (byte4 < -_SAMPLING_TOP) {
272 					byte4 = -_SAMPLING_TOP;
273 				}
274 				if (bps == 8) {
275 					*p = cast(ubyte)((byte4 >> 8) + 128);
276 					p += 1;
277 				}  //  8bit
278 				else {
279 					*(cast(short*) p) = cast(short) byte4;
280 					p += 2;
281 				} // 16bit
282 			}
283 
284 			// incriment
285 			for (int u = 0; u < unit_num; u++) {
286 				_UNIT* pU = &units[u];
287 
288 				if (pU.bEnable) {
289 					_OSCILLATOR* po = &pU.freq;
290 
291 					switch (po.ran_type) {
292 					case _RANDOMTYPE.None:
293 						offset = cast(int) po.offset;
294 						fre = _KEY_TOP * po.p_smp[offset] / _SAMPLING_TOP;
295 						break;
296 					case _RANDOMTYPE.Saw:
297 						fre = po.rdm_start + po.rdm_margin * cast(int) po.offset / _smp_num;
298 						break;
299 					case _RANDOMTYPE.Rect:
300 						fre = po.rdm_start;
301 						break;
302 					default:
303 						break;
304 					}
305 
306 					if (po.bReverse) {
307 						fre *= -1;
308 					}
309 					fre *= po.volume;
310 
311 					_incriment(&pU.main, pU.main.incriment * _freq.Get(cast(int) fre), _p_tables[pxWAVETYPE.Random]);
312 					_incriment(&pU.freq, pU.freq.incriment, _p_tables[pxWAVETYPE.Random]);
313 					_incriment(&pU.volu, pU.volu.incriment, _p_tables[pxWAVETYPE.Random]);
314 
315 					// envelope
316 					if (pU.enve_index < pU.enve_num) {
317 						pU.enve_count++;
318 						if (pU.enve_count >= pU.enves[pU.enve_index].smp) {
319 							pU.enve_count = 0;
320 							pU.enve_mag_start = pU.enves[pU.enve_index].mag;
321 							pU.enve_mag_margin = 0;
322 							pU.enve_index++;
323 							while (pU.enve_index < pU.enve_num) {
324 								pU.enve_mag_margin = pU.enves[pU.enve_index].mag - pU.enve_mag_start;
325 								if (pU.enves[pU.enve_index].smp) {
326 									break;
327 								}
328 								pU.enve_mag_start = pU.enves[pU.enve_index].mag;
329 								pU.enve_index++;
330 							}
331 						}
332 					}
333 				}
334 			}
335 		}
336 
337 		return p_pcm;
338 	}
339 }
340 
341 short[][pxWAVETYPE.num] genTables() {
342 	pxtnPOINT[1] overtones_sine = [{1, 128}];
343 	pxtnPOINT[16] overtones_saw2 = [{1, 128}, {2, 128}, {3, 128}, {4, 128}, {5, 128}, {6, 128}, {7, 128}, {8, 128}, {9, 128}, {10, 128}, {11, 128}, {12, 128}, {13, 128}, {14, 128}, {15, 128}, {16, 128},];
344 	pxtnPOINT[8] overtones_rect2 = [{1, 128}, {3, 128}, {5, 128}, {7, 128}, {9, 128}, {11, 128}, {13, 128}, {15, 128},];
345 
346 	pxtnPOINT[4] coodi_tri = [{0, 0}, {_smp_num / 4, 128}, {_smp_num * 3 / 4, -128}, {_smp_num, 0}];
347 	int s;
348 	short[] p;
349 	double work;
350 
351 	int a;
352 	short v;
353 	pxtnPulse_Oscillator osci;
354 	int[2] _rand_buf;
355 
356 	void _random_reset() nothrow @safe {
357 		_rand_buf[0] = 0x4444;
358 		_rand_buf[1] = 0x8888;
359 	}
360 
361 	short _random_get() nothrow @system {
362 		ubyte[2] w1, w2;
363 
364         short tmp = cast(short)(_rand_buf[0] + _rand_buf[1]);
365 		w2[1] = (tmp & 0xFF);
366 		w2[0] = (tmp & 0xFF00) >> 8;
367 		_rand_buf[1] = cast(short) _rand_buf[0];
368 		_rand_buf[0] = cast(short) (w2[0] + (w2[1] << 8));
369 
370 		return cast(short) (w2[0] + (w2[1] << 8));
371 	}
372 
373 	short[][pxWAVETYPE.num] _p_tables;
374 	_p_tables[pxWAVETYPE.None] = new short[_smp_num];
375 	_p_tables[pxWAVETYPE.Sine] = new short[_smp_num];
376 	_p_tables[pxWAVETYPE.Saw] = new short[_smp_num];
377 	_p_tables[pxWAVETYPE.Rect] = new short[_smp_num];
378 	_p_tables[pxWAVETYPE.Random] = new short[_smp_num_rand];
379 	_p_tables[pxWAVETYPE.Saw2] = new short[_smp_num];
380 	_p_tables[pxWAVETYPE.Rect2] = new short[_smp_num];
381 	_p_tables[pxWAVETYPE.Tri] = new short[_smp_num];
382 	//_p_tables[pxWAVETYPE.Random2] = new short[_smp_num_rand];
383 	_p_tables[pxWAVETYPE.Rect3] = new short[_smp_num];
384 	_p_tables[pxWAVETYPE.Rect4] = new short[_smp_num];
385 	_p_tables[pxWAVETYPE.Rect8] = new short[_smp_num];
386 	_p_tables[pxWAVETYPE.Rect16] = new short[_smp_num];
387 	_p_tables[pxWAVETYPE.Saw3] = new short[_smp_num];
388 	_p_tables[pxWAVETYPE.Saw4] = new short[_smp_num];
389 	_p_tables[pxWAVETYPE.Saw6] = new short[_smp_num];
390 	_p_tables[pxWAVETYPE.Saw8] = new short[_smp_num];
391 
392 	// none --
393 
394 	// sine --
395 	osci.ReadyGetSample(overtones_sine[], 1, 128, _smp_num, 0);
396 	p = _p_tables[pxWAVETYPE.Sine];
397 	for (s = 0; s < _smp_num; s++) {
398 		work = osci.GetOneSample_Overtone(s);
399 		if (work > 1.0) {
400 			work = 1.0;
401 		}
402 		if (work < -1.0) {
403 			work = -1.0;
404 		}
405 		p[0] = cast(short)(work * _SAMPLING_TOP);
406 		p = p[1 .. $];
407 	}
408 
409 	// saw down --
410 	p = _p_tables[pxWAVETYPE.Saw];
411 	work = _SAMPLING_TOP + _SAMPLING_TOP;
412 	for (s = 0; s < _smp_num; s++) {
413 		p[0] = cast(short)(_SAMPLING_TOP - work * s / _smp_num);
414 		p = p[1 .. $];
415 	}
416 
417 	// rect --
418 	p = _p_tables[pxWAVETYPE.Rect];
419 	for (s = 0; s < _smp_num / 2; s++) {
420 		p[0] = cast(short)(_SAMPLING_TOP);
421 		p = p[1 ..$];
422 	}
423 	for ( /+s+/ ; s < _smp_num; s++) {
424 		p[0] = cast(short)(-_SAMPLING_TOP);
425 		p = p[1 .. $];
426 	}
427 
428 	// random --
429 	p = _p_tables[pxWAVETYPE.Random];
430 	_random_reset();
431 	for (s = 0; s < _smp_num_rand; s++) {
432 		p[0] = _random_get();
433 		p = p[1 .. $];
434 	}
435 
436 	// saw2 --
437 	osci.ReadyGetSample(overtones_saw2[], 16, 128, _smp_num, 0);
438 	p = _p_tables[pxWAVETYPE.Saw2];
439 	for (s = 0; s < _smp_num; s++) {
440 		work = osci.GetOneSample_Overtone(s);
441 		if (work > 1.0) {
442 			work = 1.0;
443 		}
444 		if (work < -1.0) {
445 			work = -1.0;
446 		}
447 		p[0] = cast(short)(work * _SAMPLING_TOP);
448 		p = p[1 .. $];
449 	}
450 
451 	// rect2 --
452 	osci.ReadyGetSample(overtones_rect2[], 8, 128, _smp_num, 0);
453 	p = _p_tables[pxWAVETYPE.Rect2];
454 	for (s = 0; s < _smp_num; s++) {
455 		work = osci.GetOneSample_Overtone(s);
456 		if (work > 1.0) {
457 			work = 1.0;
458 		}
459 		if (work < -1.0) {
460 			work = -1.0;
461 		}
462 		p[0] = cast(short)(work * _SAMPLING_TOP);
463 		p = p[1 .. $];
464 	}
465 
466 	// Triangle --
467 	osci.ReadyGetSample(coodi_tri[], 4, 128, _smp_num, _smp_num);
468 	p = _p_tables[pxWAVETYPE.Tri];
469 	for (s = 0; s < _smp_num; s++) {
470 		work = osci.GetOneSample_Coodinate(s);
471 		if (work > 1.0) {
472 			work = 1.0;
473 		}
474 		if (work < -1.0) {
475 			work = -1.0;
476 		}
477 		p[0] = cast(short)(work * _SAMPLING_TOP);
478 		p = p[1 .. $];
479 	}
480 
481 	// Random2  -- x
482 
483 	// Rect-3  --
484 	p = _p_tables[pxWAVETYPE.Rect3];
485 	for (s = 0; s < _smp_num / 3; s++) {
486 		p[0] = cast(short)(_SAMPLING_TOP);
487 		p = p[1 .. $];
488 	}
489 	for ( /+s+/ ; s < _smp_num; s++) {
490 		p[0] = cast(short)(-_SAMPLING_TOP);
491 		p = p[1 .. $];
492 	}
493 	// Rect-4   --
494 	p = _p_tables[pxWAVETYPE.Rect4];
495 	for (s = 0; s < _smp_num / 4; s++) {
496 		p[0] = cast(short)(_SAMPLING_TOP);
497 		p = p[1 .. $];
498 	}
499 	for ( /+s+/ ; s < _smp_num; s++) {
500 		p[0] = cast(short)(-_SAMPLING_TOP);
501 		p = p[1 .. $];
502 	}
503 	// Rect-8   --
504 	p = _p_tables[pxWAVETYPE.Rect8];
505 	for (s = 0; s < _smp_num / 8; s++) {
506 		p[0] = cast(short)(_SAMPLING_TOP);
507 		p = p[1 .. $];
508 	}
509 	for ( /+s+/ ; s < _smp_num; s++) {
510 		p[0] = cast(short)(-_SAMPLING_TOP);
511 		p = p[1 .. $];
512 	}
513 	// Rect-16  --
514 	p = _p_tables[pxWAVETYPE.Rect16];
515 	for (s = 0; s < _smp_num / 16; s++) {
516 		p[0] = cast(short)(_SAMPLING_TOP);
517 		p = p[1 .. $];
518 	}
519 	for ( /+s+/ ; s < _smp_num; s++) {
520 		p[0] = cast(short)(-_SAMPLING_TOP);
521 		p = p[1 .. $];
522 	}
523 
524 	// Saw-3    --
525 	p = _p_tables[pxWAVETYPE.Saw3];
526 	for (s = 0; s < _smp_num / 3; s++) {
527 		p[0] = cast(short)(_SAMPLING_TOP);
528 		p = p[1 .. $];
529 	}
530 	for ( /+s+/ ; s < _smp_num * 2 / 3; s++) {
531 		p[0] = cast(short)(0);
532 		p = p[1 .. $];
533 	}
534 	for ( /+s+/ ; s < _smp_num; s++) {
535 		p[0] = cast(short)(-_SAMPLING_TOP);
536 		p = p[1 .. $];
537 	}
538 
539 	// Saw-4    --
540 	p = _p_tables[pxWAVETYPE.Saw4];
541 	for (s = 0; s < _smp_num / 4; s++) {
542 		p[0] = cast(short)(_SAMPLING_TOP);
543 		p = p[1 .. $];
544 	}
545 	for ( /+s+/ ; s < _smp_num * 2 / 4; s++) {
546 		p[0] = cast(short)(_SAMPLING_TOP / 3);
547 		p = p[1 .. $];
548 	}
549 	for ( /+s+/ ; s < _smp_num * 3 / 4; s++) {
550 		p[0] = cast(short)(-_SAMPLING_TOP / 3);
551 		p = p[1 .. $];
552 	}
553 	for ( /+s+/ ; s < _smp_num; s++) {
554 		p[0] = cast(short)(-_SAMPLING_TOP);
555 		p = p[1 .. $];
556 	}
557 
558 	// Saw-6    --
559 	p = _p_tables[pxWAVETYPE.Saw6];
560 	a = _smp_num * 1 / 6;
561 	v = _SAMPLING_TOP;
562 	for (s = 0; s < a; s++) {
563 		p[0] = v;
564 		p = p[1 .. $];
565 	}
566 	a = _smp_num * 2 / 6;
567 	v = _SAMPLING_TOP - _SAMPLING_TOP * 2 / 5;
568 	for ( /+s+/ ; s < a; s++) {
569 		p[0] = v;
570 		p = p[1 .. $];
571 	}
572 	a = _smp_num * 3 / 6;
573 	v = _SAMPLING_TOP / 5;
574 	for ( /+s+/ ; s < a; s++) {
575 		p[0] = v;
576 		p = p[1 .. $];
577 	}
578 	a = _smp_num * 4 / 6;
579 	v = -_SAMPLING_TOP / 5;
580 	for ( /+s+/ ; s < a; s++) {
581 		p[0] = v;
582 		p = p[1 .. $];
583 	}
584 	a = _smp_num * 5 / 6;
585 	v = -_SAMPLING_TOP + _SAMPLING_TOP * 2 / 5;
586 	for ( /+s+/ ; s < a; s++) {
587 		p[0] = v;
588 		p = p[1 .. $];
589 	}
590 	a = _smp_num;
591 	v = -_SAMPLING_TOP;
592 	for ( /+s+/ ; s < a; s++) {
593 		p[0] = v;
594 		p = p[1 .. $];
595 	}
596 
597 	// Saw-8    --
598 	p = _p_tables[pxWAVETYPE.Saw8];
599 	a = _smp_num * 1 / 8;
600 	v = _SAMPLING_TOP;
601 	for (s = 0; s < a; s++) {
602 		p[0] = v;
603 		p = p[1 .. $];
604 	}
605 	a = _smp_num * 2 / 8;
606 	v = _SAMPLING_TOP - _SAMPLING_TOP * 2 / 7;
607 	for ( /+s+/ ; s < a; s++) {
608 		p[0] = v;
609 		p = p[1 .. $];
610 	}
611 	a = _smp_num * 3 / 8;
612 	v = _SAMPLING_TOP - _SAMPLING_TOP * 4 / 7;
613 	for ( /+s+/ ; s < a; s++) {
614 		p[0] = v;
615 		p = p[1 .. $];
616 	}
617 	a = _smp_num * 4 / 8;
618 	v = _SAMPLING_TOP / 7;
619 	for ( /+s+/ ; s < a; s++) {
620 		p[0] = v;
621 		p = p[1 .. $];
622 	}
623 	a = _smp_num * 5 / 8;
624 	v = -_SAMPLING_TOP / 7;
625 	for ( /+s+/ ; s < a; s++) {
626 		p[0] = v;
627 		p = p[1 .. $];
628 	}
629 	a = _smp_num * 6 / 8;
630 	v = -_SAMPLING_TOP + _SAMPLING_TOP * 4 / 7;
631 	for ( /+s+/ ; s < a; s++) {
632 		p[0] = v;
633 		p = p[1 .. $];
634 	}
635 	a = _smp_num * 7 / 8;
636 	v = -_SAMPLING_TOP + _SAMPLING_TOP * 2 / 7;
637 	for ( /+s+/ ; s < a; s++) {
638 		p[0] = v;
639 		p = p[1 .. $];
640 	}
641 	a = _smp_num;
642 	v = -_SAMPLING_TOP;
643 	for ( /+s+/ ; s < a; s++) {
644 		p[0] = v;
645 		p = p[1 .. $];
646 	}
647 	return _p_tables;
648 }