Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: emu10k1: enable bit-exact playback, part 1: DSP attenuation

Fractional multiplication with the maximal value 2^31-1 causes some tiny
distortion. Instead, we want to multiply with the full 2^31. The catch
is of course that this cannot be represented in the DSP's signed 32 bit
registers.

One way to deal with this is to encode 1.0 as a negative number and
special-case it. As a matter of fact, the SbLive! code path already
contained such code, though the controls never actually exercised it.

A more efficient approach is to use negative values, which actually
extend to -2^31. Accordingly, for all the volume adjustments we now use
the MAC1 instruction which negates the X operand.

The range of the controls in highres mode is extended downwards, so -1
is the new zero/mute. At maximal excursion, real zero is not mute any
more, but I don't think anyone will notice this behavior change. ;-)

That also required making the min/max/values in the control structs
signed. This technically changes the user space interface, but it seems
implausible that someone would notice - the numbers were actually
treated as if they were signed anyway (and in the actual mixer iface
they _are_). And without this change, the min value didn't even make
sense in the first place (and no-one noticed, because it was always 0).

Tested-by: Jonathan Dowland <jon@dow.land>
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230514170323.3408834-7-oswald.buddenhagen@gmx.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Oswald Buddenhagen and committed by
Takashi Iwai
1298bc97 de0dc310

+64 -69
+3 -3
include/sound/emu10k1.h
··· 1508 1508 unsigned int vcount; 1509 1509 unsigned int count; /* count of GPR (1..16) */ 1510 1510 unsigned short gpr[32]; /* GPR number(s) */ 1511 - unsigned int value[32]; 1512 - unsigned int min; /* minimum range */ 1513 - unsigned int max; /* maximum range */ 1511 + int value[32]; 1512 + int min; /* minimum range */ 1513 + int max; /* maximum range */ 1514 1514 unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ 1515 1515 struct snd_kcontrol *kcontrol; 1516 1516 };
+5 -3
include/uapi/sound/emu10k1.h
··· 308 308 #define EMU10K1_GPR_TRANSLATION_BASS 2 309 309 #define EMU10K1_GPR_TRANSLATION_TREBLE 3 310 310 #define EMU10K1_GPR_TRANSLATION_ONOFF 4 311 + #define EMU10K1_GPR_TRANSLATION_NEGATE 5 312 + #define EMU10K1_GPR_TRANSLATION_NEG_TABLE100 6 311 313 312 314 enum emu10k1_ctl_elem_iface { 313 315 EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */ ··· 330 328 unsigned int vcount; /* visible count */ 331 329 unsigned int count; /* count of GPR (1..16) */ 332 330 unsigned short gpr[32]; /* GPR number(s) */ 333 - unsigned int value[32]; /* initial values */ 334 - unsigned int min; /* minimum range */ 335 - unsigned int max; /* maximum range */ 331 + int value[32]; /* initial values */ 332 + int min; /* minimum range */ 333 + int max; /* maximum range */ 336 334 unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ 337 335 const unsigned int *tlv; 338 336 };
+56 -63
sound/pci/emu10k1/emufx.c
··· 332 332 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); 333 333 struct snd_emu10k1_fx8010_ctl *ctl = 334 334 (struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value; 335 - unsigned int nval, val; 335 + int nval, val; 336 336 unsigned int i, j; 337 337 int change = 0; 338 338 ··· 349 349 case EMU10K1_GPR_TRANSLATION_NONE: 350 350 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val); 351 351 break; 352 + case EMU10K1_GPR_TRANSLATION_NEGATE: 353 + snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, ~val); 354 + break; 352 355 case EMU10K1_GPR_TRANSLATION_TABLE100: 353 356 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]); 357 + break; 358 + case EMU10K1_GPR_TRANSLATION_NEG_TABLE100: 359 + snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, 360 + val == 100 ? 0x80000000 : -(int)db_table[val]); 354 361 break; 355 362 case EMU10K1_GPR_TRANSLATION_BASS: 356 363 if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) { ··· 778 771 } 779 772 switch (gctl->translation) { 780 773 case EMU10K1_GPR_TRANSLATION_NONE: 774 + case EMU10K1_GPR_TRANSLATION_NEGATE: 781 775 break; 782 776 case EMU10K1_GPR_TRANSLATION_TABLE100: 777 + case EMU10K1_GPR_TRANSLATION_NEG_TABLE100: 783 778 if (gctl->min != 0 || gctl->max != 100) { 784 779 err = -EINVAL; 785 780 goto __error; ··· 1146 1137 1147 1138 static void 1148 1139 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl, 1149 - const char *name, int gpr, int defval) 1140 + const char *name, int gpr, int defval) 1150 1141 { 1151 1142 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; 1152 1143 strcpy(ctl->id.name, name); 1153 1144 ctl->vcount = ctl->count = 1; 1154 1145 if (high_res_gpr_volume) { 1155 - ctl->min = 0; 1146 + ctl->min = -1; 1156 1147 ctl->max = 0x7fffffff; 1157 1148 ctl->tlv = snd_emu10k1_db_linear; 1158 - ctl->translation = EMU10K1_GPR_TRANSLATION_NONE; 1159 - defval = defval * 0x7fffffffLL / 100; 1149 + ctl->translation = EMU10K1_GPR_TRANSLATION_NEGATE; 1150 + defval = defval * 0x80000000LL / 100 - 1; 1160 1151 } else { 1161 1152 ctl->min = 0; 1162 1153 ctl->max = 100; 1163 1154 ctl->tlv = snd_emu10k1_db_scale1; 1164 - ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; 1155 + ctl->translation = EMU10K1_GPR_TRANSLATION_NEG_TABLE100; 1165 1156 } 1166 1157 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; 1167 1158 } 1168 1159 1169 1160 static void 1170 1161 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl, 1171 - const char *name, int gpr, int defval) 1162 + const char *name, int gpr, int defval) 1172 1163 { 1173 1164 ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER; 1174 1165 strcpy(ctl->id.name, name); 1175 1166 ctl->vcount = ctl->count = 2; 1176 1167 if (high_res_gpr_volume) { 1177 - ctl->min = 0; 1168 + ctl->min = -1; 1178 1169 ctl->max = 0x7fffffff; 1179 1170 ctl->tlv = snd_emu10k1_db_linear; 1180 - ctl->translation = EMU10K1_GPR_TRANSLATION_NONE; 1181 - defval = defval * 0x7fffffffLL / 100; 1171 + ctl->translation = EMU10K1_GPR_TRANSLATION_NEGATE; 1172 + defval = defval * 0x80000000LL / 100 - 1; 1182 1173 } else { 1183 1174 ctl->min = 0; 1184 1175 ctl->max = 100; 1185 1176 ctl->tlv = snd_emu10k1_db_scale1; 1186 - ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; 1177 + ctl->translation = EMU10K1_GPR_TRANSLATION_NEG_TABLE100; 1187 1178 } 1188 1179 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; 1189 1180 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; ··· 1302 1293 1303 1294 #if 1 1304 1295 /* PCM front Playback Volume (independent from stereo mix) 1305 - * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31) 1306 - * where gpr contains attenuation from corresponding mixer control 1296 + * playback = -gpr * FXBUS_PCM_LEFT_FRONT >> 31 1297 + * where gpr contains negated attenuation from corresponding mixer control 1307 1298 * (snd_emu10k1_init_stereo_control) 1308 1299 */ 1309 - A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); 1310 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); 1300 + A_OP(icode, &ptr, iMAC1, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); 1301 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); 1311 1302 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100); 1312 1303 gpr += 2; 1313 1304 1314 1305 /* PCM Surround Playback (independent from stereo mix) */ 1315 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR)); 1316 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR)); 1306 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR)); 1307 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR)); 1317 1308 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100); 1318 1309 gpr += 2; 1319 1310 1320 1311 /* PCM Side Playback (independent from stereo mix) */ 1321 1312 if (emu->card_capabilities->spk71) { 1322 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE)); 1323 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE)); 1313 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE)); 1314 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE)); 1324 1315 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100); 1325 1316 gpr += 2; 1326 1317 } 1327 1318 1328 1319 /* PCM Center Playback (independent from stereo mix) */ 1329 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER)); 1320 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER)); 1330 1321 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100); 1331 1322 gpr++; 1332 1323 1333 1324 /* PCM LFE Playback (independent from stereo mix) */ 1334 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE)); 1325 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE)); 1335 1326 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100); 1336 1327 gpr++; 1337 1328 ··· 1339 1330 * Stereo Mix 1340 1331 */ 1341 1332 /* Wave (PCM) Playback Volume (will be renamed later) */ 1342 - A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT)); 1343 - A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT)); 1333 + A_OP(icode, &ptr, iMAC1, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT)); 1334 + A_OP(icode, &ptr, iMAC1, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT)); 1344 1335 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100); 1345 1336 gpr += 2; 1346 1337 1347 1338 /* Synth Playback */ 1348 - A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT)); 1349 - A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); 1339 + A_OP(icode, &ptr, iMAC1, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT)); 1340 + A_OP(icode, &ptr, iMAC1, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); 1350 1341 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100); 1351 1342 gpr += 2; 1352 1343 1353 1344 /* Wave (PCM) Capture */ 1354 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT)); 1355 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT)); 1345 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT)); 1346 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT)); 1356 1347 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0); 1357 1348 gpr += 2; 1358 1349 1359 1350 /* Synth Capture */ 1360 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT)); 1361 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); 1351 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT)); 1352 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); 1362 1353 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0); 1363 1354 gpr += 2; 1364 1355 ··· 1366 1357 * inputs 1367 1358 */ 1368 1359 #define A_ADD_VOLUME_IN(var,vol,input) \ 1369 - A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) 1360 + A_OP(icode, &ptr, iMAC1, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) 1370 1361 1371 1362 if (emu->card_capabilities->emu_model) { 1372 1363 /* EMU1010 DSP 0 and DSP 1 Capture */ 1373 1364 // The 24 MSB hold the actual value. We implicitly discard the 16 LSB. 1374 1365 if (emu->card_capabilities->ca0108_chip) { 1375 1366 // For unclear reasons, the EMU32IN cannot be the Y operand! 1376 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A3_EMU32IN(0x0), A_GPR(gpr)); 1367 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+0), A_GPR(capture+0), A3_EMU32IN(0x0), A_GPR(gpr)); 1377 1368 // A3_EMU32IN(0) is delayed by one sample, so all other A3_EMU32IN channels 1378 1369 // need to be delayed as well; we use an auxiliary register for that. 1379 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+2), A_GPR(gpr+1)); 1370 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+2), A_GPR(gpr+1)); 1380 1371 A_OP(icode, &ptr, iACC3, A_GPR(gpr+2), A3_EMU32IN(0x1), A_C_00000000, A_C_00000000); 1381 1372 } else { 1382 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0)); 1373 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+0), A_GPR(capture+0), A_P16VIN(0x0), A_GPR(gpr)); 1383 1374 // A_P16VIN(0) is delayed by one sample, so all other A_P16VIN channels 1384 1375 // need to be delayed as well; we use an auxiliary register for that. 1385 - A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_GPR(gpr+2)); 1376 + A_OP(icode, &ptr, iMAC1, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+2), A_GPR(gpr+1)); 1386 1377 A_OP(icode, &ptr, iACC3, A_GPR(gpr+2), A_P16VIN(0x1), A_C_00000000, A_C_00000000); 1387 1378 } 1388 1379 snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0); ··· 1474 1465 } 1475 1466 1476 1467 /* Stereo Mix Front Playback Volume */ 1477 - A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix)); 1478 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1)); 1468 + A_OP(icode, &ptr, iMAC1, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix)); 1469 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1)); 1479 1470 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100); 1480 1471 gpr += 2; 1481 1472 1482 1473 /* Stereo Mix Surround Playback */ 1483 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix)); 1484 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1)); 1474 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix)); 1475 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1)); 1485 1476 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0); 1486 1477 gpr += 2; 1487 1478 1488 1479 /* Stereo Mix Center Playback */ 1489 1480 /* Center = sub = Left/2 + Right/2 */ 1490 1481 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), A_C_40000000, A_GPR(stereo_mix+1)); 1491 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp)); 1482 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp)); 1492 1483 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0); 1493 1484 gpr++; 1494 1485 1495 1486 /* Stereo Mix LFE Playback */ 1496 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp)); 1487 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp)); 1497 1488 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0); 1498 1489 gpr++; 1499 1490 1500 1491 if (emu->card_capabilities->spk71) { 1501 1492 /* Stereo Mix Side Playback */ 1502 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix)); 1503 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1)); 1493 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix)); 1494 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1)); 1504 1495 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0); 1505 1496 gpr += 2; 1506 1497 } ··· 1588 1579 1589 1580 /* Master volume (will be renamed later) */ 1590 1581 for (z = 0; z < 8; z++) 1591 - A_OP(icode, &ptr, iMAC0, A_GPR(playback+z), A_C_00000000, A_GPR(gpr), A_GPR(playback+z)); 1582 + A_OP(icode, &ptr, iMAC1, A_GPR(playback+z), A_C_00000000, A_GPR(gpr), A_GPR(playback+z)); 1592 1583 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0); 1593 1584 gpr++; 1594 1585 ··· 1740 1731 * initial DSP configuration for Emu10k1 1741 1732 */ 1742 1733 1743 - /* when volume = max, then copy only to avoid volume modification */ 1744 - /* with iMAC0 (negative values) */ 1734 + /* Volumes are in the [-2^31, 0] range, zero being mute. */ 1745 1735 static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol) 1746 1736 { 1747 - OP(icode, ptr, iMAC0, dst, C_00000000, src, vol); 1748 - OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff); 1749 - OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001); 1750 - OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000); 1737 + OP(icode, ptr, iMAC1, dst, C_00000000, src, vol); 1751 1738 } 1752 1739 static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol) 1753 1740 { 1754 - OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff); 1755 - OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002); 1756 - OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001); 1757 - OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001); 1758 - OP(icode, ptr, iMAC0, dst, dst, src, vol); 1759 - } 1760 - static void _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol) 1761 - { 1762 - OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff); 1763 - OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002); 1764 - OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000); 1765 - OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001); 1766 - OP(icode, ptr, iMAC0, dst, C_00000000, src, vol); 1741 + OP(icode, ptr, iMAC1, dst, dst, src, vol); 1767 1742 } 1768 1743 1769 1744 #define VOLUME(icode, ptr, dst, src, vol) \ ··· 1759 1766 #define VOLUME_ADDIN(icode, ptr, dst, src, vol) \ 1760 1767 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol)) 1761 1768 #define VOLUME_OUT(icode, ptr, dst, src, vol) \ 1762 - _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol)) 1769 + _volume(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol)) 1763 1770 #define _SWITCH(icode, ptr, dst, src, sw) \ 1764 1771 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw); 1765 1772 #define SWITCH(icode, ptr, dst, src, sw) \