1 | Index: player_mod.cpp
|
---|
2 | ===================================================================
|
---|
3 | --- player_mod.cpp (revision 30828)
|
---|
4 | +++ player_mod.cpp (working copy)
|
---|
5 | @@ -41,8 +41,9 @@
|
---|
6 | _channels[i].id = 0;
|
---|
7 | _channels[i].vol = 0;
|
---|
8 | _channels[i].freq = 0;
|
---|
9 | - _channels[i].converter = NULL;
|
---|
10 | _channels[i].input = NULL;
|
---|
11 | + _channels[i].ctr = 0;
|
---|
12 | + _channels[i].pos = 0;
|
---|
13 | }
|
---|
14 |
|
---|
15 | _playproc = NULL;
|
---|
16 | @@ -56,7 +57,6 @@
|
---|
17 | for (int i = 0; i < MOD_MAXCHANS; i++) {
|
---|
18 | if (!_channels[i].id)
|
---|
19 | continue;
|
---|
20 | - delete _channels[i].converter;
|
---|
21 | delete _channels[i].input;
|
---|
22 | }
|
---|
23 | }
|
---|
24 | @@ -93,8 +93,10 @@
|
---|
25 | _channels[i].vol = vol;
|
---|
26 | _channels[i].pan = pan;
|
---|
27 | _channels[i].freq = rate;
|
---|
28 | + _channels[i].ctr = 0;
|
---|
29 | _channels[i].input = Audio::makeLinearInputStream((const byte*)data, size, rate, Audio::Mixer::FLAG_AUTOFREE | (loopStart != loopEnd ? Audio::Mixer::FLAG_LOOP : 0), loopStart, loopEnd);
|
---|
30 | - _channels[i].converter = Audio::makeRateConverter(rate, _mixer->getOutputRate(), false, false);
|
---|
31 | + // read the first sample
|
---|
32 | + _channels[i].input->readBuffer(&_channels[i].pos, 1);
|
---|
33 | }
|
---|
34 |
|
---|
35 | void Player_MOD::stopChannel(int id) {
|
---|
36 | @@ -102,13 +104,13 @@
|
---|
37 | error("player_mod - attempted to stop channel id 0");
|
---|
38 | for (int i = 0; i < MOD_MAXCHANS; i++) {
|
---|
39 | if (_channels[i].id == id) {
|
---|
40 | - delete _channels[i].converter;
|
---|
41 | - _channels[i].converter = NULL;
|
---|
42 | delete _channels[i].input;
|
---|
43 | _channels[i].input = NULL;
|
---|
44 | _channels[i].id = 0;
|
---|
45 | _channels[i].vol = 0;
|
---|
46 | _channels[i].freq = 0;
|
---|
47 | + _channels[i].ctr = 0;
|
---|
48 | + _channels[i].pos = 0;
|
---|
49 | }
|
---|
50 | }
|
---|
51 | }
|
---|
52 | @@ -139,9 +141,9 @@
|
---|
53 | error("player_mod - attempted to set frequency for channel id 0");
|
---|
54 | for (int i = 0; i < MOD_MAXCHANS; i++) {
|
---|
55 | if (_channels[i].id == id) {
|
---|
56 | + if (freq > 31400) // this is about as high as WinUAE goes
|
---|
57 | + freq = 31400; // can't easily verify on my own Amiga
|
---|
58 | _channels[i].freq = freq;
|
---|
59 | - delete _channels[i].converter;
|
---|
60 | - _channels[i].converter = Audio::makeRateConverter(freq, _mixer->getOutputRate(), false, false);
|
---|
61 | break;
|
---|
62 | }
|
---|
63 | }
|
---|
64 | @@ -170,11 +172,51 @@
|
---|
65 | len = 0;
|
---|
66 | }
|
---|
67 | for (i = 0; i < MOD_MAXCHANS; i++)
|
---|
68 | + {
|
---|
69 | if (_channels[i].id) {
|
---|
70 | Audio::st_volume_t vol_l = (127 - _channels[i].pan) * _channels[i].vol / 127;
|
---|
71 | Audio::st_volume_t vol_r = (127 + _channels[i].pan) * _channels[i].vol / 127;
|
---|
72 | - _channels[i].converter->flow(*_channels[i].input, &data[dpos*2], dlen, vol_l, vol_r);
|
---|
73 | + for (uint j = 0; j < dlen; j++)
|
---|
74 | + {
|
---|
75 | + // simple linear resample, unbuffered
|
---|
76 | + int delta = (uint32)(_channels[i].freq * 0x10000) / _samplerate;
|
---|
77 | + uint16 cfrac = ~_channels[i].ctr & 0xFFFF;
|
---|
78 | + if (_channels[i].ctr + delta < 0x10000)
|
---|
79 | + cfrac = delta;
|
---|
80 | + _channels[i].ctr += delta;
|
---|
81 | + int32 cpos = _channels[i].pos * cfrac / 0x10000;
|
---|
82 | + while (_channels[i].ctr >= 0x10000)
|
---|
83 | + {
|
---|
84 | + if (_channels[i].input->readBuffer(&_channels[i].pos, 1) != 1)
|
---|
85 | + { // out of data
|
---|
86 | + stopChannel(_channels[i].id);
|
---|
87 | + goto skipchan; // exit 2 loops at once
|
---|
88 | + }
|
---|
89 | + _channels[i].ctr -= 0x10000;
|
---|
90 | + if (_channels[i].ctr > 0x10000)
|
---|
91 | + cpos += _channels[i].pos;
|
---|
92 | + else cpos += (int32)(_channels[i].pos * (_channels[i].ctr & 0xFFFF)) / 0x10000;
|
---|
93 | + }
|
---|
94 | + int16 pos = 0;
|
---|
95 | + // if too many samples play in a row, the calculation below will overflow and clip
|
---|
96 | + // so try and split it up into pieces it can manage comfortably
|
---|
97 | + while (cpos < -0x8000)
|
---|
98 | + {
|
---|
99 | + pos -= 0x80000000 / delta;
|
---|
100 | + cpos += 0x8000;
|
---|
101 | + }
|
---|
102 | + while (cpos > 0x7FFF)
|
---|
103 | + {
|
---|
104 | + pos += 0x7FFF0000 / delta;
|
---|
105 | + cpos -= 0x7FFF;
|
---|
106 | + }
|
---|
107 | + pos += cpos * 0x10000 / delta;
|
---|
108 | + Audio::clampedAdd(data[(dpos + j) * 2 + 0], pos * vol_l / Audio::Mixer::kMaxMixerVolume);
|
---|
109 | + Audio::clampedAdd(data[(dpos + j) * 2 + 1], pos * vol_r / Audio::Mixer::kMaxMixerVolume);
|
---|
110 | + }
|
---|
111 | }
|
---|
112 | +skipchan: ; // channel ran out of data
|
---|
113 | + }
|
---|
114 | dpos += dlen;
|
---|
115 | }
|
---|
116 | }
|
---|
117 | Index: player_mod.h
|
---|
118 | ===================================================================
|
---|
119 | --- player_mod.h (revision 30828)
|
---|
120 | +++ player_mod.h (working copy)
|
---|
121 | @@ -75,7 +75,9 @@
|
---|
122 | uint8 vol;
|
---|
123 | int8 pan;
|
---|
124 | uint16 freq;
|
---|
125 | - Audio::RateConverter *converter;
|
---|
126 | +
|
---|
127 | + uint32 ctr;
|
---|
128 | + int16 pos;
|
---|
129 | Audio::AudioStream *input;
|
---|
130 | };
|
---|
131 |
|
---|