Ticket #8799: amiaudio.dif

File amiaudio.dif, 4.1 KB (added by SF/quietust, 16 years ago)

Amiga audio patch

Line 
1Index: 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 }
117Index: 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