1/*- 2 * Copyright (c) 2009 Ariff Abdullah <ariff@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29#ifndef _SND_MATRIX_MAP_H_ 30#define _SND_MATRIX_MAP_H_ 31 32/* 33 * Standard matrix maps: 34 * 35 * struct pcmchan_matrix { 36 * .id = Matrix identity (see matrix.h). Custom defined should use 37 * one of SND_CHN_MATRIX_MISC (for whatever purposes) or 38 * SND_CHN_MATRIX_DRV (hardware driver). 39 * .channels = Total number of channels, including whatever 'extended' 40 * (the X.ext notions, mostly LFE). 41 * .ext = Total number of extended channels (LFE). 42 * .map = { 43 * Sequences of channel type and interleave structure. 44 * [interleave offset] = { 45 * .type = channel type (see matrix.h). 46 * .members = Masks of channels that is acceptable as a 47 * member of this channel type. 48 * }, 49 * [total channels] = { 50 * .type = Maximum channels marker (SND_CHN_T_MAX). 51 * .members = 0 (no channels allowed here). 52 * }, 53 * }, 54 * .mask = Mask of channels that exist in this map. 55 * .offset = { 56 * channel offset that directly translate to the above interleave 57 * offset according to SND_CHN_T_* definitions. 58 * } 59 * }; 60 * 61 * Rule of thumb: Avoid using SND_CHN_T_* that is marked with XXX (matrix.h), 62 * or be prepared for the horror to come. 63 * 64 */ 65 66#define SND_CHN_MATRIX_MAP_1_0 { \ 67 .id = SND_CHN_MATRIX_1_0, \ 68 .channels = 1, \ 69 .ext = 0, \ 70 .map = { \ 71 /* Mono, center, etc. */ \ 72 [0] = { \ 73 .type = SND_CHN_T_FL, \ 74 .members = \ 75 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 76 SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ 77 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ 78 SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL | \ 79 SND_CHN_T_MASK_SR \ 80 }, \ 81 [1] = { \ 82 .type = SND_CHN_T_MAX, \ 83 .members = 0 \ 84 } \ 85 }, \ 86 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 87 SND_CHN_T_MASK_FC, \ 88 .offset = { 0, 0, 0, 0, 0, 0, -1, -1, 0, \ 89 0, 0, -1, -1, -1, -1, -1, -1, -1 } \ 90} 91 92#define SND_CHN_MATRIX_MAP_2_0 { \ 93 .id = SND_CHN_MATRIX_2_0, \ 94 .channels = 2, \ 95 .ext = 0, \ 96 .map = { \ 97 /* Left */ \ 98 [0] = { \ 99 .type = SND_CHN_T_FL, \ 100 .members = \ 101 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ 102 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ 103 SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ 104 }, \ 105 /* Right */ \ 106 [1] = { \ 107 .type = SND_CHN_T_FR, \ 108 .members = \ 109 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ 110 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ 111 SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ 112 }, \ 113 [2] = { \ 114 .type = SND_CHN_T_MAX, \ 115 .members = 0 \ 116 } \ 117 }, \ 118 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR, \ 119 .offset = { 0, 1, -1, -1, -1, -1, -1, -1, -1, \ 120 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 121} 122 123#define SND_CHN_MATRIX_MAP_2_1 { \ 124 .id = SND_CHN_MATRIX_2_1, \ 125 .channels = 3, \ 126 .ext = 1, \ 127 .map = { \ 128 /* Left */ \ 129 [0] = { \ 130 .type = SND_CHN_T_FL, \ 131 .members = \ 132 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ 133 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ 134 SND_CHN_T_MASK_SL \ 135 }, \ 136 /* Right */ \ 137 [1] = { \ 138 .type = SND_CHN_T_FR, \ 139 .members = \ 140 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ 141 SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ 142 SND_CHN_T_MASK_SR \ 143 }, \ 144 /* LFE */ \ 145 [2] = { \ 146 .type = SND_CHN_T_LF, \ 147 .members = SND_CHN_T_MASK_LF \ 148 }, \ 149 [3] = { \ 150 .type = SND_CHN_T_MAX, \ 151 .members = 0 \ 152 } \ 153 }, \ 154 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 155 SND_CHN_T_MASK_LF, \ 156 .offset = { 0, 1, -1, 2, -1, -1, -1, -1, -1, \ 157 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 158} 159 160#define SND_CHN_MATRIX_MAP_3_0 { /* 3 channels default */ \ 161 .id = SND_CHN_MATRIX_3_0, \ 162 .channels = 3, \ 163 .ext = 0, \ 164 .map = { \ 165 /* Left */ \ 166 [0] = { \ 167 .type = SND_CHN_T_FL, \ 168 .members = \ 169 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ 170 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SL \ 171 }, \ 172 /* Right */ \ 173 [1] = { \ 174 .type = SND_CHN_T_FR, \ 175 .members = \ 176 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ 177 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SR \ 178 }, \ 179 /* Rear Center */ \ 180 [2] = { \ 181 .type = SND_CHN_T_BC, \ 182 .members = \ 183 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ 184 SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ 185 SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR \ 186 }, \ 187 [3] = { \ 188 .type = SND_CHN_T_MAX, \ 189 .members = 0 \ 190 } \ 191 }, \ 192 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 193 SND_CHN_T_MASK_BC, \ 194 .offset = { 0, 1, -1, -1, -1, -1, -1, -1, 2, \ 195 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 196} 197 198#define SND_CHN_MATRIX_MAP_4_0 { \ 199 .id = SND_CHN_MATRIX_4_0, \ 200 .channels = 4, \ 201 .ext = 0, \ 202 .map = { \ 203 /* Left */ \ 204 [0] = { \ 205 .type = SND_CHN_T_FL, \ 206 .members = \ 207 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ 208 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SL \ 209 }, \ 210 /* Right */ \ 211 [1] = { \ 212 .type = SND_CHN_T_FR, \ 213 .members = \ 214 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ 215 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SR \ 216 }, \ 217 /* Rear Left */ \ 218 [2] = { \ 219 .type = SND_CHN_T_BL, \ 220 .members = \ 221 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ 222 SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ 223 }, \ 224 /* Rear Right */ \ 225 [3] = { \ 226 .type = SND_CHN_T_BR, \ 227 .members = \ 228 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ 229 SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ 230 }, \ 231 [4] = { \ 232 .type = SND_CHN_T_MAX, \ 233 .members = 0 \ 234 } \ 235 }, \ 236 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 237 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR, \ 238 .offset = { 0, 1, -1, -1, 2, 3, -1, -1, -1, \ 239 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 240} 241 242#define SND_CHN_MATRIX_MAP_4_1 { \ 243 .id = SND_CHN_MATRIX_4_1, \ 244 .channels = 5, \ 245 .ext = 1, \ 246 .map = { \ 247 /* Left */ \ 248 [0] = { \ 249 .type = SND_CHN_T_FL, \ 250 .members = \ 251 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ 252 SND_CHN_T_MASK_SL \ 253 }, \ 254 /* Right */ \ 255 [1] = { \ 256 .type = SND_CHN_T_FR, \ 257 .members = \ 258 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ 259 SND_CHN_T_MASK_SR \ 260 }, \ 261 /* Rear Left */ \ 262 [2] = { \ 263 .type = SND_CHN_T_BL, \ 264 .members = \ 265 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ 266 SND_CHN_T_MASK_SL \ 267 }, \ 268 /* Rear Right */ \ 269 [3] = { \ 270 .type = SND_CHN_T_BR, \ 271 .members = \ 272 SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ 273 SND_CHN_T_MASK_SR \ 274 }, \ 275 /* LFE */ \ 276 [4] = { \ 277 .type = SND_CHN_T_LF, \ 278 .members = SND_CHN_T_MASK_LF \ 279 }, \ 280 [5] = { \ 281 .type = SND_CHN_T_MAX, \ 282 .members = 0 \ 283 } \ 284 }, \ 285 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 286 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ 287 SND_CHN_T_MASK_LF, \ 288 .offset = { 0, 1, -1, 4, 2, 3, -1, -1, -1, \ 289 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 290} 291 292#define SND_CHN_MATRIX_MAP_5_0 { /* 5 channels default */ \ 293 .id = SND_CHN_MATRIX_5_0, \ 294 .channels = 5, \ 295 .ext = 0, \ 296 .map = { \ 297 /* Left */ \ 298 [0] = { \ 299 .type = SND_CHN_T_FL, \ 300 .members = \ 301 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF | \ 302 SND_CHN_T_MASK_SL \ 303 }, \ 304 /* Right */ \ 305 [1] = { \ 306 .type = SND_CHN_T_FR, \ 307 .members = \ 308 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF | \ 309 SND_CHN_T_MASK_SR \ 310 }, \ 311 /* Rear Left */ \ 312 [2] = { \ 313 .type = SND_CHN_T_BL, \ 314 .members = \ 315 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ 316 SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ 317 }, \ 318 /* Rear Right */ \ 319 [3] = { \ 320 .type = SND_CHN_T_BR, \ 321 .members = \ 322 SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ 323 SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ 324 }, \ 325 /* Center */ \ 326 [4] = { \ 327 .type = SND_CHN_T_FC, \ 328 .members = SND_CHN_T_MASK_FC \ 329 }, \ 330 [5] = { \ 331 .type = SND_CHN_T_MAX, \ 332 .members = 0 \ 333 } \ 334 }, \ 335 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 336 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ 337 SND_CHN_T_MASK_FC, \ 338 .offset = { 0, 1, 4, -1, 2, 3, -1, -1, -1, \ 339 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 340} 341 342#define SND_CHN_MATRIX_MAP_5_1 { /* 6 channels default */ \ 343 .id = SND_CHN_MATRIX_5_1, \ 344 .channels = 6, \ 345 .ext = 1, \ 346 .map = { \ 347 /* Left */ \ 348 [0] = { \ 349 .type = SND_CHN_T_FL, \ 350 .members = \ 351 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_SL \ 352 }, \ 353 /* Right */ \ 354 [1] = { \ 355 .type = SND_CHN_T_FR, \ 356 .members = \ 357 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_SR \ 358 }, \ 359 /* Rear Left */ \ 360 [2] = { \ 361 .type = SND_CHN_T_BL, \ 362 .members = \ 363 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ 364 SND_CHN_T_MASK_SL \ 365 }, \ 366 /* Rear Right */ \ 367 [3] = { \ 368 .type = SND_CHN_T_BR, \ 369 .members = \ 370 SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ 371 SND_CHN_T_MASK_SR \ 372 }, \ 373 /* Center */ \ 374 [4] = { \ 375 .type = SND_CHN_T_FC, \ 376 .members = SND_CHN_T_MASK_FC \ 377 }, \ 378 /* LFE */ \ 379 [5] = { \ 380 .type = SND_CHN_T_LF, \ 381 .members = SND_CHN_T_MASK_LF \ 382 }, \ 383 [6] = { \ 384 .type = SND_CHN_T_MAX, \ 385 .members = 0 \ 386 } \ 387 }, \ 388 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 389 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ 390 SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF, \ 391 .offset = { 0, 1, 4, 5, 2, 3, -1, -1, -1, \ 392 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 393} 394 395#define SND_CHN_MATRIX_MAP_6_0 { \ 396 .id = SND_CHN_MATRIX_6_0, \ 397 .channels = 6, \ 398 .ext = 0, \ 399 .map = { \ 400 /* Left */ \ 401 [0] = { \ 402 .type = SND_CHN_T_FL, \ 403 .members = \ 404 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF | \ 405 SND_CHN_T_MASK_SL \ 406 }, \ 407 /* Right */ \ 408 [1] = { \ 409 .type = SND_CHN_T_FR, \ 410 .members = \ 411 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF | \ 412 SND_CHN_T_MASK_SR \ 413 }, \ 414 /* Rear Left */ \ 415 [2] = { \ 416 .type = SND_CHN_T_BL, \ 417 .members = \ 418 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_LF | \ 419 SND_CHN_T_MASK_SL \ 420 }, \ 421 /* Rear Right */ \ 422 [3] = { \ 423 .type = SND_CHN_T_BR, \ 424 .members = \ 425 SND_CHN_T_MASK_BR | SND_CHN_T_MASK_LF | \ 426 SND_CHN_T_MASK_SR \ 427 }, \ 428 /* Center */ \ 429 [4] = { \ 430 .type = SND_CHN_T_FC, \ 431 .members = SND_CHN_T_MASK_FC \ 432 }, \ 433 /* Rear Center */ \ 434 [5] = { \ 435 .type = SND_CHN_T_BC, \ 436 .members = SND_CHN_T_MASK_BC \ 437 }, \ 438 [6] = { \ 439 .type = SND_CHN_T_MAX, \ 440 .members = 0 \ 441 } \ 442 }, \ 443 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 444 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ 445 SND_CHN_T_MASK_FC | SND_CHN_T_MASK_BC, \ 446 .offset = { 0, 1, 4, -1, 2, 3, -1, -1, 5, \ 447 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 448} 449 450#define SND_CHN_MATRIX_MAP_6_1 { \ 451 .id = SND_CHN_MATRIX_6_1, \ 452 .channels = 7, \ 453 .ext = 1, \ 454 .map = { \ 455 /* Left */ \ 456 [0] = { \ 457 .type = SND_CHN_T_FL, \ 458 .members = \ 459 SND_CHN_T_MASK_FL | SND_CHN_T_MASK_SL \ 460 }, \ 461 /* Right */ \ 462 [1] = { \ 463 .type = SND_CHN_T_FR, \ 464 .members = \ 465 SND_CHN_T_MASK_FR | SND_CHN_T_MASK_SR \ 466 }, \ 467 /* Rear Left */ \ 468 [2] = { \ 469 .type = SND_CHN_T_BL, \ 470 .members = \ 471 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_SL \ 472 }, \ 473 /* Rear Right */ \ 474 [3] = { \ 475 .type = SND_CHN_T_BR, \ 476 .members = \ 477 SND_CHN_T_MASK_BR | SND_CHN_T_MASK_SR \ 478 }, \ 479 /* Center */ \ 480 [4] = { \ 481 .type = SND_CHN_T_FC, \ 482 .members = SND_CHN_T_MASK_FC \ 483 }, \ 484 /* LFE */ \ 485 [5] = { \ 486 .type = SND_CHN_T_LF, \ 487 .members = SND_CHN_T_MASK_LF \ 488 }, \ 489 /* Rear Center */ \ 490 [6] = { \ 491 .type = SND_CHN_T_BC, \ 492 .members = SND_CHN_T_MASK_BC \ 493 }, \ 494 [7] = { \ 495 .type = SND_CHN_T_MAX, \ 496 .members = 0 \ 497 } \ 498 }, \ 499 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 500 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ 501 SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ 502 SND_CHN_T_MASK_BC, \ 503 .offset = { 0, 1, 4, 5, 2, 3, -1, -1, 6, \ 504 -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ 505} 506 507#define SND_CHN_MATRIX_MAP_7_1 { \ 508 .id = SND_CHN_MATRIX_7_1, \ 509 .channels = 8, \ 510 .ext = 1, \ 511 .map = { \ 512 /* Left */ \ 513 [0] = { \ 514 .type = SND_CHN_T_FL, \ 515 .members = SND_CHN_T_MASK_FL \ 516 }, \ 517 /* Right */ \ 518 [1] = { \ 519 .type = SND_CHN_T_FR, \ 520 .members = SND_CHN_T_MASK_FR \ 521 }, \ 522 /* Rear Left */ \ 523 [2] = { \ 524 .type = SND_CHN_T_BL, \ 525 .members = \ 526 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC \ 527 }, \ 528 /* Rear Right */ \ 529 [3] = { \ 530 .type = SND_CHN_T_BR, \ 531 .members = \ 532 SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC \ 533 }, \ 534 /* Center */ \ 535 [4] = { \ 536 .type = SND_CHN_T_FC, \ 537 .members = SND_CHN_T_MASK_FC \ 538 }, \ 539 /* LFE */ \ 540 [5] = { \ 541 .type = SND_CHN_T_LF, \ 542 .members = SND_CHN_T_MASK_LF \ 543 }, \ 544 /* Side Left */ \ 545 [6] = { \ 546 .type = SND_CHN_T_SL, \ 547 .members = SND_CHN_T_MASK_SL \ 548 }, \ 549 /* Side Right */ \ 550 [7] = { \ 551 .type = SND_CHN_T_SR, \ 552 .members = SND_CHN_T_MASK_SR \ 553 }, \ 554 [8] = { \ 555 .type = SND_CHN_T_MAX, \ 556 .members = 0 \ 557 } \ 558 }, \ 559 .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ 560 SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ 561 SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ 562 SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR, \ 563 .offset = { 0, 1, 4, 5, 2, 3, -1, -1, -1, \ 564 6, 7, -1, -1, -1, -1, -1, -1, -1 } \ 565} 566 567#endif /* !_SND_MATRIX_MAP_H_ */ 568