git ssb

0+

kode54 / syntrax-c



Commit cd661690274becf438f26f617e6ec47efdbc3b80

Implemented sinc interpolation.

Christopher Snowhill authored on 1/2/2016, 7:39:06 AM
Christopher Snowhill committed on 6/13/2018, 12:10:58 AM
Parent: a598e4485ed3fd07d57f9290824ce35590edec73

Files changed

src/syntrax/syntrax.cchanged
src/syntrax/syntrax.hchanged
src/syntrax/resampler.cadded
src/syntrax/resampler.hadded
src/syntrax/syntrax.cView
@@ -1,10 +1,14 @@
11 #include <stdint.h>
22 #include <stdlib.h>
3+#include <string.h>
4+#define _USE_MATH_DEFINES
35 #include <math.h>
6+#include <time.h>
47
58 #include "syntrax.h"
69 #include "file.h"
10+#include "resampler.h"
711
812 static void reset(Player *p)
913 {
1014 int i, j;
@@ -96,17 +100,26 @@
96100 }
97101
98102 void playerDestroy(Player *p)
99103 {
104+ int i;
105+
100106 if (p) {
101107 if (p->dynamorphTable) free(p->dynamorphTable);
102108 if (p->freqTable) free(p->freqTable);
103109 if (p->silentBuffer) free(p->silentBuffer);
104110 if (p->overlapBuff) free(p->overlapBuff);
105111 if (p->delayBufferL) free(p->delayBufferL);
106112 if (p->delayBufferR) free(p->delayBufferR);
107113 if (p->tuneChannels) free(p->tuneChannels);
108- if (p->voices) free(p->voices);
114+ if (p->voices) {
115+ for (i = 0; i < SE_MAXCHANS; i++)
116+ {
117+ resampler_destroy(p->voices[i].resampler[0]);
118+ resampler_destroy(p->voices[i].resampler[1]);
119+ }
120+ free(p->voices);
121+ }
109122
110123 if (p->instruments) free(p->instruments);
111124
112125 free(p);
@@ -164,8 +177,15 @@
164177 if (!p->tuneChannels) goto FAIL;
165178 p->voices = malloc(SE_MAXCHANS *sizeof(Voice));
166179 if (!p->voices) goto FAIL;
167180
181+ for (i = 0; i < SE_MAXCHANS; i++)
182+ {
183+ p->voices[i].resampler[0] = resampler_create();
184+ p->voices[i].resampler[1] = resampler_create();
185+ if (!p->voices[i].resampler[0] || !p->voices[i].resampler[1]) goto FAIL;
186+ }
187+
168188 reset(p);
169189
170190 return p;
171191
@@ -930,11 +950,11 @@
930950 tc->sampleBuffer = p->samples[instrNum - 1];
931951 } else {
932952 tc->sampleBuffer = p->samples[ins->shareSmpDataFromInstr - 1];
933953 }
934- tc->sampPos = ins->smpStartPoint << 8;
935- tc->smpLoopStart = ins->smpLoopPoint << 8;
936- tc->smpLoopEnd = ins->smpEndPoint << 8;
954+ tc->sampPos = ins->smpStartPoint;
955+ tc->smpLoopStart = ins->smpLoopPoint;
956+ tc->smpLoopEnd = ins->smpEndPoint;
937957 tc->hasLoop = ins->hasLoop;
938958 tc->hasBidiLoop = ins->hasBidiLoop;
939959 tc->hasLooped = 0;
940960 tc->isPlayingBackward = 0;
@@ -947,8 +967,11 @@
947967 memcpy(&tc->synthBuffers[i], &ins->synthBuffers[i], 0x100 *2);
948968 }
949969 }
950970 tc->insNum = instrNum - 1;
971+
972+ resampler_clear(v->resampler[0]);
973+ v->last_delta = 0;
951974 }
952975 ins = &p->instruments[tc->insNum];
953976
954977 for (j = 0; j < 4; j++) {
@@ -1747,9 +1770,9 @@
17471770 }
17481771 else if ( !tc->sampleBuffer )
17491772 {
17501773 int waveNum = p->instruments[insNum].waveform;
1751- v->wavelength = (p->instruments[insNum].wavelength << 8) - 1;
1774+ v->wavelength = (p->instruments[insNum].wavelength) - 1;
17521775 v->waveBuff = tc->synthBuffers[waveNum];
17531776 v->isSample = 0;
17541777 }
17551778 else
@@ -1769,8 +1792,14 @@
17691792 tc->freq = 10;
17701793
17711794 v->gain = (tc->volume + 10000) / 39;
17721795 v->delta = (tc->freq << 8) / p->SAMPLEFREQUENCY;
1796+ if (v->delta != v->last_delta)
1797+ {
1798+ double fdelta = (double)v->delta * (1.0 / (double)0x100);
1799+ v->last_delta = v->delta;
1800+ resampler_set_rate(v->resampler[0], fdelta);
1801+ }
17731802
17741803 if ( v->gain > 0x100 )
17751804 v->gain = 0x100;
17761805 if ( tc->panning )
@@ -1830,65 +1859,80 @@
18301859 {
18311860 v = &p->voices[j];
18321861 if ( v->isSample == 1 )
18331862 {
1834- if ( v->sampPos != -1 )
1863+ if ( v->sampPos != -1 || resampler_get_avail(v->resampler[0]) )
18351864 {
18361865 //interpolation
1837- //smp = intp->interpSamp(v);
1838- smp = v->waveBuff[v->sampPos>>8];
1839-
1840- audioMainR += (smp * v->gainRight) >> 8;
1841- audioMainL += (smp * v->gainLeft) >> 8;
1842- audioDelayR += (smp * v->gainDelayRight) >> 8;
1843- audioDelayL += (smp * v->gainDelayLeft) >> 8;
1844- if ( v->isPlayingBackward )
1866+ sample_t s;
1867+ while ( v->sampPos != -1 && resampler_get_min_fill(v->resampler[0]) )
18451868 {
1846- v->sampPos -= v->delta;
1847- if ( v->sampPos <= v->smpLoopStart )
1869+ s = v->waveBuff[v->sampPos];
1870+ resampler_write_pair(v->resampler[0], s, s);
1871+ if ( v->isPlayingBackward )
18481872 {
1849- v->isPlayingBackward = 0;
1850- v->sampPos += v->delta;
1873+ v->sampPos--;
1874+ if ( v->sampPos <= v->smpLoopStart )
1875+ {
1876+ v->isPlayingBackward = 0;
1877+ v->sampPos++;
1878+ }
18511879 }
1852- }
1853- else
1854- {
1855- v->sampPos += v->delta;
1856- if ( v->sampPos >= v->smpLoopEnd )
1880+ else
18571881 {
1858- if ( v->hasLoop )
1882+ v->sampPos++;
1883+ if ( v->sampPos >= v->smpLoopEnd )
18591884 {
1860- v->hasLooped = 1;
1861- if ( v->hasBidiLoop )
1885+ if ( v->hasLoop )
18621886 {
1863- v->isPlayingBackward = 1;
1864- v->sampPos -= v->delta;
1887+ v->hasLooped = 1;
1888+ if ( v->hasBidiLoop )
1889+ {
1890+ v->isPlayingBackward = 1;
1891+ v->sampPos--;
1892+ }
1893+ else
1894+ {
1895+ v->sampPos += v->smpLoopStart - v->smpLoopEnd;
1896+ }
18651897 }
18661898 else
18671899 {
1868- v->sampPos += v->smpLoopStart - v->smpLoopEnd;
1900+ v->sampPos = -1;
18691901 }
18701902 }
1871- else
1872- {
1873- v->sampPos = -1;
1874- }
18751903 }
18761904 }
1905+
1906+ //smp = intp->interpSamp(v);
1907+ resampler_read_pair(v->resampler[0], &s, &s);
1908+ smp = s;
1909+
1910+ audioMainR += (smp * v->gainRight) >> 8;
1911+ audioMainL += (smp * v->gainLeft) >> 8;
1912+ audioDelayR += (smp * v->gainDelayRight) >> 8;
1913+ audioDelayL += (smp * v->gainDelayLeft) >> 8;
18771914 }
18781915 }
18791916 else
18801917 {
18811918 //interpolation
18821919 //smp = intp->interpSynt(v);
1883- smp = v->waveBuff[v->synthPos>>8];
1920+ sample_t s;
1921+ while ( resampler_get_min_fill(v->resampler[0]) )
1922+ {
1923+ s = v->waveBuff[v->synthPos];
1924+ resampler_write_pair(v->resampler[0], s, s);
1925+ v->synthPos++;
1926+ v->synthPos &= v->wavelength;
1927+ }
1928+ resampler_read_pair(v->resampler[0], &s, &s);
1929+ smp = s;
18841930
18851931 audioMainR += (smp * v->gainRight) >> 8;
18861932 audioMainL += (smp * v->gainLeft) >> 8;
18871933 audioDelayR += (smp * v->gainDelayRight) >> 8;
18881934 audioDelayL += (smp * v->gainDelayLeft) >> 8;
1889- v->synthPos += v->delta;
1890- v->synthPos &= v->wavelength;
18911935 }
18921936 }
18931937 }
18941938
@@ -1938,9 +1982,13 @@
19381982 }
19391983 if ( p->otherSamplesPerBeat == (p->samplesPerBeat * p->SAMPLEFREQUENCY) / 44100 )
19401984 {
19411985 p->bkpDelayPos = p->delayPos;
1942- for (i = 0; i < p->channelNumber; i++) p->voices[i].bkpSynthPos = p->voices[i].synthPos;
1986+ for (i = 0; i < p->channelNumber; i++)
1987+ {
1988+ p->voices[i].bkpSynthPos = p->voices[i].synthPos;
1989+ resampler_dup_inplace(p->voices[i].resampler[1], p->voices[i].resampler[0]);
1990+ }
19431991
19441992 p->overlapPos = 0;
19451993 if ( outBuff )
19461994 {
@@ -1956,65 +2004,79 @@
19562004 {
19572005 v = &p->voices[j];
19582006 if ( v->isSample == 1 )
19592007 {
1960- if ( v->sampPos != -1 )
2008+ if ( v->sampPos != -1 || resampler_get_avail(v->resampler[1]) )
19612009 {
19622010 //interpolation
19632011 //smp = intp->interpSamp(v);
1964- smp = v->waveBuff[v->sampPos>>8];
1965-
1966- audioMainR += (smp * v->gainRight) >> 8;
1967- audioMainL += (smp * v->gainLeft) >> 8;
1968- audioDelayR += (smp * v->gainDelayRight) >> 8;
1969- audioDelayL += (smp * v->gainDelayLeft) >> 8;
1970- if ( v->isPlayingBackward )
2012+ sample_t s;
2013+ while ( v->sampPos != -1 && resampler_get_min_fill(v->resampler[1]) )
19712014 {
1972- v->sampPos -= v->delta;
1973- if ( v->sampPos <= v->smpLoopStart )
2015+ s = v->waveBuff[v->sampPos];
2016+ resampler_write_pair(v->resampler[1], s, s);
2017+ if ( v->isPlayingBackward )
19742018 {
1975- v->isPlayingBackward = 0;
1976- v->sampPos += v->delta;
2019+ v->sampPos--;
2020+ if ( v->sampPos <= v->smpLoopStart )
2021+ {
2022+ v->isPlayingBackward = 0;
2023+ v->sampPos++;
2024+ }
19772025 }
1978- }
1979- else
1980- {
1981- v->sampPos += v->delta;
1982- if ( v->sampPos >= v->smpLoopEnd )
2026+ else
19832027 {
1984- if ( v->hasLoop )
2028+ v->sampPos++;
2029+ if ( v->sampPos >= v->smpLoopEnd )
19852030 {
1986- v->hasLooped = 1;
1987- if ( v->hasBidiLoop )
2031+ if ( v->hasLoop )
19882032 {
1989- v->isPlayingBackward = 1;
1990- v->sampPos -= v->delta;
2033+ v->hasLooped = 1;
2034+ if ( v->hasBidiLoop )
2035+ {
2036+ v->isPlayingBackward = 1;
2037+ v->sampPos--;
2038+ }
2039+ else
2040+ {
2041+ v->sampPos += v->smpLoopStart - v->smpLoopEnd;
2042+ }
19912043 }
19922044 else
19932045 {
1994- v->sampPos += v->smpLoopStart - v->smpLoopEnd;
2046+ v->sampPos = -1;
19952047 }
19962048 }
1997- else
1998- {
1999- v->sampPos = -1;
2000- }
20012049 }
20022050 }
2051+ resampler_read_pair(v->resampler[1], &s, &s);
2052+ smp = s;
2053+
2054+ audioMainR += (smp * v->gainRight) >> 8;
2055+ audioMainL += (smp * v->gainLeft) >> 8;
2056+ audioDelayR += (smp * v->gainDelayRight) >> 8;
2057+ audioDelayL += (smp * v->gainDelayLeft) >> 8;
20032058 }
20042059 }
20052060 else
20062061 {
20072062 //interpolation
20082063 //smp = intp->interpSynt(v);
2009- smp = v->waveBuff[v->synthPos>>8];
2064+ sample_t s;
2065+ while ( resampler_get_min_fill(v->resampler[1]) )
2066+ {
2067+ s = v->waveBuff[v->synthPos];
2068+ resampler_write_pair(v->resampler[1], s, s);
2069+ v->synthPos++;
2070+ v->synthPos &= v->wavelength;
2071+ }
2072+ resampler_read_pair(v->resampler[1], &s, &s);
2073+ smp = s;
20102074
20112075 audioMainR += (smp * v->gainRight) >> 8;
20122076 audioMainL += (smp * v->gainLeft) >> 8;
20132077 audioDelayR += (smp * v->gainDelayRight) >> 8;
20142078 audioDelayL += (smp * v->gainDelayLeft) >> 8;
2015- v->synthPos += v->delta;
2016- v->synthPos &= v->wavelength;
20172079 }
20182080 }
20192081 }
20202082
src/syntrax/syntrax.hView
@@ -1,10 +1,8 @@
11 #ifndef SYNTRAX_H
22 #define SYNTRAX_H
33
44 #include <stdint.h>
5-#include <string.h>
6-#include <sys/time.h>
75
86 //----------------------------typedefs-------------------------
97 #ifndef NULL
108 #define NULL 0
@@ -58,8 +56,10 @@
5856 int smpLength;
5957 int gainDelayRight;
6058 int gainDelayLeft;
6159 int hasLooped;
60+ void * resampler[2];
61+ int last_delta;
6262 } Voice;
6363
6464 typedef struct
6565 {
src/syntrax/resampler.cView
@@ -1,0 +1,361 @@
1+#include "resampler.h"
2+
3+#include <math.h>
4+#include <stdlib.h>
5+#include <string.h>
6+
7+/* Copyright (C) 2004-2008 Shay Green.
8+ Copyright (C) 2015 Christopher Snowhill. This module is free software; you
9+can redistribute it and/or modify it under the terms of the GNU Lesser
10+General Public License as published by the Free Software Foundation; either
11+version 2.1 of the License, or (at your option) any later version. This
12+module is distributed in the hope that it will be useful, but WITHOUT ANY
13+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15+details. You should have received a copy of the GNU Lesser General Public
16+License along with this module; if not, write to the Free Software Foundation,
17+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18+
19+#undef PI
20+#define PI 3.1415926535897932384626433832795029
21+
22+enum { imp_scale = 0x7FFF };
23+typedef int16_t imp_t;
24+typedef int32_t imp_off_t; /* for max_res of 512 and impulse width of 32, end offsets must be 32 bits */
25+
26+#if RESAMPLER_BITS == 16
27+typedef int32_t intermediate_t;
28+#elif RESAMPLER_BITS == 32
29+typedef int64_t intermediate_t;
30+#endif
31+
32+static void gen_sinc( double rolloff, int width, double offset, double spacing, double scale,
33+ int count, imp_t* out )
34+{
35+ double const maxh = 256;
36+ double const step = PI / maxh * spacing;
37+ double const to_w = maxh * 2 / width;
38+ double const pow_a_n = pow( rolloff, maxh );
39+ scale /= maxh * 2;
40+ double angle = (count / 2 - 1 + offset) * -step;
41+
42+ while ( count-- )
43+ {
44+ *out++ = 0;
45+ double w = angle * to_w;
46+ if ( fabs( w ) < PI )
47+ {
48+ double rolloff_cos_a = rolloff * cos( angle );
49+ double num = 1 - rolloff_cos_a -
50+ pow_a_n * cos( maxh * angle ) +
51+ pow_a_n * rolloff * cos( (maxh - 1) * angle );
52+ double den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
53+ double sinc = scale * num / den - scale;
54+
55+ out [-1] = (imp_t) (cos( w ) * sinc + sinc);
56+ }
57+ angle += step;
58+ }
59+}
60+
61+enum { width = 32 };
62+enum { stereo = 2 };
63+enum { max_res = 512 };
64+enum { min_width = (width < 4 ? 4 : width) };
65+enum { adj_width = min_width / 4 * 4 + 2 };
66+enum { write_offset = adj_width * stereo };
67+
68+enum { buffer_size = 128 };
69+
70+typedef struct _resampler
71+{
72+ int width_;
73+ int rate_;
74+ int inptr;
75+ int infilled;
76+ int outptr;
77+ int outfilled;
78+
79+ int latency;
80+
81+ imp_t const* imp;
82+ imp_t impulses [max_res * (adj_width + 2 * (sizeof(imp_off_t) / sizeof(imp_t)))];
83+ sample_t buffer_in[buffer_size * stereo * 2];
84+ sample_t buffer_out[buffer_size * stereo];
85+} resampler;
86+
87+void * resampler_create()
88+{
89+ resampler *r = (resampler *) malloc(sizeof(resampler));
90+ if (r) resampler_clear(r);
91+ return r;
92+}
93+
94+void * resampler_dup(const void *_r)
95+{
96+ void *_t = (resampler *) malloc(sizeof(resampler));
97+ if (_t) resampler_dup_inplace(_t, _r);
98+ return _t;
99+}
100+
101+void resampler_dup_inplace(void *_t, const void *_r)
102+{
103+ const resampler *r = (const resampler *)_r;
104+ resampler *t = (resampler *)_t;
105+ if (r && t)
106+ {
107+ memcpy(t, r, sizeof(resampler));
108+ t->imp = t->impulses + (r->imp - r->impulses);
109+ }
110+ else if (t)
111+ {
112+ resampler_clear(t);
113+ }
114+}
115+
116+void resampler_destroy(void *r)
117+{
118+ free(r);
119+}
120+
121+void resampler_clear(void *_r)
122+{
123+ resampler * r = (resampler *)_r;
124+ r->width_ = adj_width;
125+ r->inptr = 0;
126+ r->infilled = 0;
127+ r->outptr = 0;
128+ r->outfilled = 0;
129+ r->latency = 0;
130+ r->imp = r->impulses;
131+
132+ resampler_set_rate(r, 1.0);
133+}
134+
135+void resampler_set_rate( void *_r, double new_factor )
136+{
137+ resampler *rs = (resampler *)_r;
138+
139+ double const rolloff = 0.999;
140+ double const gain = 1.0;
141+
142+ /* determine number of sub-phases that yield lowest error */
143+ double ratio_ = 0.0;
144+ int res = -1;
145+ {
146+ double least_error = 2;
147+ double pos = 0;
148+ for ( int r = 1; r <= max_res; r++ )
149+ {
150+ pos += new_factor;
151+ double nearest = floor( pos + 0.5 );
152+ double error = fabs( pos - nearest );
153+ if ( error < least_error )
154+ {
155+ res = r;
156+ ratio_ = nearest / res;
157+ least_error = error;
158+ }
159+ }
160+ }
161+ rs->rate_ = ratio_;
162+
163+ /* how much of input is used for each output sample */
164+ int const step = stereo * (int) floor( ratio_ );
165+ double fraction = fmod( ratio_, 1.0 );
166+
167+ double const filter = (ratio_ < 1.0) ? 1.0 : 1.0 / ratio_;
168+ double pos = 0.0;
169+ /*int input_per_cycle = 0;*/
170+ imp_t* out = rs->impulses;
171+ for ( int n = res; --n >= 0; )
172+ {
173+ gen_sinc( rolloff, (int) (rs->width_ * filter + 1) & ~1, pos, filter,
174+ (double)(imp_scale * gain * filter), (int) rs->width_, out );
175+ out += rs->width_;
176+
177+ int cur_step = step;
178+ pos += fraction;
179+ if ( pos >= 0.9999999 )
180+ {
181+ pos -= 1.0;
182+ cur_step += stereo;
183+ }
184+
185+ ((imp_off_t*)out)[0] = (cur_step - rs->width_ * 2 + 4) * sizeof (sample_t);
186+ ((imp_off_t*)out)[1] = 2 * sizeof (imp_t) + 2 * sizeof (imp_off_t);
187+ out += 2 * (sizeof(imp_off_t) / sizeof(imp_t));
188+ /*input_per_cycle += cur_step;*/
189+ }
190+ /* last offset moves back to beginning of impulses*/
191+ ((imp_off_t*)out) [-1] -= (char*) out - (char*) rs->impulses;
192+
193+ rs->imp = rs->impulses;
194+}
195+
196+int resampler_get_free(void *_r)
197+{
198+ resampler *r = (resampler *)_r;
199+ return buffer_size * stereo - r->infilled;
200+}
201+
202+int resampler_get_min_fill(void *_r)
203+{
204+ resampler *r = (resampler *)_r;
205+ const int min_needed = write_offset + stereo;
206+ const int latency = r->latency ? 0 : adj_width;
207+ int min_free = min_needed - r->infilled - latency;
208+ return min_free < 0 ? 0 : min_free;
209+}
210+
211+void resampler_write_pair(void *_r, sample_t ls, sample_t rs)
212+{
213+ resampler *r = (resampler *)_r;
214+
215+ if (!r->latency)
216+ {
217+ for (int i = 0; i < adj_width / 2; ++i)
218+ {
219+ r->buffer_in[r->inptr + 0] = 0;
220+ r->buffer_in[r->inptr + 1] = 0;
221+ r->buffer_in[buffer_size * stereo + r->inptr + 0] = 0;
222+ r->buffer_in[buffer_size * stereo + r->inptr + 1] = 0;
223+ r->inptr = (r->inptr + stereo) % (buffer_size * stereo);
224+ r->infilled += stereo;
225+ }
226+ r->latency = 1;
227+ }
228+
229+ if (r->infilled < buffer_size * stereo)
230+ {
231+ r->buffer_in[r->inptr + 0] = ls;
232+ r->buffer_in[r->inptr + 1] = rs;
233+ r->buffer_in[buffer_size * stereo + r->inptr + 0] = ls;
234+ r->buffer_in[buffer_size * stereo + r->inptr + 1] = rs;
235+ r->inptr = (r->inptr + stereo) % (buffer_size * stereo);
236+ r->infilled += stereo;
237+ }
238+}
239+
240+#ifdef _MSC_VER
241+#define restrict __restrict
242+#endif
243+
244+static const sample_t * resampler_inner_loop( resampler *r, sample_t** out_,
245+ sample_t const* out_end, sample_t const in [], int in_size )
246+{
247+ in_size -= write_offset;
248+ if ( in_size > 0 )
249+ {
250+ sample_t* restrict out = *out_;
251+ sample_t const* const in_end = in + in_size;
252+ imp_t const* imp = r->imp;
253+
254+ do
255+ {
256+ /* accumulate in extended precision*/
257+ int pt = imp [0];
258+ intermediate_t l = (intermediate_t)pt * (intermediate_t)(in [0]);
259+ intermediate_t r = (intermediate_t)pt * (intermediate_t)(in [1]);
260+ if ( out >= out_end )
261+ break;
262+ for ( int n = (adj_width - 2) / 2; n; --n )
263+ {
264+ pt = imp [1];
265+ l += (intermediate_t)pt * (intermediate_t)(in [2]);
266+ r += (intermediate_t)pt * (intermediate_t)(in [3]);
267+
268+ /* pre-increment more efficient on some RISC processors*/
269+ imp += 2;
270+ pt = imp [0];
271+ r += (intermediate_t)pt * (intermediate_t)(in [5]);
272+ in += 4;
273+ l += (intermediate_t)pt * (intermediate_t)(in [0]);
274+ }
275+ pt = imp [1];
276+ l += (intermediate_t)pt * (intermediate_t)(in [2]);
277+ r += (intermediate_t)pt * (intermediate_t)(in [3]);
278+
279+ /* these two "samples" after the end of the impulse give the
280+ * proper offsets to the next input sample and next impulse */
281+ in = (sample_t const*) ((char const*) in + ((imp_off_t*)(&imp [2]))[0]); /* some negative value */
282+ imp = (imp_t const*) ((char const*) imp + ((imp_off_t*)(&imp [2]))[1]); /* small positive or large negative */
283+
284+ out [0] = (sample_t) (l >> 15);
285+ out [1] = (sample_t) (r >> 15);
286+ out += 2;
287+ }
288+ while ( in < in_end );
289+
290+ r->imp = imp;
291+ *out_ = out;
292+ }
293+ return in;
294+}
295+
296+#undef restrict
297+
298+static int resampler_wrapper( resampler *r, sample_t out [], int* out_size,
299+ sample_t const in [], int in_size )
300+{
301+ sample_t* out_ = out;
302+ int result = resampler_inner_loop( r, &out_, out + *out_size, in, in_size ) - in;
303+
304+ *out_size = out_ - out;
305+ return result;
306+}
307+
308+static void resampler_fill( resampler *r )
309+{
310+ while (!r->outfilled && r->infilled)
311+ {
312+ int writepos = ( r->outptr + r->outfilled ) % (buffer_size * stereo);
313+ int writesize = (buffer_size * stereo) - writepos;
314+ if ( writesize > ( buffer_size * stereo - r->outfilled ) )
315+ writesize = buffer_size * stereo - r->outfilled;
316+ int inread = resampler_wrapper(r, &r->buffer_out[writepos], &writesize, &r->buffer_in[buffer_size * stereo + r->inptr - r->infilled], r->infilled);
317+ r->infilled -= inread;
318+ r->outfilled += writesize;
319+ if (!inread)
320+ break;
321+ }
322+}
323+
324+int resampler_get_avail(void *_r)
325+{
326+ resampler *r = (resampler *)_r;
327+ if (r->outfilled < stereo && r->infilled >= r->width_)
328+ resampler_fill( r );
329+ return r->outfilled;
330+}
331+
332+static void resampler_read_pair_internal( resampler *r, sample_t *ls, sample_t *rs, int advance )
333+{
334+ if (r->outfilled < stereo)
335+ resampler_fill( r );
336+ if (r->outfilled < stereo)
337+ {
338+ *ls = 0;
339+ *rs = 0;
340+ return;
341+ }
342+ *ls = r->buffer_out[r->outptr + 0];
343+ *rs = r->buffer_out[r->outptr + 1];
344+ if (advance)
345+ {
346+ r->outptr = (r->outptr + 2) % (buffer_size * stereo);
347+ r->outfilled -= stereo;
348+ }
349+}
350+
351+void resampler_read_pair( void *_r, sample_t *ls, sample_t *rs )
352+{
353+ resampler *r = (resampler *)_r;
354+ resampler_read_pair_internal(r, ls, rs, 1);
355+}
356+
357+void resampler_peek_pair( void *_r, sample_t *ls, sample_t *rs )
358+{
359+ resampler *r = (resampler *)_r;
360+ resampler_read_pair_internal(r, ls, rs, 0);
361+}
src/syntrax/resampler.hView
@@ -1,0 +1,75 @@
1+#ifndef _RESAMPLER_H_
2+#define _RESAMPLER_H_
3+
4+/* Copyright (C) 2004-2008 Shay Green.
5+ Copyright (C) 2015 Christopher Snowhill. This module is free software; you
6+can redistribute it and/or modify it under the terms of the GNU Lesser
7+General Public License as published by the Free Software Foundation; either
8+version 2.1 of the License, or (at your option) any later version. This
9+module is distributed in the hope that it will be useful, but WITHOUT ANY
10+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12+details. You should have received a copy of the GNU Lesser General Public
13+License along with this module; if not, write to the Free Software Foundation,
14+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
15+
16+#define RESAMPLER_BITS 32
17+#define RESAMPLER_DECORATE syntrax
18+
19+#ifdef RESAMPLER_DECORATE
20+#undef PASTE
21+#undef EVALUATE
22+#define PASTE(a,b) a ## b
23+#define EVALUATE(a,b) PASTE(a,b)
24+#define resampler_create EVALUATE(RESAMPLER_DECORATE,_resampler_create)
25+#define resampler_dup EVALUATE(RESAMPLER_DECORATE,_resampler_dup)
26+#define resampler_dup_inplace EVALUATE(RESAMPLER_DECORATE,_resampler_dup_inplace)
27+#define resampler_destroy EVALUATE(RESAMPLER_DECORATE,_resampler_destroy)
28+#define resampler_clear EVALUATE(RESAMPLER_DECORATE,_resampler_clear)
29+#define resampler_set_rate EVALUATE(RESAMPLER_DECORATE,_resampler_set_rate)
30+#define resampler_get_free EVALUATE(RESAMPLER_DECORATE,_resampler_get_free)
31+#define resampler_get_min_fill EVALUATE(RESAMPLER_DECORATE,_resampler_get_min_fill)
32+#define resampler_write_pair EVALUATE(RESAMPLER_DECORATE,_resampler_write_pair)
33+#define resampler_get_avail EVALUATE(RESAMPLER_DECORATE,_resampler_get_avail)
34+#define resampler_read_pair EVALUATE(RESAMPLER_DECORATE,_resampler_read_pair)
35+#define resampler_peek_pair EVALUATE(RESAMPLER_DECORATE,_resampler_peek_pair)
36+#endif
37+
38+#include <stdint.h>
39+
40+#if RESAMPLER_BITS == 16
41+typedef int16_t sample_t;
42+#elif RESAMPLER_BITS == 32
43+typedef int32_t sample_t;
44+#else
45+#error Choose a bit depth!
46+#endif
47+
48+#ifdef __cplusplus
49+extern "C" {
50+#endif
51+
52+void * resampler_create();
53+void * resampler_dup(const void *);
54+void resampler_dup_inplace(void *, const void *);
55+void resampler_destroy(void *);
56+
57+void resampler_clear(void *);
58+
59+void resampler_set_rate( void *, double new_factor );
60+
61+int resampler_get_free(void *);
62+int resampler_get_min_fill(void *);
63+
64+void resampler_write_pair(void *, sample_t ls, sample_t rs);
65+
66+int resampler_get_avail(void *);
67+
68+void resampler_read_pair( void *, sample_t *ls, sample_t *rs );
69+void resampler_peek_pair( void *, sample_t *ls, sample_t *rs );
70+
71+#ifdef __cplusplus
72+}
73+#endif
74+
75+#endif

Built with git-ssb-web