Previous 199869 Revisions Next

r19976 Monday 31st December, 2012 at 22:04:28 UTC by R. Belmont
Split AMM decoder from YMZ770 and add MPEG layer 1/2 support [O. Galibert]

De-skeletonized Sega Z80 type Digital Sound Board, hooked up to swa [R. Belmont, O. Galibert]
[src/emu/sound]mpeg_audio.c* mpeg_audio.h* sound.mak ymz770.c ymz770.h
[src/mame/audio]dsbz80.c dsbz80.h
[src/mame/drivers]model1.c
[src/mame/includes]model1.h

trunk/src/emu/sound/mpeg_audio.c
r0r19976
1/***************************************************************************
2
3   MPEG audio support.  Only layer2 and variants for now.
4
5***************************************************************************/
6
7#include "emu.h"
8#include "mpeg_audio.h"
9
10mpeg_audio::mpeg_audio(const void *_base, unsigned int _accepted, bool lsb_first, int _position_align)
11{
12   base = (const UINT8 *)_base;
13   accepted = _accepted;
14   do_gb = lsb_first ? do_gb_lsb : do_gb_msb;
15   position_align = _position_align ? _position_align - 1 : 0;
16
17   memset(audio_buffer, 0, sizeof(audio_buffer));
18   audio_buffer_pos[0] = 16*32;
19   audio_buffer_pos[1] = 16*32;
20}
21
22
23bool mpeg_audio::decode_buffer(int &pos, int limit, short *output,
24                        int &output_samples, int &sample_rate, int &channels)
25{
26   if(limit - pos < 16)
27      return false;
28
29   // Scan for the sync mark
30   //
31   // Avoid the exception dance at the point where going out of bound
32   // is the most probable and easily avoidable
33
34   current_pos = pos;
35   current_limit = limit;
36   unsigned short sync = do_gb(base, current_pos, 12);
37
38 retry_sync:
39   while(sync != 0xfff && current_pos < limit)
40      sync = ((sync << 1) | do_gb(base, current_pos, 1)) & 0xfff;
41
42   if(limit - current_pos < 4)
43      return false;
44
45   int layer = 0;
46   int variant = do_gb(base, current_pos, 3);
47   switch(variant) {
48   case 2:
49      if(accepted & L2_5)
50         layer = 2;
51      else if(accepted & AMM)
52         layer = 4;
53      break;
54
55   case 5:
56      if(accepted & L3)
57         layer = 3;
58      break;
59
60   case 6:
61      if(accepted & (L2|L2_5))
62         layer = 2;
63      else if(accepted & AMM)
64         layer = 4;
65      break;
66
67   case 7:
68      if(accepted & L1)
69         layer = 1;
70      break;
71   }
72
73   if(!layer) {
74      current_pos -= 3;
75      sync = ((sync << 1) | do_gb(base, current_pos, 1)) & 0xfff;
76      goto retry_sync;
77   }
78
79   switch(layer) {
80   case 1:
81      abort();
82   case 2:
83      try {
84         read_header_mpeg2(variant == 2);
85         read_data_mpeg2();
86         decode_mpeg2(output, output_samples);
87      } catch(limit_hit) {
88         return false;
89      }
90      break;
91   case 3:
92      abort();
93   case 4:
94      try {
95         read_header_amm(variant == 2);
96         read_data_mpeg2();
97         decode_mpeg2(output, output_samples);
98      } catch(limit_hit) {
99         return false;
100      }
101      break;
102   }
103
104   if(position_align)
105      current_pos = (current_pos + position_align) & ~position_align;
106
107   pos = current_pos;
108   sample_rate = sample_rates[sampling_rate];
109   channels = channel_count;
110   return true;
111}
112
113void mpeg_audio::read_header_amm(bool layer25)
114{
115   gb(1); // unused
116   int full_packets_count = gb(4); // max 12
117   int srate_index = gb(2); // max 2
118   sampling_rate = srate_index + 4 * layer25;
119   int last_packet_frame_id = gb(2); // max 2
120   last_frame_number = 3*full_packets_count + last_packet_frame_id;
121   int stereo_mode = gb(2);
122   int stereo_mode_ext = gb(2);
123   param_index = gb(3);
124   gb(1); // must be zero
125
126   channel_count = stereo_mode != 3 ? 2 : 1;
127
128   total_bands = total_band_counts[param_index];
129   joint_bands = total_bands;
130   if(stereo_mode == 1) // joint stereo
131      joint_bands = joint_band_counts[stereo_mode_ext];
132   if(joint_bands > total_bands )
133      joint_bands = total_bands;
134}
135
136void mpeg_audio::read_header_mpeg2(bool layer25)
137{
138   int prot = gb(1);
139   int bitrate_index = gb(4);
140   sampling_rate = gb(2);
141   gb(1); // padding
142   gb(1);
143   last_frame_number = 36;
144   int stereo_mode = gb(2);
145   int stereo_mode_ext = gb(2);
146   gb(2); // copyright, original
147   gb(2); // emphasis
148   if(!prot)
149      gb(16); // crc
150
151   channel_count = stereo_mode != 3 ? 2 : 1;
152
153   param_index = layer2_param_index[channel_count-1][sampling_rate][bitrate_index];
154   assert(param_index != -1);
155
156   total_bands = total_band_counts[param_index];
157   joint_bands = total_bands;
158   if(stereo_mode == 1) // joint stereo
159      joint_bands = joint_band_counts[stereo_mode_ext];
160   if(joint_bands > total_bands )
161      joint_bands = total_bands;
162}
163
164void mpeg_audio::read_data_mpeg2()
165{
166   read_band_params();
167   read_scfci();
168   read_band_amplitude_params();
169}
170
171void mpeg_audio::decode_mpeg2(short *output, int &output_samples)
172{
173   output_samples = 0;
174   build_amplitudes();
175
176   // Supposed to stop at last_frame_number when it's not 12*3+2 = 38
177   int frame_number = 0;
178   for(int upper_step = 0; upper_step<3; upper_step++)
179      for(int middle_step = 0; middle_step < 4; middle_step++) {
180         build_next_segments(upper_step);
181         for(int lower_step = 0; lower_step < 3; lower_step++) {
182            retrieve_subbuffer(lower_step);
183
184            for(int chan=0; chan<channel_count; chan++) {
185               double resynthesis_buffer[32];
186               idct32(subbuffer[chan], audio_buffer[chan] + audio_buffer_pos[chan]);
187               resynthesis(audio_buffer[chan] + audio_buffer_pos[chan] + 16, resynthesis_buffer);
188               scale_and_clamp(resynthesis_buffer, output + chan, channel_count);
189               audio_buffer_pos[chan] -= 32;
190               if(audio_buffer_pos[chan]<0) {
191                  memmove(audio_buffer[chan]+17*32, audio_buffer[chan], 15*32*sizeof(audio_buffer[chan][0]));
192                  audio_buffer_pos[chan] = 16*32;
193               }
194            }
195            output += 32*channel_count;
196            output_samples += 32;
197            frame_number++;
198            if(frame_number == last_frame_number)
199               return;
200         }
201      }
202}
203
204const int mpeg_audio::sample_rates[8] = { 44100, 48000, 32000, 0, 22050, 24000, 16000, 0 };
205
206const int mpeg_audio::layer2_param_index[2][4][16] = {
207   {
208      {  1,  2,  2,  0,  0,  0,  1,  1,  1,  1,  1, -1, -1, -1, -1, -1 },
209      {  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1, -1, -1, -1 },
210      {  1,  3,  3,  0,  0,  0,  1,  1,  1,  1,  1, -1, -1, -1, -1, -1 },
211      { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
212   },
213   {
214      {  1, -1, -1, -1,  2, -1,  2,  0,  0,  0,  1,  1,  1,  1,  1, -1 },
215      {  0, -1, -1, -1,  2, -1,  2,  0,  0,  0,  0,  0,  0,  0,  0, -1 },
216      {  1, -1, -1, -1,  3, -1,  3,  0,  0,  0,  1,  1,  1,  1,  1, -1 },
217      { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
218   }
219};
220
221const int mpeg_audio::band_parameter_indexed_values[5][32][17] = {
222   {
223      {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
224      {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
225      {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
226      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
227      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
228      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
229      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
230      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
231      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
232      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
233      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
234      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
235      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
236      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
237      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
238      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
239      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
240      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
241      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
242      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
243      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
244      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
245      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
246      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
247      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
248      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
249      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
250      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
251      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
252      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
253      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
254      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
255   },
256   {
257      {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
258      {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
259      {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
260      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
261      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
262      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
263      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
264      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
265      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
266      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
267      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
268      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
269      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
270      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
271      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
272      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
273      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
274      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
275      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
276      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
277      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
278      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
279      {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
280      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
281      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
282      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
283      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
284      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
285      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
286      {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
287      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
288      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
289   },
290   {
291      {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
292      {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
293      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
294      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
295      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
296      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
297      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
298      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
299      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
300      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
301      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
302      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
303      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
304      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
305      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
306      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
307      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
308      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
309      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
310      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
311      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
312      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
313      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
314      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
315      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
316      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
317      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
318      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
319      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
320      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
321      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
322      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
323   },
324   {
325      {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
326      {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
327      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
328      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
329      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
330      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
331      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
332      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
333      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
334      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
335      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
336      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
337      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
338      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
339      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
340      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
341      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
342      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
343      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
344      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
345      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
346      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
347      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
348      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
349      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
350      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
351      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
352      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
353      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
354      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
355      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
356      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
357   },
358   {
359      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
360      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
361      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
362      {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
363      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
364      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
365      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
366      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
367      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
368      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
369      {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
370      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
371      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
372      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
373      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
374      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
375      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
376      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
377      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
378      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
379      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
380      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
381      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
382      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
383      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
384      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
385      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
386      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
387      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
388      {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
389      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
390      {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
391   }
392};
393
394const int mpeg_audio::band_parameter_index_bits_count[5][32] = {
395   { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, },
396   { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 0, 0, },
397   { 4, 4, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
398   { 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
399   { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, },
400};
401
402const int mpeg_audio::total_band_counts[5] = { 27, 30, 8, 12, 30 };
403
404const int mpeg_audio::joint_band_counts[4] = { 4, 8, 12, 16 };
405
406const mpeg_audio::band_info mpeg_audio::band_infos[18] = {
407   { 0x0000,  0.00,  0,  0, 0,  0,           0,          0,                 0,         0 },
408   { 0x0003,  7.00,  2,  5, 3,  9, 1-1.0/    4, -1.0/    4,   1/(1-1.0/    4), 1.0/    2 },
409   { 0x0005, 11.00,  3,  7, 5, 25, 1-3.0/    8, -3.0/    8,   1/(1-3.0/    8), 1.0/    2 },
410   { 0x0007, 16.00,  3,  9, 0,  0, 1-1.0/    8, -1.0/    8,   1/(1-1.0/    8), 1.0/    4 },
411   { 0x0009, 20.84,  4, 10, 9, 81, 1-7.0/   16, -7.0/   16,   1/(1-7.0/   16), 1.0/    2 },
412   { 0x000f, 25.28,  4, 12, 0,  0, 1-1.0/   16, -1.0/   16,   1/(1-1.0/   16), 1.0/    8 },
413   { 0x001f, 31.59,  5, 15, 0,  0, 1-1.0/   32, -1.0/   32,   1/(1-1.0/   32), 1.0/   16 },
414   { 0x003f, 37.75,  6, 18, 0,  0, 1-1.0/   64, -1.0/   64,   1/(1-1.0/   64), 1.0/   32 },
415   { 0x007f, 43.84,  7, 21, 0,  0, 1-1.0/  128, -1.0/  128,   1/(1-1.0/  128), 1.0/   64 },
416   { 0x00ff, 49.89,  8, 24, 0,  0, 1-1.0/  256, -1.0/  256,   1/(1-1.0/  256), 1.0/  128 },
417   { 0x01ff, 55.93,  9, 27, 0,  0, 1-1.0/  512, -1.0/  512,   1/(1-1.0/  512), 1.0/  256 },
418   { 0x03ff, 61.96, 10, 30, 0,  0, 1-1.0/ 1024, -1.0/ 1024,   1/(1-1.0/ 1024), 1.0/  512 },
419   { 0x07ff, 67.98, 11, 33, 0,  0, 1-1.0/ 2048, -1.0/ 2048,   1/(1-1.0/ 2048), 1.0/ 1024 },
420   { 0x0fff, 74.01, 12, 36, 0,  0, 1-1.0/ 4096, -1.0/ 4096,   1/(1-1.0/ 4096), 1.0/ 2048 },
421   { 0x1fff, 80.03, 13, 39, 0,  0, 1-1.0/ 8192, -1.0/ 8192,   1/(1-1.0/ 8192), 1.0/ 4096 },
422   { 0x3fff, 86.05, 14, 42, 0,  0, 1-1.0/16384, -1.0/16384,   1/(1-1.0/16384), 1.0/ 8192 },
423   { 0x7fff, 92.01, 15, 45, 0,  0, 1-1.0/32768, -1.0/32768,   1/(1-1.0/32768), 1.0/16384 },
424   { 0xffff, 98.01, 16, 48, 0,  0, 1-1.0/65536, -1.0/65536,   1/(1-1.0/65536), 1.0/32768 },
425};
426
427const double mpeg_audio::scalefactors[64] = {
428   2.00000000000000, 1.58740105196820, 1.25992104989487, 1.00000000000000,
429   0.79370052598410, 0.62996052494744, 0.50000000000000, 0.39685026299205,
430   0.31498026247372, 0.25000000000000, 0.19842513149602, 0.15749013123686,
431   0.12500000000000, 0.09921256574801, 0.07874506561843, 0.06250000000000,
432   0.04960628287401, 0.03937253280921, 0.03125000000000, 0.02480314143700,
433   0.01968626640461, 0.01562500000000, 0.01240157071850, 0.00984313320230,
434   0.00781250000000, 0.00620078535925, 0.00492156660115, 0.00390625000000,
435   0.00310039267963, 0.00246078330058, 0.00195312500000, 0.00155019633981,
436   0.00123039165029, 0.00097656250000, 0.00077509816991, 0.00061519582514,
437   0.00048828125000, 0.00038754908495, 0.00030759791257, 0.00024414062500,
438   0.00019377454248, 0.00015379895629, 0.00012207031250, 0.00009688727124,
439   0.00007689947814, 0.00006103515625, 0.00004844363562, 0.00003844973907,
440   0.00003051757812, 0.00002422181781, 0.00001922486954, 0.00001525878906,
441   0.00001211090890, 0.00000961243477, 0.00000762939453, 0.00000605545445,
442   0.00000480621738, 0.00000381469727, 0.00000302772723, 0.00000240310869,
443   0.00000190734863, 0.00000151386361, 0.00000120155435, 0.00000000000000
444};
445
446const double mpeg_audio::synthesis_filter[512] = {
447   +0.000000000, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000030518,
448   -0.000030518, -0.000030518, -0.000030518, -0.000045776, -0.000045776, -0.000061035, -0.000061035, -0.000076294,
449   -0.000076294, -0.000091553, -0.000106812, -0.000106812, -0.000122070, -0.000137329, -0.000152588, -0.000167847,
450   -0.000198364, -0.000213623, -0.000244141, -0.000259399, -0.000289917, -0.000320435, -0.000366211, -0.000396729,
451   -0.000442505, -0.000473022, -0.000534058, -0.000579834, -0.000625610, -0.000686646, -0.000747681, -0.000808716,
452   -0.000885010, -0.000961304, -0.001037598, -0.001113892, -0.001205444, -0.001296997, -0.001388550, -0.001480103,
453   -0.001586914, -0.001693726, -0.001785278, -0.001907349, -0.002014160, -0.002120972, -0.002243042, -0.002349854,
454   -0.002456665, -0.002578735, -0.002685547, -0.002792358, -0.002899170, -0.002990723, -0.003082275, -0.003173828,
455   +0.003250122, +0.003326416, +0.003387451, +0.003433228, +0.003463745, +0.003479004, +0.003479004, +0.003463745,
456   +0.003417969, +0.003372192, +0.003280640, +0.003173828, +0.003051758, +0.002883911, +0.002700806, +0.002487183,
457   +0.002227783, +0.001937866, +0.001617432, +0.001266479, +0.000869751, +0.000442505, -0.000030518, -0.000549316,
458   -0.001098633, -0.001693726, -0.002334595, -0.003005981, -0.003723145, -0.004486084, -0.005294800, -0.006118774,
459   -0.007003784, -0.007919312, -0.008865356, -0.009841919, -0.010848999, -0.011886597, -0.012939453, -0.014022827,
460   -0.015121460, -0.016235352, -0.017349243, -0.018463135, -0.019577026, -0.020690918, -0.021789550, -0.022857666,
461   -0.023910522, -0.024932861, -0.025909424, -0.026840210, -0.027725220, -0.028533936, -0.029281616, -0.029937744,
462   -0.030532837, -0.031005860, -0.031387330, -0.031661987, -0.031814575, -0.031845093, -0.031738280, -0.031478880,
463   +0.031082153, +0.030517578, +0.029785156, +0.028884888, +0.027801514, +0.026535034, +0.025085450, +0.023422241,
464   +0.021575928, +0.019531250, +0.017257690, +0.014801025, +0.012115479, +0.009231567, +0.006134033, +0.002822876,
465   -0.000686646, -0.004394531, -0.008316040, -0.012420654, -0.016708374, -0.021179200, -0.025817871, -0.030609130,
466   -0.035552980, -0.040634155, -0.045837402, -0.051132202, -0.056533813, -0.061996460, -0.067520140, -0.073059080,
467   -0.078628540, -0.084182740, -0.089706420, -0.095169070, -0.100540160, -0.105819700, -0.110946655, -0.115921020,
468   -0.120697020, -0.125259400, -0.129562380, -0.133590700, -0.137298580, -0.140670780, -0.143676760, -0.146255500,
469   -0.148422240, -0.150115970, -0.151306150, -0.151962280, -0.152069090, -0.151596070, -0.150497440, -0.148773200,
470   -0.146362300, -0.143264770, -0.139450070, -0.134887700, -0.129577640, -0.123474120, -0.116577150, -0.108856200,
471   +0.100311280, +0.090927124, +0.080688480, +0.069595340, +0.057617188, +0.044784546, +0.031082153, +0.016510010,
472   +0.001068115, -0.015228271, -0.032379150, -0.050354004, -0.069168090, -0.088775635, -0.109161380, -0.130310060,
473   -0.152206420, -0.174789430, -0.198059080, -0.221984860, -0.246505740, -0.271591200, -0.297210700, -0.323318480,
474   -0.349868770, -0.376800540, -0.404083250, -0.431655880, -0.459472660, -0.487472530, -0.515609740, -0.543823240,
475   -0.572036740, -0.600219700, -0.628295900, -0.656219500, -0.683914200, -0.711318970, -0.738372800, -0.765029900,
476   -0.791214000, -0.816864000, -0.841949460, -0.866363500, -0.890090940, -0.913055400, -0.935195900, -0.956481930,
477   -0.976852400, -0.996246340, -1.014617900, -1.031936600, -1.048156700, -1.063217200, -1.077117900, -1.089782700,
478   -1.101211500, -1.111373900, -1.120224000, -1.127746600, -1.133926400, -1.138763400, -1.142211900, -1.144287100,
479   +1.144989000, +1.144287100, +1.142211900, +1.138763400, +1.133926400, +1.127746600, +1.120224000, +1.111373900,
480   +1.101211500, +1.089782700, +1.077117900, +1.063217200, +1.048156700, +1.031936600, +1.014617900, +0.996246340,
481   +0.976852400, +0.956481930, +0.935195900, +0.913055400, +0.890090940, +0.866363500, +0.841949460, +0.816864000,
482   +0.791214000, +0.765029900, +0.738372800, +0.711318970, +0.683914200, +0.656219500, +0.628295900, +0.600219700,
483   +0.572036740, +0.543823240, +0.515609740, +0.487472530, +0.459472660, +0.431655880, +0.404083250, +0.376800540,
484   +0.349868770, +0.323318480, +0.297210700, +0.271591200, +0.246505740, +0.221984860, +0.198059080, +0.174789430,
485   +0.152206420, +0.130310060, +0.109161380, +0.088775635, +0.069168090, +0.050354004, +0.032379150, +0.015228271,
486   -0.001068115, -0.016510010, -0.031082153, -0.044784546, -0.057617188, -0.069595340, -0.080688480, -0.090927124,
487   +0.100311280, +0.108856200, +0.116577150, +0.123474120, +0.129577640, +0.134887700, +0.139450070, +0.143264770,
488   +0.146362300, +0.148773200, +0.150497440, +0.151596070, +0.152069090, +0.151962280, +0.151306150, +0.150115970,
489   +0.148422240, +0.146255500, +0.143676760, +0.140670780, +0.137298580, +0.133590700, +0.129562380, +0.125259400,
490   +0.120697020, +0.115921020, +0.110946655, +0.105819700, +0.100540160, +0.095169070, +0.089706420, +0.084182740,
491   +0.078628540, +0.073059080, +0.067520140, +0.061996460, +0.056533813, +0.051132202, +0.045837402, +0.040634155,
492   +0.035552980, +0.030609130, +0.025817871, +0.021179200, +0.016708374, +0.012420654, +0.008316040, +0.004394531,
493   +0.000686646, -0.002822876, -0.006134033, -0.009231567, -0.012115479, -0.014801025, -0.017257690, -0.019531250,
494   -0.021575928, -0.023422241, -0.025085450, -0.026535034, -0.027801514, -0.028884888, -0.029785156, -0.030517578,
495   +0.031082153, +0.031478880, +0.031738280, +0.031845093, +0.031814575, +0.031661987, +0.031387330, +0.031005860,
496   +0.030532837, +0.029937744, +0.029281616, +0.028533936, +0.027725220, +0.026840210, +0.025909424, +0.024932861,
497   +0.023910522, +0.022857666, +0.021789550, +0.020690918, +0.019577026, +0.018463135, +0.017349243, +0.016235352,
498   +0.015121460, +0.014022827, +0.012939453, +0.011886597, +0.010848999, +0.009841919, +0.008865356, +0.007919312,
499   +0.007003784, +0.006118774, +0.005294800, +0.004486084, +0.003723145, +0.003005981, +0.002334595, +0.001693726,
500   +0.001098633, +0.000549316, +0.000030518, -0.000442505, -0.000869751, -0.001266479, -0.001617432, -0.001937866,
501   -0.002227783, -0.002487183, -0.002700806, -0.002883911, -0.003051758, -0.003173828, -0.003280640, -0.003372192,
502   -0.003417969, -0.003463745, -0.003479004, -0.003479004, -0.003463745, -0.003433228, -0.003387451, -0.003326416,
503   +0.003250122, +0.003173828, +0.003082275, +0.002990723, +0.002899170, +0.002792358, +0.002685547, +0.002578735,
504   +0.002456665, +0.002349854, +0.002243042, +0.002120972, +0.002014160, +0.001907349, +0.001785278, +0.001693726,
505   +0.001586914, +0.001480103, +0.001388550, +0.001296997, +0.001205444, +0.001113892, +0.001037598, +0.000961304,
506   +0.000885010, +0.000808716, +0.000747681, +0.000686646, +0.000625610, +0.000579834, +0.000534058, +0.000473022,
507   +0.000442505, +0.000396729, +0.000366211, +0.000320435, +0.000289917, +0.000259399, +0.000244141, +0.000213623,
508   +0.000198364, +0.000167847, +0.000152588, +0.000137329, +0.000122070, +0.000106812, +0.000106812, +0.000091553,
509   +0.000076294, +0.000076294, +0.000061035, +0.000061035, +0.000045776, +0.000045776, +0.000030518, +0.000030518,
510   +0.000030518, +0.000030518, +0.000015259, +0.000015259, +0.000015259, +0.000015259, +0.000015259, +0.000015259,
511};
512
513int mpeg_audio::do_gb_msb(const unsigned char *data, int &pos, int count)
514{
515   int v = 0;
516   for(int i=0; i != count; i++) {
517      v <<= 1;
518      if(data[pos >> 3] & (0x80 >> (pos & 7)))
519         v |= 1;
520      pos++;
521   }
522   return v;
523}
524
525int mpeg_audio::do_gb_lsb(const unsigned char *data, int &pos, int count)
526{
527   int v = 0;
528   for(int i=0; i != count; i++) {
529      v <<= 1;
530      if(data[pos >> 3] & (0x01 << (pos & 7)))
531         v |= 1;
532      pos++;
533   }
534   return v;
535}
536
537int mpeg_audio::get_band_param(int band)
538{
539   int bit_count = band_parameter_index_bits_count[param_index][band];
540   int index = gb(bit_count);
541   return band_parameter_indexed_values[param_index][band][index];
542}
543
544void mpeg_audio::read_band_params()
545{
546   int band = 0;
547
548   while(band < joint_bands) {
549      for(int chan=0; chan < channel_count; chan++)
550         band_param[chan][band] = get_band_param(band);
551      band++;
552   }
553
554   while(band < total_bands) {
555      int val = get_band_param(band);
556      band_param[0][band] = val;
557      band_param[1][band] = val;
558      band++;
559   }
560
561   while(band < 32) {
562      band_param[0][band] = 0;
563      band_param[1][band] = 0;
564      band++;
565   }
566}
567
568void mpeg_audio::read_scfci()
569{
570   memset(scfsi, 0, sizeof(scfsi));
571   for(int band=0; band < total_bands; band++)
572      for(int chan=0; chan < channel_count; chan++)
573         if(band_param[chan][band])
574            scfsi[chan][band] = gb(2);
575}
576
577void mpeg_audio::read_band_amplitude_params()
578{
579   memset(scf, 0, sizeof(scf));
580   for(int band=0; band < total_bands; band++)
581      for(int chan=0; chan<channel_count; chan++)
582         if(band_param[chan][band]) {
583            switch(scfsi[chan][band]) {
584            case 0:
585               scf[chan][0][band] = gb(6);
586               scf[chan][1][band] = gb(6);
587               scf[chan][2][band] = gb(6);
588               break;
589
590            case 1: {
591               int val = gb(6);
592               scf[chan][0][band] = val;
593               scf[chan][1][band] = val;
594               scf[chan][2][band] = gb(6);
595               break;
596            }
597
598            case 2: {
599               int val = gb(6);
600               scf[chan][0][band] = val;
601               scf[chan][1][band] = val;
602               scf[chan][2][band] = val;
603               break;
604            }
605
606            case 3: {
607               scf[chan][0][band] = gb(6);
608               int val = gb(6);
609               scf[chan][1][band] = val;
610               scf[chan][2][band] = val;
611               break;
612            }
613            }
614         }
615}
616
617void mpeg_audio::build_amplitudes()
618{
619   memset(amp_values, 0, sizeof(amp_values));
620
621   for(int band=0; band < total_bands; band++)
622      for(int chan=0; chan<channel_count; chan++)
623         if(band_param[chan][band])
624            for(int step=0; step<3; step++)
625               amp_values[chan][step][band] = scalefactors[scf[chan][step][band]];
626}
627
628void mpeg_audio::read_band_value_triplet(int chan, int band)
629{
630   double buffer[3];
631
632   int band_idx = band_param[chan][band];
633   switch(band_idx) {
634   case 0:
635      bdata[chan][0][band] = 0;
636      bdata[chan][1][band] = 0;
637      bdata[chan][2][band] = 0;
638      return;
639
640   case 1:
641   case 2:
642   case 4: {
643      int modulo = band_infos[band_idx].modulo;
644      int val  = gb(band_infos[band_idx].cube_bits);
645      buffer[0] = val % modulo;
646      val = val / modulo;
647      buffer[1] = val % modulo;
648      val = val / modulo;
649      buffer[2] = val % modulo;
650      break;
651   }
652
653   default: {
654      int bits = band_infos[band_idx].bits;
655      buffer[0] = gb(bits);
656      buffer[1] = gb(bits);
657      buffer[2] = gb(bits);
658      break;
659   }
660   }
661
662   double scale = 1 << (band_infos[band_idx].bits - 1);
663
664   bdata[chan][0][band] = ((buffer[0] - scale) / scale + band_infos[band_idx].offset) * band_infos[band_idx].scale;
665   bdata[chan][1][band] = ((buffer[1] - scale) / scale + band_infos[band_idx].offset) * band_infos[band_idx].scale;
666   bdata[chan][2][band] = ((buffer[2] - scale) / scale + band_infos[band_idx].offset) * band_infos[band_idx].scale;
667}
668
669void mpeg_audio::build_next_segments(int step)
670{
671   int band = 0;
672   while(band < joint_bands) {
673      for(int chan=0; chan<channel_count; chan++) {
674         read_band_value_triplet(chan, band);
675         double amp = amp_values[chan][step][band];
676         bdata[chan][0][band] *= amp;
677         bdata[chan][1][band] *= amp;
678         bdata[chan][2][band] *= amp;
679      }
680      band++;
681   }
682
683   while(band < joint_bands) {
684      read_band_value_triplet(0, band);
685      bdata[1][0][band] = bdata[0][0][band];
686      bdata[1][1][band] = bdata[0][1][band];
687      bdata[1][2][band] = bdata[0][2][band];
688
689      for(int chan=0; chan<channel_count; chan++) {
690         double amp = amp_values[chan][step][band];
691         bdata[chan][0][band] *= amp;
692         bdata[chan][1][band] *= amp;
693         bdata[chan][2][band] *= amp;
694      }
695      band++;
696   }
697
698   while(band < 32) {
699      bdata[0][0][band] = 0;
700      bdata[0][1][band] = 0;
701      bdata[0][2][band] = 0;
702      bdata[1][0][band] = 0;
703      bdata[1][1][band] = 0;
704      bdata[1][2][band] = 0;
705      band++;
706   }
707}
708
709void mpeg_audio::retrieve_subbuffer(int step)
710{
711   for(int chan=0; chan<channel_count; chan++)
712      memcpy(subbuffer[chan], bdata[chan][step], 32*sizeof(subbuffer[0][0]));
713}
714
715void mpeg_audio::idct32(const double *input, double *output)
716{
717   // Simplest idct32 ever, non-fast at all
718   for(int i=0; i<32; i++) {
719      double s = 0;
720      for(int j=0; j<32; j++)
721         s += input[j] * cos(i*(2*j+1)*M_PI/64);
722      output[i] = s;
723   }
724}
725
726void mpeg_audio::resynthesis(const double *input, double *output)
727{
728   memset(output, 0, 32*sizeof(output[0]));
729   for(int j=0; j<64*8; j+=64) {
730      for(int i=0; i<16; i++)
731         output[i] += input[   i+j]*synthesis_filter[i+j] - input[32-i+j]*synthesis_filter[32+i+j];
732      output[16] -= input[16+j]*synthesis_filter[32+16+j];
733      for(int i=17; i<32; i++)
734         output[i] -= input[32-i+j]*synthesis_filter[i+j] + input[   i+j]*synthesis_filter[32+i+j];
735   }
736}
737
738void mpeg_audio::scale_and_clamp(const double *input, short *output, int step)
739{
740   for(int i=0; i<32; i++) {
741      double val = input[i]*32768 + 0.5;
742      short cval;
743      if(val <= -32768)
744         cval = -32768;
745      else if(val >= 32767)
746         cval = 32767;
747      else
748         cval = int(val);
749      *output = cval;
750      output += step;
751   }
752}
trunk/src/emu/sound/mpeg_audio.h
r0r19976
1/***************************************************************************
2
3   MPEG audio support.  Only layer2 and variants for now.
4
5***************************************************************************/
6
7#ifndef __MPEG_AUDIO_H__
8#define __MPEG_AUDIO_H__
9
10class mpeg_audio {
11public:
12   // Accepted layers.  Beware that AMM is incompatible with L2 (and
13   // not automatically recognizable) and that 2.5 implies 2.
14
15   enum {
16      L1 = 1,
17      L2 = 2,
18      L2_5 = 4,
19      L3 = 8,
20      AMM = 16
21   };
22
23   // base           = Start of the mpeg data block
24   // accepted       = Binary or of accepted layers
25   // lsb_first      = Read bits out of bytes lsb-first rather than msb first
26   // position_align = Position alignment after reading a block (0 = pure bitstream, must be a power of 2 otherwise)
27
28   mpeg_audio(const void *base, unsigned int accepted, bool lsb_first, int position_align);
29
30   // Decode one mpeg buffer.
31   // pos            = position in *bits* relative to base
32   // limit          = maximum accepted position in bits
33   // output         = output samples, interleaved
34   // output_samples = number of samples written to output per channel
35   // sample_rate    = output sample rate
36   // channels       = number of channels written to output (total sample count is output_samples*channels)
37   //
38   // returns true if the buffer was complete and the new position in pos, false otherwise
39   //
40   // Sample rate and channels can change every buffer.  That's mpeg
41   // for you.  Channels rarely changes, sample rate sometimes do,
42   // especially in amm samples (drops to half at the end).
43   //
44   // One call to output buffer will generate 0 or 1 frame, which is
45   // 384 samples per channel in layer I and 1152 otherwise (up to
46   // 1152 in the amm case, <1152 indicating end of stream).
47
48   bool decode_buffer(int &pos, int limit, short *output,
49                  int &output_samples, int &sample_rate, int &channels);
50   
51
52   // Change the base pointer
53   void set_base(const void *base);
54
55private:
56   struct limit_hit {};
57
58   struct band_info {
59      int modulo;
60      double s1;
61      int bits, cube_bits;
62      int s4, s5;
63      double range, s7, scale, offset;
64   };
65
66   static const double scalefactors[64];
67   static const int sample_rates[8];
68   static const int layer2_param_index[2][4][16];
69   static const int band_parameter_indexed_values[5][32][17];
70   static const int band_parameter_index_bits_count[5][32];
71   static const int joint_band_counts[4], total_band_counts[5];
72   static const band_info band_infos[18];
73   static const double synthesis_filter[512];
74
75   const UINT8 *base;
76   int accepted, position_align;
77
78   int sampling_rate, last_frame_number;
79   int param_index;
80
81   int channel_count, total_bands, joint_bands;
82
83   int band_param[2][32];
84   int scfsi[2][32];
85   int scf[2][3][32];
86   double amp_values[2][3][32];
87   double bdata[2][3][32];
88   double subbuffer[2][32];
89   double audio_buffer[2][32*32];
90   int audio_buffer_pos[2];
91
92   int master_pos;
93
94   int current_pos, current_limit;
95
96   void read_header_amm(bool layer25);
97   void read_header_mpeg2(bool layer25);
98   void read_data_mpeg2();
99   void decode_mpeg2(short *output, int &output_samples);
100
101   int get_band_param(int band);
102   void read_band_params();
103   void read_scfci();
104   void read_band_amplitude_params();
105   void read_band_value_triplet(int chan, int band);
106   void build_amplitudes();
107   void build_next_segments(int step);
108   void retrieve_subbuffer(int step);
109   void handle_block(int &pos);
110   void idct32(const double *input, double *output);
111   void resynthesis(const double *input, double *output);
112   void scale_and_clamp(const double *input, short *output, int step);
113
114
115   static int do_gb_msb(const unsigned char *data, int &pos, int count);
116   static int do_gb_lsb(const unsigned char *data, int &pos, int count);
117
118   int (*do_gb)(const unsigned char *data, int &pos, int count);
119
120   inline int gb(int count)
121   {
122      if(current_pos + count > current_limit)
123         throw limit_hit();
124
125      return do_gb(base, current_pos, count);
126   }
127};
128
129#endif
trunk/src/emu/sound/sound.mak
r19975r19976
752752#-------------------------------------------------
753753
754754ifneq ($(filter YMZ770,$(SOUNDS)),)
755SOUNDOBJS += $(SOUNDOBJ)/ymz770.o
755SOUNDOBJS += $(SOUNDOBJ)/ymz770.o $(SOUNDOBJ)/mpeg_audio.o
756756endif
757757
758758#-------------------------------------------------
trunk/src/emu/sound/ymz770.c
r19975r19976
99
1010#include "emu.h"
1111#include "ymz770.h"
12#include "mpeg_audio.h"
1213
1314// device type definition
1415const device_type YMZ770 = &device_creator<ymz770_device>;
1516
16//**************************************************************************
17//  Yamaha "AMM" decoder
18//**************************************************************************
19
20class amm {
21public:
22   amm();
23
24   void init();
25   bool run();
26
27   void set_pointers(UINT8 *ptr, UINT8 *outptr) { data = ptr; result = outptr; size = rsize = 0; }
28   int get_rsize() { return rsize; }
29
30private:
31   struct band_parameter_size {
32   int band_count;
33   int s1, s2, s3, s4, s5;
34   };
35
36   struct band_info {
37   int modulo;
38   double s1;
39   int bits, cube_bits;
40   int s4, s5;
41   double range, s7, scale, offset;
42   };
43
44   double amplitude_table[64];
45
46   static const int sample_rates[8];
47   static const int band_parameter_indexed_values[5][32][17];
48   static const int band_parameter_index_bits_count[5][32];
49   static const band_parameter_size band_parameter_sizes[5];
50   static const int init_band_counts[4];
51   static const band_info band_infos[18];
52   static const double synthesis_filter[512];
53
54   int sampling_rate, last_frame_number;
55   int param_index, forced_param_index;
56
57   int channel_count, total_bands, init_bands;
58
59   int band_param[2][32];
60   int scfsi[2][32];
61   int scalefactors[2][3][32];
62   double amp_values[2][3][32];
63   double bdata[2][3][32];
64   double subbuffer[2][32];
65   double audio_buffer[2][32*32];
66   int audio_buffer_pos[2];
67
68   int master_pos;
69
70   void read_header(int &pos);
71   int get_band_param(int &pos, int band);
72   void read_band_params(int &pos);
73   void read_scfci(int &pos);
74   void read_band_amplitude_params(int &pos);
75   void read_band_value_triplet(int &pos, int chan, int band);
76   void build_amplitudes();
77   void build_next_segments(int &pos, int step);
78   void retrieve_subbuffer(int step);
79   void handle_block(int &pos);
80   void idct32(const double *input, double *output);
81   void resynthesis(const double *input, double *output);
82   void scale_and_clamp(const double *input, int offset, int step);
83
84   UINT8 *data;
85   int size;
86
87   UINT8 *result;
88   int rsize;
89
90   int gb(int &pos, int count)
91   {
92      int v = 0;
93      for(int i=0; i != count; i++) {
94         v <<= 1;
95         if(data[pos >> 3] & (0x80 >> (pos & 7)))
96            v |= 1;
97         pos++;
98      }
99      return v;
100   }
101
102   void w16(int offset, unsigned short value)
103   {
104      if (offset > (0x8fe*2))
105      {
106         fatalerror("AMM block decoded to %x bytes, buffer overflow!\n", offset);
107      }
108
109      *(unsigned short *)(result+offset) = value;
110   }
111};
112
113void amm::read_header(int &pos)
114{
115  int full_rate = gb(pos, 1);
116  gb(pos, 2); // must be 2
117  gb(pos, 1); // unused
118  int full_packets_count = gb(pos, 4); // max 12
119  int srate_index = gb(pos, 2); // max 2
120  sampling_rate = srate_index + 4 * (1 - full_rate);
121  int last_packet_frame_id = gb(pos, 2); // max 2
122  last_frame_number = 3*full_packets_count + last_packet_frame_id;
123  int frame_type = gb(pos, 2);
124  int init_band_count_index = gb(pos, 2);
125  int normal_param_index = gb(pos, 3);
126  gb(pos, 1); // must be zero
127  param_index = forced_param_index >= 5 ? normal_param_index : forced_param_index; // max 4
128  channel_count = frame_type != 3 ? 2 : 1;
129  total_bands = band_parameter_sizes[param_index].band_count;
130  init_bands = total_bands;
131  if(frame_type == 1)
132    init_bands = init_band_counts[init_band_count_index];
133  if(init_bands > total_bands )
134    init_bands = total_bands;
135}
136
137const int amm::sample_rates[8] = { 44100, 48000, 32000, 0, 22050, 24000, 16000, 0 };
138
139const int amm::band_parameter_indexed_values[5][32][17] = {
140  {
141    {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
142    {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
143    {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
144    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
145    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
146    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
147    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
148    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
149    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
150    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
151    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
152    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
153    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
154    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
155    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
156    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
157    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
158    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
159    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
160    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
161    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
162    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
163    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
164    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
165    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
166    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
167    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
168    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
169    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
170    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
171    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
172    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
173  },
174  {
175    {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
176    {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
177    {  0,  1,  3,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1, },
178    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
179    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
180    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
181    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
182    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
183    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
184    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
185    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 17, -1, },
186    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
187    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
188    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
189    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
190    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
191    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
192    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
193    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
194    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
195    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
196    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
197    {  0,  1,  2,  3,  4,  5,  6, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
198    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
199    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
200    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
201    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
202    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
203    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
204    {  0,  1,  2, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
205    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
206    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
207  },
208  {
209    {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
210    {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
211    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
212    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
213    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
214    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
215    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
216    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
217    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
218    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
219    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
220    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
221    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
222    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
223    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
224    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
225    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
226    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
227    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
228    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
229    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
230    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
231    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
232    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
233    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
234    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
235    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
236    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
237    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
238    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
239    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
240    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
241  },
242  {
243    {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
244    {  0,  1,  2,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, -1, },
245    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
246    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
247    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
248    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
249    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
250    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
251    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
252    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
253    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
254    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
255    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
256    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
257    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
258    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
259    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
260    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
261    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
262    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
263    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
264    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
265    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
266    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
267    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
268    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
269    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
270    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
271    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
272    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
273    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
274    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
275  },
276  {
277    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
278    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
279    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
280    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, -1, },
281    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
282    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
283    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
284    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
285    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
286    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
287    {  0,  1,  2,  4,  5,  6,  7,  8, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
288    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
289    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
290    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
291    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
292    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
293    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
294    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
295    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
296    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
297    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
298    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
299    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
300    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
301    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
302    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
303    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
304    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
305    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
306    {  0,  1,  2,  4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
307    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
308    {  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
309  }
310};
311
312const int amm::band_parameter_index_bits_count[5][32] = {
313  { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, },
314  { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 0, 0, },
315  { 4, 4, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316  { 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
317  { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, },
318};
319
320const amm::band_parameter_size amm::band_parameter_sizes[5] = {
321  { 27,  88, 104, 120, 135, 147 },
322  { 30,  94, 110, 126, 141, 153 },
323  {  8,  26,  40,  52,  52,  52 },
324  { 12,  38,  52,  64,  76,  76 },
325  { 30,  75,  91, 103, 114, 122 },
326};
327
328const int amm::init_band_counts[4] = { 4, 8, 12, 16 };
329
330const amm::band_info amm::band_infos[18] = {
331  { 0x0000,  0.00,  0,  0, 0,  0,           0,          0,                 0,         0 },
332  { 0x0003,  7.00,  2,  5, 3,  9, 1-1.0/    4, -1.0/    4,   1/(1-1.0/    4), 1.0/    2 },
333  { 0x0005, 11.00,  3,  7, 5, 25, 1-3.0/    8, -3.0/    8,   1/(1-3.0/    8), 1.0/    2 },
334  { 0x0007, 16.00,  3,  9, 0,  0, 1-1.0/    8, -1.0/    8,   1/(1-1.0/    8), 1.0/    4 },
335  { 0x0009, 20.84,  4, 10, 9, 81, 1-7.0/   16, -7.0/   16,   1/(1-7.0/   16), 1.0/    2 },
336  { 0x000f, 25.28,  4, 12, 0,  0, 1-1.0/   16, -1.0/   16,   1/(1-1.0/   16), 1.0/    8 },
337  { 0x001f, 31.59,  5, 15, 0,  0, 1-1.0/   32, -1.0/   32,   1/(1-1.0/   32), 1.0/   16 },
338  { 0x003f, 37.75,  6, 18, 0,  0, 1-1.0/   64, -1.0/   64,   1/(1-1.0/   64), 1.0/   32 },
339  { 0x007f, 43.84,  7, 21, 0,  0, 1-1.0/  128, -1.0/  128,   1/(1-1.0/  128), 1.0/   64 },
340  { 0x00ff, 49.89,  8, 24, 0,  0, 1-1.0/  256, -1.0/  256,   1/(1-1.0/  256), 1.0/  128 },
341  { 0x01ff, 55.93,  9, 27, 0,  0, 1-1.0/  512, -1.0/  512,   1/(1-1.0/  512), 1.0/  256 },
342  { 0x03ff, 61.96, 10, 30, 0,  0, 1-1.0/ 1024, -1.0/ 1024,   1/(1-1.0/ 1024), 1.0/  512 },
343  { 0x07ff, 67.98, 11, 33, 0,  0, 1-1.0/ 2048, -1.0/ 2048,   1/(1-1.0/ 2048), 1.0/ 1024 },
344  { 0x0fff, 74.01, 12, 36, 0,  0, 1-1.0/ 4096, -1.0/ 4096,   1/(1-1.0/ 4096), 1.0/ 2048 },
345  { 0x1fff, 80.03, 13, 39, 0,  0, 1-1.0/ 8192, -1.0/ 8192,   1/(1-1.0/ 8192), 1.0/ 4096 },
346  { 0x3fff, 86.05, 14, 42, 0,  0, 1-1.0/16384, -1.0/16384,   1/(1-1.0/16384), 1.0/ 8192 },
347  { 0x7fff, 92.01, 15, 45, 0,  0, 1-1.0/32768, -1.0/32768,   1/(1-1.0/32768), 1.0/16384 },
348  { 0xffff, 98.01, 16, 48, 0,  0, 1-1.0/65536, -1.0/65536,   1/(1-1.0/65536), 1.0/32768 },
349};
350
351const double amm::synthesis_filter[512] = {
352  +0.000000000, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000015259, -0.000030518,
353  -0.000030518, -0.000030518, -0.000030518, -0.000045776, -0.000045776, -0.000061035, -0.000061035, -0.000076294,
354  -0.000076294, -0.000091553, -0.000106812, -0.000106812, -0.000122070, -0.000137329, -0.000152588, -0.000167847,
355  -0.000198364, -0.000213623, -0.000244141, -0.000259399, -0.000289917, -0.000320435, -0.000366211, -0.000396729,
356  -0.000442505, -0.000473022, -0.000534058, -0.000579834, -0.000625610, -0.000686646, -0.000747681, -0.000808716,
357  -0.000885010, -0.000961304, -0.001037598, -0.001113892, -0.001205444, -0.001296997, -0.001388550, -0.001480103,
358  -0.001586914, -0.001693726, -0.001785278, -0.001907349, -0.002014160, -0.002120972, -0.002243042, -0.002349854,
359  -0.002456665, -0.002578735, -0.002685547, -0.002792358, -0.002899170, -0.002990723, -0.003082275, -0.003173828,
360  +0.003250122, +0.003326416, +0.003387451, +0.003433228, +0.003463745, +0.003479004, +0.003479004, +0.003463745,
361  +0.003417969, +0.003372192, +0.003280640, +0.003173828, +0.003051758, +0.002883911, +0.002700806, +0.002487183,
362  +0.002227783, +0.001937866, +0.001617432, +0.001266479, +0.000869751, +0.000442505, -0.000030518, -0.000549316,
363  -0.001098633, -0.001693726, -0.002334595, -0.003005981, -0.003723145, -0.004486084, -0.005294800, -0.006118774,
364  -0.007003784, -0.007919312, -0.008865356, -0.009841919, -0.010848999, -0.011886597, -0.012939453, -0.014022827,
365  -0.015121460, -0.016235352, -0.017349243, -0.018463135, -0.019577026, -0.020690918, -0.021789550, -0.022857666,
366  -0.023910522, -0.024932861, -0.025909424, -0.026840210, -0.027725220, -0.028533936, -0.029281616, -0.029937744,
367  -0.030532837, -0.031005860, -0.031387330, -0.031661987, -0.031814575, -0.031845093, -0.031738280, -0.031478880,
368  +0.031082153, +0.030517578, +0.029785156, +0.028884888, +0.027801514, +0.026535034, +0.025085450, +0.023422241,
369  +0.021575928, +0.019531250, +0.017257690, +0.014801025, +0.012115479, +0.009231567, +0.006134033, +0.002822876,
370  -0.000686646, -0.004394531, -0.008316040, -0.012420654, -0.016708374, -0.021179200, -0.025817871, -0.030609130,
371  -0.035552980, -0.040634155, -0.045837402, -0.051132202, -0.056533813, -0.061996460, -0.067520140, -0.073059080,
372  -0.078628540, -0.084182740, -0.089706420, -0.095169070, -0.100540160, -0.105819700, -0.110946655, -0.115921020,
373  -0.120697020, -0.125259400, -0.129562380, -0.133590700, -0.137298580, -0.140670780, -0.143676760, -0.146255500,
374  -0.148422240, -0.150115970, -0.151306150, -0.151962280, -0.152069090, -0.151596070, -0.150497440, -0.148773200,
375  -0.146362300, -0.143264770, -0.139450070, -0.134887700, -0.129577640, -0.123474120, -0.116577150, -0.108856200,
376  +0.100311280, +0.090927124, +0.080688480, +0.069595340, +0.057617188, +0.044784546, +0.031082153, +0.016510010,
377  +0.001068115, -0.015228271, -0.032379150, -0.050354004, -0.069168090, -0.088775635, -0.109161380, -0.130310060,
378  -0.152206420, -0.174789430, -0.198059080, -0.221984860, -0.246505740, -0.271591200, -0.297210700, -0.323318480,
379  -0.349868770, -0.376800540, -0.404083250, -0.431655880, -0.459472660, -0.487472530, -0.515609740, -0.543823240,
380  -0.572036740, -0.600219700, -0.628295900, -0.656219500, -0.683914200, -0.711318970, -0.738372800, -0.765029900,
381  -0.791214000, -0.816864000, -0.841949460, -0.866363500, -0.890090940, -0.913055400, -0.935195900, -0.956481930,
382  -0.976852400, -0.996246340, -1.014617900, -1.031936600, -1.048156700, -1.063217200, -1.077117900, -1.089782700,
383  -1.101211500, -1.111373900, -1.120224000, -1.127746600, -1.133926400, -1.138763400, -1.142211900, -1.144287100,
384  +1.144989000, +1.144287100, +1.142211900, +1.138763400, +1.133926400, +1.127746600, +1.120224000, +1.111373900,
385  +1.101211500, +1.089782700, +1.077117900, +1.063217200, +1.048156700, +1.031936600, +1.014617900, +0.996246340,
386  +0.976852400, +0.956481930, +0.935195900, +0.913055400, +0.890090940, +0.866363500, +0.841949460, +0.816864000,
387  +0.791214000, +0.765029900, +0.738372800, +0.711318970, +0.683914200, +0.656219500, +0.628295900, +0.600219700,
388  +0.572036740, +0.543823240, +0.515609740, +0.487472530, +0.459472660, +0.431655880, +0.404083250, +0.376800540,
389  +0.349868770, +0.323318480, +0.297210700, +0.271591200, +0.246505740, +0.221984860, +0.198059080, +0.174789430,
390  +0.152206420, +0.130310060, +0.109161380, +0.088775635, +0.069168090, +0.050354004, +0.032379150, +0.015228271,
391  -0.001068115, -0.016510010, -0.031082153, -0.044784546, -0.057617188, -0.069595340, -0.080688480, -0.090927124,
392  +0.100311280, +0.108856200, +0.116577150, +0.123474120, +0.129577640, +0.134887700, +0.139450070, +0.143264770,
393  +0.146362300, +0.148773200, +0.150497440, +0.151596070, +0.152069090, +0.151962280, +0.151306150, +0.150115970,
394  +0.148422240, +0.146255500, +0.143676760, +0.140670780, +0.137298580, +0.133590700, +0.129562380, +0.125259400,
395  +0.120697020, +0.115921020, +0.110946655, +0.105819700, +0.100540160, +0.095169070, +0.089706420, +0.084182740,
396  +0.078628540, +0.073059080, +0.067520140, +0.061996460, +0.056533813, +0.051132202, +0.045837402, +0.040634155,
397  +0.035552980, +0.030609130, +0.025817871, +0.021179200, +0.016708374, +0.012420654, +0.008316040, +0.004394531,
398  +0.000686646, -0.002822876, -0.006134033, -0.009231567, -0.012115479, -0.014801025, -0.017257690, -0.019531250,
399  -0.021575928, -0.023422241, -0.025085450, -0.026535034, -0.027801514, -0.028884888, -0.029785156, -0.030517578,
400  +0.031082153, +0.031478880, +0.031738280, +0.031845093, +0.031814575, +0.031661987, +0.031387330, +0.031005860,
401  +0.030532837, +0.029937744, +0.029281616, +0.028533936, +0.027725220, +0.026840210, +0.025909424, +0.024932861,
402  +0.023910522, +0.022857666, +0.021789550, +0.020690918, +0.019577026, +0.018463135, +0.017349243, +0.016235352,
403  +0.015121460, +0.014022827, +0.012939453, +0.011886597, +0.010848999, +0.009841919, +0.008865356, +0.007919312,
404  +0.007003784, +0.006118774, +0.005294800, +0.004486084, +0.003723145, +0.003005981, +0.002334595, +0.001693726,
405  +0.001098633, +0.000549316, +0.000030518, -0.000442505, -0.000869751, -0.001266479, -0.001617432, -0.001937866,
406  -0.002227783, -0.002487183, -0.002700806, -0.002883911, -0.003051758, -0.003173828, -0.003280640, -0.003372192,
407  -0.003417969, -0.003463745, -0.003479004, -0.003479004, -0.003463745, -0.003433228, -0.003387451, -0.003326416,
408  +0.003250122, +0.003173828, +0.003082275, +0.002990723, +0.002899170, +0.002792358, +0.002685547, +0.002578735,
409  +0.002456665, +0.002349854, +0.002243042, +0.002120972, +0.002014160, +0.001907349, +0.001785278, +0.001693726,
410  +0.001586914, +0.001480103, +0.001388550, +0.001296997, +0.001205444, +0.001113892, +0.001037598, +0.000961304,
411  +0.000885010, +0.000808716, +0.000747681, +0.000686646, +0.000625610, +0.000579834, +0.000534058, +0.000473022,
412  +0.000442505, +0.000396729, +0.000366211, +0.000320435, +0.000289917, +0.000259399, +0.000244141, +0.000213623,
413  +0.000198364, +0.000167847, +0.000152588, +0.000137329, +0.000122070, +0.000106812, +0.000106812, +0.000091553,
414  +0.000076294, +0.000076294, +0.000061035, +0.000061035, +0.000045776, +0.000045776, +0.000030518, +0.000030518,
415  +0.000030518, +0.000030518, +0.000015259, +0.000015259, +0.000015259, +0.000015259, +0.000015259, +0.000015259,
416};
417
418int amm::get_band_param(int &pos, int band)
419{
420  int bit_count = band_parameter_index_bits_count[param_index][band];
421  int index = gb(pos, bit_count);
422  return band_parameter_indexed_values[param_index][band][index];
423}
424
425void amm::read_band_params(int &pos)
426{
427  int band = 0;
428
429  while(band < init_bands) {
430    for(int chan=0; chan < channel_count; chan++)
431      band_param[chan][band] = get_band_param(pos, band);
432    band++;
433  }
434
435  while(band < total_bands) {
436    int val = get_band_param(pos, band);
437    band_param[0][band] = val;
438    band_param[1][band] = val;
439    band++;
440  }
441
442  while(band < 32) {
443    band_param[0][band] = 0;
444    band_param[1][band] = 0;
445    band++;
446  }
447}
448
449void amm::read_scfci(int &pos)
450{
451  memset(scfsi, 0, sizeof(scfsi));
452  for(int band=0; band < total_bands; band++)
453    for(int chan=0; chan < channel_count; chan++)
454      if(band_param[chan][band])
455   scfsi[chan][band] = gb(pos, 2);
456}
457
458void amm::read_band_amplitude_params(int &pos)
459{
460  memset(scalefactors, 0, sizeof(scalefactors));
461  for(int band=0; band < total_bands; band++)
462    for(int chan=0; chan<channel_count; chan++)
463   if(band_param[chan][band]) {
464     switch(scfsi[chan][band]) {
465     case 0:
466       scalefactors[chan][0][band] = gb(pos, 6);
467       scalefactors[chan][1][band] = gb(pos, 6);
468       scalefactors[chan][2][band] = gb(pos, 6);
469       break;
470
471     case 1: {
472       int val = gb(pos, 6);
473       scalefactors[chan][0][band] = val;
474       scalefactors[chan][1][band] = val;
475       scalefactors[chan][2][band] = gb(pos, 6);
476       break;
477     }
478
479     case 2: {
480       int val = gb(pos, 6);
481       scalefactors[chan][0][band] = val;
482       scalefactors[chan][1][band] = val;
483       scalefactors[chan][2][band] = val;
484       break;
485     }
486
487     case 3: {
488       scalefactors[chan][0][band] = gb(pos, 6);
489       int val = gb(pos, 6);
490       scalefactors[chan][1][band] = val;
491       scalefactors[chan][2][band] = val;
492       break;
493     }
494     }
495   }
496}
497
498void amm::build_amplitudes()
499{
500  memset(amp_values, 0, sizeof(amp_values));
501
502  for(int band=0; band < total_bands; band++)
503    for(int chan=0; chan<channel_count; chan++)
504      if(band_param[chan][band])
505   for(int step=0; step<3; step++)
506     amp_values[chan][step][band] = amplitude_table[scalefactors[chan][step][band]];
507}
508
509void amm::read_band_value_triplet(int &pos, int chan, int band)
510{
511  double buffer[3];
512
513  int band_idx = band_param[chan][band];
514  switch(band_idx) {
515  case 0:
516    bdata[chan][0][band] = 0;
517    bdata[chan][1][band] = 0;
518    bdata[chan][2][band] = 0;
519    return;
520
521  case 1:
522  case 2:
523  case 4: {
524    int modulo = band_infos[band_idx].modulo;
525    int val  = gb(pos, band_infos[band_idx].cube_bits);
526    buffer[0] = val % modulo;
527    val = val / modulo;
528    buffer[1] = val % modulo;
529    val = val / modulo;
530    buffer[2] = val % modulo;
531    break;
532  }
533
534  default: {
535    int bits = band_infos[band_idx].bits;
536    buffer[0] = gb(pos, bits);
537    buffer[1] = gb(pos, bits);
538    buffer[2] = gb(pos, bits);
539    break;
540  }
541  }
542
543  double scale = 1 << (band_infos[band_idx].bits - 1);
544
545  bdata[chan][0][band] = ((buffer[0] - scale) / scale + band_infos[band_idx].offset) * band_infos[band_idx].scale;
546  bdata[chan][1][band] = ((buffer[1] - scale) / scale + band_infos[band_idx].offset) * band_infos[band_idx].scale;
547  bdata[chan][2][band] = ((buffer[2] - scale) / scale + band_infos[band_idx].offset) * band_infos[band_idx].scale;
548}
549
550void amm::build_next_segments(int &pos, int step)
551{
552  int band = 0;
553  while(band < init_bands) {
554    for(int chan=0; chan<channel_count; chan++) {
555      read_band_value_triplet(pos, chan, band);
556      double amp = amp_values[chan][step][band];
557      bdata[chan][0][band] *= amp;
558      bdata[chan][1][band] *= amp;
559      bdata[chan][2][band] *= amp;
560    }
561    band++;
562  }
563
564  while(band < init_bands) {
565    read_band_value_triplet(pos, 0, band);
566    bdata[1][0][band] = bdata[0][0][band];
567    bdata[1][1][band] = bdata[0][1][band];
568    bdata[1][2][band] = bdata[0][2][band];
569
570    for(int chan=0; chan<channel_count; chan++) {
571      double amp = amp_values[chan][step][band];
572      bdata[chan][0][band] *= amp;
573      bdata[chan][1][band] *= amp;
574      bdata[chan][2][band] *= amp;
575    }
576    band++;
577  }
578
579  while(band < 32) {
580    bdata[0][0][band] = 0;
581    bdata[0][1][band] = 0;
582    bdata[0][2][band] = 0;
583    bdata[1][0][band] = 0;
584    bdata[1][1][band] = 0;
585    bdata[1][2][band] = 0;
586    band++;
587  }
588}
589
590void amm::retrieve_subbuffer(int step)
591{
592  for(int chan=0; chan<channel_count; chan++)
593    memcpy(subbuffer[chan], bdata[chan][step], 32*sizeof(subbuffer[0][0]));
594}
595
596void amm::idct32(const double *input, double *output)
597{
598  // Simplest idct32 ever, non-fast at all
599  for(int i=0; i<32; i++) {
600    double s = 0;
601    for(int j=0; j<32; j++)
602      s += input[j] * cos(i*(2*j+1)*M_PI/64);
603    output[i] = s;
604  }
605}
606
607void amm::resynthesis(const double *input, double *output)
608{
609  memset(output, 0, 32*sizeof(output[0]));
610  for(int j=0; j<64*8; j+=64) {
611    for(int i=0; i<16; i++) {
612      output[   i] += input[   i+j]*synthesis_filter[   i+j] - input[32-i+j]*synthesis_filter[32+i+j];
613    }
614    output[16] -= input[16+j]*synthesis_filter[32+16+j];
615   for(int i=17; i<32; i++) {
616      output[i] -= input[32-i+j]*synthesis_filter[i+j] + input[i+j]*synthesis_filter[32+i+j];
617   }
618  }
619}
620
621void amm::scale_and_clamp(const double *input, int offset, int step)
622{
623  for(int i=0; i<32; i++) {
624    double val = input[i]*32768 + 0.5;
625    short cval;
626    if(val <= -32768)
627      cval = -32768;
628    else if(val >= 32767)
629      cval = 32767;
630    else
631      cval = int(val);
632    w16(offset, cval);
633    offset += step;
634  }
635}
636
637amm::amm()
638{
639  forced_param_index = 5;
640
641  for(int i=0; i<63; i++)
642    amplitude_table[i] = pow(2, (3-i)/3.0);
643  amplitude_table[63] = 1e-20;
644
645  memset(audio_buffer, 0, sizeof(audio_buffer));
646  audio_buffer_pos[0] = 16*32;
647  audio_buffer_pos[1] = 16*32;
648}
649
650void amm::handle_block(int &pos)
651{
652  gb(pos, 12); // Must be 0xfff
653//  printf("sync: %03x\n", h);
654  read_header(pos);
655//  printf("sample rate: %d\n", sample_rates[sampling_rate]);
656  read_band_params(pos);
657  read_scfci(pos);
658  read_band_amplitude_params(pos);
659  build_amplitudes();
660
661  // Supposed to stop at last_frame_number when it's not 12*3+2 = 38
662  for(int upper_step = 0; upper_step<3; upper_step++)
663    for(int middle_step = 0; middle_step < 4; middle_step++) {
664      build_next_segments(pos, upper_step);
665      for(int lower_step = 0; lower_step < 3; lower_step++) {
666   retrieve_subbuffer(lower_step);
667
668   int base_offset = rsize;
669   for(int chan=0; chan<channel_count; chan++) {
670     double resynthesis_buffer[32];
671     idct32(subbuffer[chan], audio_buffer[chan] + audio_buffer_pos[chan]);
672     resynthesis(audio_buffer[chan] + audio_buffer_pos[chan] + 16, resynthesis_buffer);
673     scale_and_clamp(resynthesis_buffer, base_offset+2*chan, 2*channel_count);
674     audio_buffer_pos[chan] -= 32;
675     if(audio_buffer_pos[chan]<0) {
676       memmove(audio_buffer[chan]+17*32, audio_buffer[chan], 15*32*sizeof(audio_buffer[chan][0]));
677       audio_buffer_pos[chan] = 16*32;
678     }
679   }
680   rsize += 32*2*channel_count;
681      }
682    }
683  pos = (pos+7) & ~7;
684}
685
686void amm::init()
687{
688   master_pos = 0;
689}
690
691// returns true if this is the last block
692bool amm::run()
693{
694   rsize = 0;
695   handle_block(master_pos);
696
697   // "last_frame_number" for the current chunk is 36 means there are more segments, otherwise not
698   if (last_frame_number == 36)
699   {
700      return false;
701   }
702
703   return true;
704}
705
706
707//**************************************************************************
708//  LIVE DEVICE
709//**************************************************************************
710
71117//-------------------------------------------------
71218//  ymz770_device - constructor
71319//-------------------------------------------------
r19975r19976
72531{
72632   // create the stream
72733   m_stream = machine().sound().stream_alloc(*this, 0, 2, 16000, this);
34   rom_base = device().machine().root_device().memregion(":ymz770")->base();
35   rom_size = device().machine().root_device().memregion(":ymz770")->bytes() * 8;
72836
72937   for (int i = 0; i < 8; i++)
73038   {
73139      channels[i].is_playing = false;
73240      channels[i].is_seq_playing = false;
733      channels[i].decoder = new amm;
41      channels[i].decoder = new mpeg_audio(rom_base, mpeg_audio::AMM, false, 0);
73442   }
73543
736   rom_base = device().machine().root_device().memregion(":ymz770")->base();
73744
73845   save_item(NAME(cur_reg));
73946   for (int i = 0; i < 8; i++)
r19975r19976
74653      save_item(NAME(channels[i].last_block), i);
74754      save_item(NAME(channels[i].output_remaining), i);
74855      save_item(NAME(channels[i].output_ptr), i);
56      save_item(NAME(channels[i].pptr), i);
74957      save_item(NAME(channels[i].sequence), i);
75058      save_item(NAME(channels[i].seqcontrol), i);
75159      save_item(NAME(channels[i].seqdelay), i);
r19975r19976
839147            }
840148            else
841149            {
150            retry:
842151               if (channels[ch].last_block)
843152               {
844153                  if (channels[ch].control & 1)
845154                  {
846155                        UINT8 phrase = channels[ch].phrase;
847                        UINT32 pptr = rom_base[(4*phrase)+1]<<16 | rom_base[(4*phrase)+2]<<8 | rom_base[(4*phrase)+3];
848
849                        channels[ch].decoder->set_pointers(&rom_base[pptr], (UINT8 *)&channels[ch].output_data[0]);
850                        channels[ch].decoder->init();
156                        channels[ch].pptr = 8*(rom_base[(4*phrase)+1]<<16 | rom_base[(4*phrase)+2]<<8 | rom_base[(4*phrase)+3]);
851157                  }
852158                  else
853159                  {
r19975r19976
857163
858164               if (channels[ch].is_playing)
859165               {
860                  channels[ch].last_block = channels[ch].decoder->run();
861                  channels[ch].output_remaining = (channels[ch].decoder->get_rsize()/2)-1;
166                  int sample_rate, channel_count;
167                  if(!channels[ch].decoder->decode_buffer(channels[ch].pptr,
168                                                rom_size,
169                                                channels[ch].output_data,
170                                                channels[ch].output_remaining,
171                                                sample_rate,
172                                                channel_count))
173                  {
174                     channels[ch].last_block = true;
175                     goto retry;
176                  }
177
178                  channels[ch].last_block = channels[ch].output_remaining < 1152;
179                  channels[ch].output_remaining--;
862180                  channels[ch].output_ptr = 1;
863181
864182                  mix += (channels[ch].output_data[0]*2*channels[ch].volume);
r19975r19976
913231            if (data & 6)
914232            {
915233               UINT8 phrase = channels[voice].phrase;
916               UINT32 pptr = rom_base[(4*phrase)+1]<<16 | rom_base[(4*phrase)+2]<<8 | rom_base[(4*phrase)+3];
917
918               channels[voice].decoder->set_pointers(&rom_base[pptr], (UINT8 *)&channels[voice].output_data[0]);
919               channels[voice].decoder->init();
234               channels[voice].pptr = 8*(rom_base[(4*phrase)+1]<<16 | rom_base[(4*phrase)+2]<<8 | rom_base[(4*phrase)+3]);
920235               channels[voice].output_remaining = 0;
921236               channels[voice].output_ptr = 0;
922237               channels[voice].last_block = false;
trunk/src/emu/sound/ymz770.h
r19975r19976
2828//**************************************************************************
2929
3030// forward definition
31class amm;
31class mpeg_audio;
3232
3333// ======================> ymz770_device
3434
r19975r19976
4343
4444        bool is_playing, last_block;
4545
46        amm *decoder;
46        mpeg_audio *decoder;
4747
48        INT16 output_data[0x8fe];
48        INT16 output_data[1152];
4949        int output_remaining;
5050        int output_ptr;
51      int pptr;
5152
5253       UINT8 sequence;
5354       UINT8 seqcontrol;
r19975r19976
8081    // data
8182    UINT8 cur_reg;
8283    UINT8 *rom_base;
84   int rom_size;
8385
8486    ymz_channel channels[8];
8587};
trunk/src/mame/drivers/model1.c
r19975r19976
867867   m_fifo_wptr++;
868868   if (m_fifo_wptr >= ARRAY_LENGTH(m_to_68k)) m_fifo_wptr = 0;
869869
870   if (data == 0xae)
871   {
872      m_snd_cmd_state = 0;
873   }
874
870875    if (m_dsbz80 != NULL)
871876    {
872        m_dsbz80->latch_w(space, 0, data);
877//      printf("%d: %02x (last %02x)\n", m_snd_cmd_state, data, m_last_snd_cmd);
878      // HACK: on h/w, who filters out commands the DSB shouldn't see?  Need a wiring diagram.
879      if ((m_snd_cmd_state == 2) && (m_last_snd_cmd == 0x50))
880      {
881         m_dsbz80->latch_w(space, 0, data);
882      }
883      else   // keep in sync but send a "don't care"
884      {
885         m_dsbz80->latch_w(space, 0, 0x70);
886      }
873887    }
874888
889   m_last_snd_cmd = data;
890   m_snd_cmd_state++;
891
875892   // signal the 68000 that there's data waiting
876893   machine().device("audiocpu")->execute().set_input_line(2, HOLD_LINE);
877894   // give the 68k time to reply
r19975r19976
13561373    ROM_REGION( 0x20000, "mpegcpu", 0 ) /* Z80 DSB code */
13571374    ROM_LOAD( "epr-16471.bin", 0x000000, 0x020000, CRC(f4ee84a4) SHA1(f12b214e6f195b0e5f49ba9f41d8e54bfcea9acc) )
13581375
1359    ROM_REGION( 0x400000, "ymz770", 0 ) /* DSB MPEG data */
1376    ROM_REGION( 0x400000, "mpeg", 0 ) /* DSB MPEG data */
13601377    ROM_LOAD( "mpr-16514.bin", 0x000000, 0x200000, CRC(3175b0be) SHA1(63649d053c8c17ce1746d16d0cc8202be20c302f) )
13611378    ROM_LOAD( "mpr-16515.bin", 0x200000, 0x200000, CRC(3114d748) SHA1(9ef090623cdd2a1d06b5d1bc4b9a07ab4eff5b76) )
13621379
r19975r19976
15641581
15651582static MACHINE_CONFIG_DERIVED(swa, model1)
15661583    MCFG_DSBZ80_ADD(DSBZ80_TAG)
1584   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
1585   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
15671586MACHINE_CONFIG_END
15681587
15691588static MACHINE_CONFIG_START( model1_vr, model1_state )
trunk/src/mame/audio/dsbz80.c
r19975r19976
3030
3131
3232MACHINE_CONFIG_FRAGMENT( dsbz80 )
33    MCFG_CPU_ADD(Z80_TAG, Z80, 1000000)     /* unknown clock, but probably pretty slow considering the z80 does like nothing */
33    MCFG_CPU_ADD(Z80_TAG, Z80, 4000000)     /* unknown clock, but probably pretty slow considering the z80 does like nothing */
3434   MCFG_CPU_PROGRAM_MAP(dsbz80_map)
3535    MCFG_CPU_IO_MAP(dsbz80io_map)
36#if 0
37    MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
38    MCFG_YMZ770_ADD(YMZ770_TAG, 8000000)    /* clock ignored for this */
39   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
40   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
41#endif
4236MACHINE_CONFIG_END
4337
4438//**************************************************************************
r19975r19976
6862
6963dsbz80_device::dsbz80_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
7064    device_t(mconfig, DSBZ80, "Sega Z80-based Digital Sound Board", tag, owner, clock),
71   m_ourcpu(*this, Z80_TAG),
72   m_ymz770(*this, YMZ770_TAG)
65   device_sound_interface(mconfig, *this),
66   m_ourcpu(*this, Z80_TAG)
7367{
7468}
7569
r19975r19976
7973
8074void dsbz80_device::device_start()
8175{
76   UINT8 *rom_base = machine().root_device().memregion("mpeg")->base();
77   decoder = new mpeg_audio(rom_base, mpeg_audio::L2, false, 0);
78   machine().sound().stream_alloc(*this, 0, 2, 32000, this);
8279}
8380
8481//-------------------------------------------------
r19975r19976
9087   m_dsb_latch = 0;
9188   status = 1;
9289    start = end = 0;
90   audio_pos = audio_avail = 0;
91   memset(audio_buf, 0, sizeof(audio_buf));
92   mp_state = 0;
9393}
9494
9595WRITE8_MEMBER(dsbz80_device::latch_w)
r19975r19976
9797   m_ourcpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
9898    m_dsb_latch = data;
9999    status |= 2;
100//    printf("%02x to DSB latch\n", data);
100//   printf("%02x to DSB latch\n", data);
101101}
102102
103103READ8_MEMBER(dsbz80_device::latch_r)
104104{
105105   m_ourcpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
106//    printf("DSB Z80 read %02x\n", m_dsb_latch);
106//   printf("DSB Z80 read %02x\n", m_dsb_latch);
107107   status &= ~2;
108108    return m_dsb_latch;
109109}
r19975r19976
114114
115115   if (data == 0)   // stop
116116   {
117//      MPEG_Stop_Playing();
118//        printf("MPEG stop\n");
117      mp_state = 0;
118      audio_pos = audio_avail = 0;
119119   }
120120   else if (data == 1)   // play without loop
121121   {
122//      MPEG_Set_Loop(NULL, 0);
123//      MPEG_Play_Memory(ROM + mp_start, mp_end-mp_start);
124//        printf("MPEG start, one-shot from %x\n", mp_start);
122      mp_pos = mp_start*8;
125123   }
126124   else if (data == 2)   // play with loop
127125   {
128//      MPEG_Play_Memory(ROM + mp_start, mp_end-mp_start);
129//        printf("MPEG start, loop from %x\n", mp_start);
126      mp_pos = mp_start*8;
130127   }
131128}
132129
133130READ8_MEMBER(dsbz80_device::mpeg_pos_r)
134131{
135   int mp_prg = 0; //MPEG_Get_Progress();  // returns the byte offset currently playing
132   int mp_prg = mp_pos >> 3;
136133
137   mp_prg += mp_start;
138
139134   switch (offset)
140135   {
141136      case 0:
r19975r19976
153148   get latched.  When the current stream ends, the MPEG hardware starts playing
154149   immediately from the latched start and end position.  In this way, the Z80
155150   enforces looping where appropriate and multi-part songs in other cases
156   (song #16 is a good example)
151   (song #16 is a good example)
157152*/
158153
159154WRITE8_MEMBER(dsbz80_device::mpeg_start_w)
r19975r19976
182177            // SWA: if loop end is zero, it means "keep previous end marker"
183178            if (lp_end == 0)
184179            {
185//                  MPEG_Set_Loop(ROM + lp_start, mp_end-lp_start);
180//               MPEG_Set_Loop(ROM + lp_start, mp_end-lp_start);
186181            }
187182            else
188183            {
189//                  MPEG_Set_Loop(ROM + lp_start, lp_end-lp_start);
184//               MPEG_Set_Loop(ROM + lp_start, lp_end-lp_start);
190185            }
191186         }
192187         break;
r19975r19976
216211         else
217212         {
218213            lp_end = end;
219//              MPEG_Set_Loop(ROM + lp_start, lp_end-lp_start);
214//            MPEG_Set_Loop(ROM + lp_start, lp_end-lp_start);
220215         }
221216         break;
222217   }
r19975r19976
229224
230225WRITE8_MEMBER(dsbz80_device::mpeg_stereo_w)
231226{
232   mp_pan = data & 3;
227   mp_pan = data & 3;   // 0 = stereo, 1 = left on both channels, 2 = right on both channels
233228}
234229
235230READ8_MEMBER(dsbz80_device::status_r)
r19975r19976
240235   // SWA requires that status & 0x38 = 0 or else it loops endlessly...
241236   return status;
242237}
238
239void dsbz80_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
240{
241   stream_sample_t *out_l = outputs[0];
242   stream_sample_t *out_r = outputs[1];
243
244   for(;;)
245   {
246      while(samples && audio_pos < audio_avail)
247      {
248         switch (mp_pan)
249         {
250            case 0:   // stereo
251               *out_l++ = audio_buf[audio_pos*2];
252               *out_r++ = audio_buf[audio_pos*2+1];
253               break;
254
255            case 1:   // left only
256               *out_l++ = audio_buf[audio_pos*2];
257               *out_r++ = audio_buf[audio_pos*2];
258               break;
259
260            case 2:   // right only
261               *out_l++ = audio_buf[audio_pos*2+1];
262               *out_r++ = audio_buf[audio_pos*2+1];
263               break;
264         }
265         audio_pos++;
266         samples--;
267      }
268
269      if(!samples)
270      {
271         break;
272      }
273
274      if(mp_state == 0)
275      {
276         for(int i=0; i != samples; i++)
277         {
278            *out_l++ = 0;
279            *out_r++ = 0;
280         }
281         break;
282
283      }
284      else
285      {
286         int sample_rate, channel_count;
287         bool ok = decoder->decode_buffer(mp_pos, mp_end*8, audio_buf, audio_avail, sample_rate, channel_count);
288
289         if (ok)
290         {
291            audio_pos = 0;
292         }
293         else
294         {
295            if(mp_state == 2)
296            {
297               if (mp_pos == lp_start*8)
298               {
299                  // We're looping on un-decodable crap, abort abort abort
300                  mp_state = 0;
301               }
302               mp_pos = lp_start*8;
303
304               if (lp_end)
305               {
306                  mp_end = lp_end;
307               }
308            }
309            else
310            {
311               mp_state = 0;
312            }
313         }
314      }
315   }
316}
317
trunk/src/mame/audio/dsbz80.h
r19975r19976
55
66#include "emu.h"
77#include "cpu/z80/z80.h"
8#include "sound/ymz770.h"
8#include "sound/mpeg_audio.h"
99
1010#define DSBZ80_TAG "dsbz80"
1111
r19975r19976
1616//  TYPE DEFINITIONS
1717//**************************************************************************
1818
19class dsbz80_device : public device_t
19class dsbz80_device : public device_t, public device_sound_interface
2020{
2121public:
2222    // construction/destruction
r19975r19976
2828    DECLARE_WRITE8_MEMBER(latch_w);
2929
3030    required_device<cpu_device> m_ourcpu;
31    optional_device<ymz770_device> m_ymz770;
3231
3332    DECLARE_WRITE8_MEMBER(mpeg_trigger_w);
3433    DECLARE_WRITE8_MEMBER(mpeg_start_w);
r19975r19976
4443    virtual void device_start();
4544    virtual void device_reset();
4645
46   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
47
4748private:
49   mpeg_audio *decoder;
50   INT16 audio_buf[1152*2];
4851    UINT8 m_dsb_latch;
4952    UINT32 mp_start, mp_end, mp_vol, mp_pan, mp_state, lp_start, lp_end, start, end;
53   int mp_pos, audio_pos, audio_avail;
5054    int status;
55    int getbit();
5156};
5257
5358
trunk/src/mame/includes/model1.h
r19975r19976
3737   struct quad_m1 **m_quadind;
3838   int m_sound_irq;
3939   int m_to_68k[8];
40   UINT8 m_last_snd_cmd;
41   int m_snd_cmd_state;
4042   int m_fifo_wptr;
4143   int m_fifo_rptr;
4244   int m_last_irq;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team