diff --git a/sys/dev/sound/pcm/matrix.h b/sys/dev/sound/pcm/matrix.h index 14f3a3410a70..e2798c651536 100644 --- a/sys/dev/sound/pcm/matrix.h +++ b/sys/dev/sound/pcm/matrix.h @@ -1,220 +1,860 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2007-2009 Ariff Abdullah * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _SND_MATRIX_H_ #define _SND_MATRIX_H_ #undef SND_MULTICHANNEL #ifndef SND_OLDSTEREO #define SND_MULTICHANNEL 1 #endif /* * XXX = unused, but part of the definition (will be used someday, maybe). */ #define SND_CHN_T_FL 0 /* Front Left */ #define SND_CHN_T_FR 1 /* Front Right */ #define SND_CHN_T_FC 2 /* Front Center */ #define SND_CHN_T_LF 3 /* Low Frequency */ #define SND_CHN_T_BL 4 /* Back Left */ #define SND_CHN_T_BR 5 /* Back Right */ #define SND_CHN_T_FLC 6 /* Front Left Center XXX */ #define SND_CHN_T_FRC 7 /* Front Right Center XXX */ #define SND_CHN_T_BC 8 /* Back Center */ #define SND_CHN_T_SL 9 /* Side Left */ #define SND_CHN_T_SR 10 /* Side Right */ #define SND_CHN_T_TC 11 /* Top Center XXX */ #define SND_CHN_T_TFL 12 /* Top Front Left XXX */ #define SND_CHN_T_TFC 13 /* Top Front Center XXX */ #define SND_CHN_T_TFR 14 /* Top Front Right XXX */ #define SND_CHN_T_TBL 15 /* Top Back Left XXX */ #define SND_CHN_T_TBC 16 /* Top Back Center XXX */ #define SND_CHN_T_TBR 17 /* Top Back Right XXX */ #define SND_CHN_T_MAX 18 /* Maximum channels */ #define SND_CHN_T_ZERO (SND_CHN_T_MAX + 1) /* Zero samples */ #define SND_CHN_T_LABELS { \ "fl", "fr", "fc", "lf", "bl", "br", \ "flc", "frc", "bc", "sl", "sr", "tc", \ "tfl", "tfc", "tfr", "tbl", "tbc", "tbr" \ } #define SND_CHN_T_NAMES { \ "Front Left", "Front Right", "Front Center", \ "Low Frequency Effects", \ "Back Left", "Back Right", \ "Front Left Center", "Front Right Center", \ "Back Center", \ "Side Left", "Side Right", \ "Top Center", \ "Top Front Left", "Top Front Center", "Top Front Right", \ "Top Back Left", "Top Back Center", "Top Back Right" \ } #define SND_CHN_T_MASK_FL (1 << SND_CHN_T_FL) #define SND_CHN_T_MASK_FR (1 << SND_CHN_T_FR) #define SND_CHN_T_MASK_FC (1 << SND_CHN_T_FC) #define SND_CHN_T_MASK_LF (1 << SND_CHN_T_LF) #define SND_CHN_T_MASK_BL (1 << SND_CHN_T_BL) #define SND_CHN_T_MASK_BR (1 << SND_CHN_T_BR) #define SND_CHN_T_MASK_FLC (1 << SND_CHN_T_FLC) #define SND_CHN_T_MASK_FRC (1 << SND_CHN_T_FRC) #define SND_CHN_T_MASK_BC (1 << SND_CHN_T_BC) #define SND_CHN_T_MASK_SL (1 << SND_CHN_T_SL) #define SND_CHN_T_MASK_SR (1 << SND_CHN_T_SR) #define SND_CHN_T_MASK_TC (1 << SND_CHN_T_TC) #define SND_CHN_T_MASK_TFL (1 << SND_CHN_T_TFL) #define SND_CHN_T_MASK_TFC (1 << SND_CHN_T_TFC) #define SND_CHN_T_MASK_TFR (1 << SND_CHN_T_TFR) #define SND_CHN_T_MASK_TBL (1 << SND_CHN_T_TBL) #define SND_CHN_T_MASK_TBC (1 << SND_CHN_T_TBC) #define SND_CHN_T_MASK_TBR (1 << SND_CHN_T_TBR) #define SND_CHN_LEFT_MASK (SND_CHN_T_MASK_FL | \ SND_CHN_T_MASK_BL | \ SND_CHN_T_MASK_FLC | \ SND_CHN_T_MASK_SL | \ SND_CHN_T_MASK_TFL | \ SND_CHN_T_MASK_TBL) #define SND_CHN_RIGHT_MASK (SND_CHN_T_MASK_FR | \ SND_CHN_T_MASK_BR | \ SND_CHN_T_MASK_FRC | \ SND_CHN_T_MASK_SR | \ SND_CHN_T_MASK_TFR | \ SND_CHN_T_MASK_TBR) #define SND_CHN_CENTER_MASK (SND_CHN_T_MASK_FC | \ SND_CHN_T_MASK_BC | \ SND_CHN_T_MASK_TC | \ SND_CHN_T_MASK_TFC | \ SND_CHN_T_MASK_TBC | \ SND_CHN_T_MASK_LF) /* XXX what?!? */ /* * Matrix identity. */ /* 1 @ Mono 1.0 */ #define SND_CHN_MATRIX_1_0 0 #define SND_CHN_MATRIX_1 SND_CHN_MATRIX_1_0 /* 2 @ Stereo 2.0 */ #define SND_CHN_MATRIX_2_0 1 #define SND_CHN_MATRIX_2 SND_CHN_MATRIX_2_0 /* 3 @ 2.1 (lfe), 3.0 (rear center, DEFAULT) */ #define SND_CHN_MATRIX_2_1 2 #define SND_CHN_MATRIX_3_0 3 #define SND_CHN_MATRIX_3 SND_CHN_MATRIX_3_0 /* 4 @ 3.1 (lfe), 4.0 (Quadraphonic, DEFAULT) */ #define SND_CHN_MATRIX_3_1 4 #define SND_CHN_MATRIX_4_0 5 #define SND_CHN_MATRIX_4 SND_CHN_MATRIX_4_0 /* 5 @ 4.1 (lfe), 5.0 (center, DEFAULT) */ #define SND_CHN_MATRIX_4_1 6 #define SND_CHN_MATRIX_5_0 7 #define SND_CHN_MATRIX_5 SND_CHN_MATRIX_5_0 /* 6 @ 5.1 (lfe, DEFAULT), 6.0 (rear center) */ #define SND_CHN_MATRIX_5_1 8 #define SND_CHN_MATRIX_6_0 9 #define SND_CHN_MATRIX_6 SND_CHN_MATRIX_5_1 /* 7 @ 6.1 (lfe, DEFAULT), 7.0 */ #define SND_CHN_MATRIX_6_1 10 #define SND_CHN_MATRIX_7_0 11 #define SND_CHN_MATRIX_7 SND_CHN_MATRIX_6_1 /* 8 @ 7.1 (lfe) */ #define SND_CHN_MATRIX_7_1 12 #define SND_CHN_MATRIX_8 SND_CHN_MATRIX_7_1 #define SND_CHN_MATRIX_MAX 13 #define SND_CHN_MATRIX_BEGIN SND_CHN_MATRIX_1_0 #define SND_CHN_MATRIX_END SND_CHN_MATRIX_7_1 /* Custom matrix identity */ #define SND_CHN_MATRIX_DRV -4 /* driver own identity */ #define SND_CHN_MATRIX_PCMCHANNEL -3 /* PCM channel identity */ #define SND_CHN_MATRIX_MISC -2 /* misc, custom defined */ #define SND_CHN_MATRIX_UNKNOWN -1 /* unknown */ #define SND_CHN_T_VOL_0DB SND_CHN_T_MAX #define SND_CHN_T_VOL_MAX (SND_CHN_T_VOL_0DB + 1) #define SND_CHN_T_BEGIN SND_CHN_T_FL #define SND_CHN_T_END SND_CHN_T_TBR #define SND_CHN_T_STEP 1 #define SND_CHN_MIN 1 #ifdef SND_MULTICHANNEL #define SND_CHN_MAX 8 #else #define SND_CHN_MAX 2 #endif /* * Multichannel interleaved volume matrix. Each calculated value relative * to master and 0db will be stored in each CLASS + 1 as long as * chn_setvolume_matrix() or the equivalent CHN_SETVOLUME() macros is * used (see channel.c). */ #define SND_VOL_C_MASTER 0 #define SND_VOL_C_PCM 1 #define SND_VOL_C_PCM_VAL 2 #define SND_VOL_C_MAX 3 #define SND_VOL_C_BEGIN SND_VOL_C_PCM #define SND_VOL_C_END SND_VOL_C_PCM #define SND_VOL_C_STEP 2 #define SND_VOL_C_VAL(x) ((x) + 1) #define SND_VOL_0DB_MIN 1 #define SND_VOL_0DB_MAX 100 #define SND_VOL_0DB_MASTER 100 #define SND_VOL_0DB_PCM 45 #define SND_VOL_RESOLUTION 8 #define SND_VOL_FLAT (1 << SND_VOL_RESOLUTION) #define SND_VOL_CALC_SAMPLE(x, y) (((x) * (y)) >> SND_VOL_RESOLUTION) #define SND_VOL_CALC_VAL(x, y, z) \ (((((x)[y][z] << SND_VOL_RESOLUTION) / \ (x)[y][SND_CHN_T_VOL_0DB]) * \ (x)[SND_VOL_C_MASTER][z]) / \ (x)[SND_VOL_C_MASTER][SND_CHN_T_VOL_0DB]) \ +/* + * Standard matrix maps: + * + * struct pcmchan_matrix { + * .id = Matrix identity (see matrix.h). Custom defined should use + * one of SND_CHN_MATRIX_MISC (for whatever purposes) or + * SND_CHN_MATRIX_DRV (hardware driver). + * .channels = Total number of channels, including whatever 'extended' + * (the X.ext notions, mostly LFE). + * .ext = Total number of extended channels (LFE). + * .map = { + * Sequences of channel type and interleave structure. + * [interleave offset] = { + * .type = channel type (see matrix.h). + * .members = Masks of channels that is acceptable as a + * member of this channel type. + * }, + * [total channels] = { + * .type = Maximum channels marker (SND_CHN_T_MAX). + * .members = 0 (no channels allowed here). + * }, + * }, + * .mask = Mask of channels that exist in this map. + * .offset = { + * channel offset that directly translate to the above interleave + * offset according to SND_CHN_T_* definitions. + * } + * }; + * + * Rule of thumb: Avoid using SND_CHN_T_* that is marked with XXX (matrix.h), + * or be prepared for the horror to come. + * + */ + +#define SND_CHN_MATRIX_MAP_1_0 { \ + .id = SND_CHN_MATRIX_1_0, \ + .channels = 1, \ + .ext = 0, \ + .map = { \ + /* Mono, center, etc. */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL | \ + SND_CHN_T_MASK_SR \ + }, \ + [1] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_FC, \ + .offset = { 0, 0, 0, 0, 0, 0, -1, -1, 0, \ + 0, 0, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_2_0 { \ + .id = SND_CHN_MATRIX_2_0, \ + .channels = 2, \ + .ext = 0, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ + SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ + }, \ + [2] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR, \ + .offset = { 0, 1, -1, -1, -1, -1, -1, -1, -1, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_2_1 { \ + .id = SND_CHN_MATRIX_2_1, \ + .channels = 3, \ + .ext = 1, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SR \ + }, \ + /* LFE */ \ + [2] = { \ + .type = SND_CHN_T_LF, \ + .members = SND_CHN_T_MASK_LF \ + }, \ + [3] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_LF, \ + .offset = { 0, 1, -1, 2, -1, -1, -1, -1, -1, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_3_0 { /* 3 channels default */ \ + .id = SND_CHN_MATRIX_3_0, \ + .channels = 3, \ + .ext = 0, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SR \ + }, \ + /* Rear Center */ \ + [2] = { \ + .type = SND_CHN_T_BC, \ + .members = \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR \ + }, \ + [3] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BC, \ + .offset = { 0, 1, -1, -1, -1, -1, -1, -1, 2, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_3_1 { \ + .id = SND_CHN_MATRIX_3_1, \ + .channels = 4, \ + .ext = 1, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_SR \ + }, \ + /* LFE */ \ + [2] = { \ + .type = SND_CHN_T_LF, \ + .members = SND_CHN_T_MASK_LF \ + }, \ + /* Rear Center */ \ + [3] = { \ + .type = SND_CHN_T_BC, \ + .members = \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR \ + }, \ + [4] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BC, \ + .offset = { 0, 1, -1, 2, -1, -1, -1, -1, 3, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_4_0 { \ + .id = SND_CHN_MATRIX_4_0, \ + .channels = 4, \ + .ext = 0, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SR \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ + SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ + }, \ + [4] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR, \ + .offset = { 0, 1, -1, -1, 2, 3, -1, -1, -1, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_4_1 { \ + .id = SND_CHN_MATRIX_4_1, \ + .channels = 5, \ + .ext = 1, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_SR \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SR \ + }, \ + /* LFE */ \ + [4] = { \ + .type = SND_CHN_T_LF, \ + .members = SND_CHN_T_MASK_LF \ + }, \ + [5] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_LF, \ + .offset = { 0, 1, -1, 4, 2, 3, -1, -1, -1, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_5_0 { /* 5 channels default */ \ + .id = SND_CHN_MATRIX_5_0, \ + .channels = 5, \ + .ext = 0, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_SR \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ + SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ + }, \ + /* Center */ \ + [4] = { \ + .type = SND_CHN_T_FC, \ + .members = SND_CHN_T_MASK_FC \ + }, \ + [5] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_FC, \ + .offset = { 0, 1, 4, -1, 2, 3, -1, -1, -1, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_5_1 { /* 6 channels default */ \ + .id = SND_CHN_MATRIX_5_1, \ + .channels = 6, \ + .ext = 1, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_SR \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_SR \ + }, \ + /* Center */ \ + [4] = { \ + .type = SND_CHN_T_FC, \ + .members = SND_CHN_T_MASK_FC \ + }, \ + /* LFE */ \ + [5] = { \ + .type = SND_CHN_T_LF, \ + .members = SND_CHN_T_MASK_LF \ + }, \ + [6] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF, \ + .offset = { 0, 1, 4, 5, 2, 3, -1, -1, -1, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_6_0 { \ + .id = SND_CHN_MATRIX_6_0, \ + .channels = 6, \ + .ext = 0, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_SR \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_SL \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_SR \ + }, \ + /* Center */ \ + [4] = { \ + .type = SND_CHN_T_FC, \ + .members = SND_CHN_T_MASK_FC \ + }, \ + /* Rear Center */ \ + [5] = { \ + .type = SND_CHN_T_BC, \ + .members = SND_CHN_T_MASK_BC \ + }, \ + [6] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_FC | SND_CHN_T_MASK_BC, \ + .offset = { 0, 1, 4, -1, 2, 3, -1, -1, 5, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_6_1 { \ + .id = SND_CHN_MATRIX_6_1, \ + .channels = 7, \ + .ext = 1, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_SL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_SR \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_SL \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_SR \ + }, \ + /* Center */ \ + [4] = { \ + .type = SND_CHN_T_FC, \ + .members = SND_CHN_T_MASK_FC \ + }, \ + /* LFE */ \ + [5] = { \ + .type = SND_CHN_T_LF, \ + .members = SND_CHN_T_MASK_LF \ + }, \ + /* Rear Center */ \ + [6] = { \ + .type = SND_CHN_T_BC, \ + .members = SND_CHN_T_MASK_BC \ + }, \ + [7] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_BC, \ + .offset = { 0, 1, 4, 5, 2, 3, -1, -1, 6, \ + -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_7_0 { \ + .id = SND_CHN_MATRIX_7_0, \ + .channels = 7, \ + .ext = 0, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = \ + SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = \ + SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_LF \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ + SND_CHN_T_MASK_LF \ + }, \ + /* Center */ \ + [4] = { \ + .type = SND_CHN_T_FC, \ + .members = \ + SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF \ + }, \ + /* Side Left */ \ + [5] = { \ + .type = SND_CHN_T_SL, \ + .members = \ + SND_CHN_T_MASK_SL | SND_CHN_T_MASK_LF \ + }, \ + /* Side Right */ \ + [6] = { \ + .type = SND_CHN_T_SR, \ + .members = \ + SND_CHN_T_MASK_SR | SND_CHN_T_MASK_LF \ + }, \ + [7] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_FC | \ + SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR, \ + .offset = { 0, 1, 4, -1, 2, 3, -1, -1, -1, \ + 5, 6, -1, -1, -1, -1, -1, -1, -1 } \ +} + +#define SND_CHN_MATRIX_MAP_7_1 { \ + .id = SND_CHN_MATRIX_7_1, \ + .channels = 8, \ + .ext = 1, \ + .map = { \ + /* Left */ \ + [0] = { \ + .type = SND_CHN_T_FL, \ + .members = SND_CHN_T_MASK_FL \ + }, \ + /* Right */ \ + [1] = { \ + .type = SND_CHN_T_FR, \ + .members = SND_CHN_T_MASK_FR \ + }, \ + /* Rear Left */ \ + [2] = { \ + .type = SND_CHN_T_BL, \ + .members = \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC \ + }, \ + /* Rear Right */ \ + [3] = { \ + .type = SND_CHN_T_BR, \ + .members = \ + SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC \ + }, \ + /* Center */ \ + [4] = { \ + .type = SND_CHN_T_FC, \ + .members = SND_CHN_T_MASK_FC \ + }, \ + /* LFE */ \ + [5] = { \ + .type = SND_CHN_T_LF, \ + .members = SND_CHN_T_MASK_LF \ + }, \ + /* Side Left */ \ + [6] = { \ + .type = SND_CHN_T_SL, \ + .members = SND_CHN_T_MASK_SL \ + }, \ + /* Side Right */ \ + [7] = { \ + .type = SND_CHN_T_SR, \ + .members = SND_CHN_T_MASK_SR \ + }, \ + [8] = { \ + .type = SND_CHN_T_MAX, \ + .members = 0 \ + } \ + }, \ + .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ + SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ + SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ + SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR, \ + .offset = { 0, 1, 4, 5, 2, 3, -1, -1, -1, \ + 6, 7, -1, -1, -1, -1, -1, -1, -1 } \ +} + #endif /* !_SND_MATRIX_H_ */ diff --git a/sys/dev/sound/pcm/matrix_map.h b/sys/dev/sound/pcm/matrix_map.h deleted file mode 100644 index ec0619614273..000000000000 --- a/sys/dev/sound/pcm/matrix_map.h +++ /dev/null @@ -1,672 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2009 Ariff Abdullah - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _SND_MATRIX_MAP_H_ -#define _SND_MATRIX_MAP_H_ - -/* - * Standard matrix maps: - * - * struct pcmchan_matrix { - * .id = Matrix identity (see matrix.h). Custom defined should use - * one of SND_CHN_MATRIX_MISC (for whatever purposes) or - * SND_CHN_MATRIX_DRV (hardware driver). - * .channels = Total number of channels, including whatever 'extended' - * (the X.ext notions, mostly LFE). - * .ext = Total number of extended channels (LFE). - * .map = { - * Sequences of channel type and interleave structure. - * [interleave offset] = { - * .type = channel type (see matrix.h). - * .members = Masks of channels that is acceptable as a - * member of this channel type. - * }, - * [total channels] = { - * .type = Maximum channels marker (SND_CHN_T_MAX). - * .members = 0 (no channels allowed here). - * }, - * }, - * .mask = Mask of channels that exist in this map. - * .offset = { - * channel offset that directly translate to the above interleave - * offset according to SND_CHN_T_* definitions. - * } - * }; - * - * Rule of thumb: Avoid using SND_CHN_T_* that is marked with XXX (matrix.h), - * or be prepared for the horror to come. - * - */ - -#define SND_CHN_MATRIX_MAP_1_0 { \ - .id = SND_CHN_MATRIX_1_0, \ - .channels = 1, \ - .ext = 0, \ - .map = { \ - /* Mono, center, etc. */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL | \ - SND_CHN_T_MASK_SR \ - }, \ - [1] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_FC, \ - .offset = { 0, 0, 0, 0, 0, 0, -1, -1, 0, \ - 0, 0, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_2_0 { \ - .id = SND_CHN_MATRIX_2_0, \ - .channels = 2, \ - .ext = 0, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ - SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ - }, \ - [2] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR, \ - .offset = { 0, 1, -1, -1, -1, -1, -1, -1, -1, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_2_1 { \ - .id = SND_CHN_MATRIX_2_1, \ - .channels = 3, \ - .ext = 1, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SR \ - }, \ - /* LFE */ \ - [2] = { \ - .type = SND_CHN_T_LF, \ - .members = SND_CHN_T_MASK_LF \ - }, \ - [3] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_LF, \ - .offset = { 0, 1, -1, 2, -1, -1, -1, -1, -1, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_3_0 { /* 3 channels default */ \ - .id = SND_CHN_MATRIX_3_0, \ - .channels = 3, \ - .ext = 0, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SR \ - }, \ - /* Rear Center */ \ - [2] = { \ - .type = SND_CHN_T_BC, \ - .members = \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR \ - }, \ - [3] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BC, \ - .offset = { 0, 1, -1, -1, -1, -1, -1, -1, 2, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_3_1 { \ - .id = SND_CHN_MATRIX_3_1, \ - .channels = 4, \ - .ext = 1, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_SR \ - }, \ - /* LFE */ \ - [2] = { \ - .type = SND_CHN_T_LF, \ - .members = SND_CHN_T_MASK_LF \ - }, \ - /* Rear Center */ \ - [3] = { \ - .type = SND_CHN_T_BC, \ - .members = \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR \ - }, \ - [4] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BC, \ - .offset = { 0, 1, -1, 2, -1, -1, -1, -1, 3, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_4_0 { \ - .id = SND_CHN_MATRIX_4_0, \ - .channels = 4, \ - .ext = 0, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_SR \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ - SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ - }, \ - [4] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR, \ - .offset = { 0, 1, -1, -1, 2, 3, -1, -1, -1, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_4_1 { \ - .id = SND_CHN_MATRIX_4_1, \ - .channels = 5, \ - .ext = 1, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_SR \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SR \ - }, \ - /* LFE */ \ - [4] = { \ - .type = SND_CHN_T_LF, \ - .members = SND_CHN_T_MASK_LF \ - }, \ - [5] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_LF, \ - .offset = { 0, 1, -1, 4, 2, 3, -1, -1, -1, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_5_0 { /* 5 channels default */ \ - .id = SND_CHN_MATRIX_5_0, \ - .channels = 5, \ - .ext = 0, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_SR \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL | \ - SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR \ - }, \ - /* Center */ \ - [4] = { \ - .type = SND_CHN_T_FC, \ - .members = SND_CHN_T_MASK_FC \ - }, \ - [5] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_FC, \ - .offset = { 0, 1, 4, -1, 2, 3, -1, -1, -1, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_5_1 { /* 6 channels default */ \ - .id = SND_CHN_MATRIX_5_1, \ - .channels = 6, \ - .ext = 1, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_SR \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_SR \ - }, \ - /* Center */ \ - [4] = { \ - .type = SND_CHN_T_FC, \ - .members = SND_CHN_T_MASK_FC \ - }, \ - /* LFE */ \ - [5] = { \ - .type = SND_CHN_T_LF, \ - .members = SND_CHN_T_MASK_LF \ - }, \ - [6] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF, \ - .offset = { 0, 1, 4, 5, 2, 3, -1, -1, -1, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_6_0 { \ - .id = SND_CHN_MATRIX_6_0, \ - .channels = 6, \ - .ext = 0, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_SR \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_SL \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_SR \ - }, \ - /* Center */ \ - [4] = { \ - .type = SND_CHN_T_FC, \ - .members = SND_CHN_T_MASK_FC \ - }, \ - /* Rear Center */ \ - [5] = { \ - .type = SND_CHN_T_BC, \ - .members = SND_CHN_T_MASK_BC \ - }, \ - [6] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_FC | SND_CHN_T_MASK_BC, \ - .offset = { 0, 1, 4, -1, 2, 3, -1, -1, 5, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_6_1 { \ - .id = SND_CHN_MATRIX_6_1, \ - .channels = 7, \ - .ext = 1, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_SL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_SR \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_SL \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_SR \ - }, \ - /* Center */ \ - [4] = { \ - .type = SND_CHN_T_FC, \ - .members = SND_CHN_T_MASK_FC \ - }, \ - /* LFE */ \ - [5] = { \ - .type = SND_CHN_T_LF, \ - .members = SND_CHN_T_MASK_LF \ - }, \ - /* Rear Center */ \ - [6] = { \ - .type = SND_CHN_T_BC, \ - .members = SND_CHN_T_MASK_BC \ - }, \ - [7] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_BC, \ - .offset = { 0, 1, 4, 5, 2, 3, -1, -1, 6, \ - -1, -1, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_7_0 { \ - .id = SND_CHN_MATRIX_7_0, \ - .channels = 7, \ - .ext = 0, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = \ - SND_CHN_T_MASK_FL | SND_CHN_T_MASK_LF \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = \ - SND_CHN_T_MASK_FR | SND_CHN_T_MASK_LF \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_LF \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC | \ - SND_CHN_T_MASK_LF \ - }, \ - /* Center */ \ - [4] = { \ - .type = SND_CHN_T_FC, \ - .members = \ - SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF \ - }, \ - /* Side Left */ \ - [5] = { \ - .type = SND_CHN_T_SL, \ - .members = \ - SND_CHN_T_MASK_SL | SND_CHN_T_MASK_LF \ - }, \ - /* Side Right */ \ - [6] = { \ - .type = SND_CHN_T_SR, \ - .members = \ - SND_CHN_T_MASK_SR | SND_CHN_T_MASK_LF \ - }, \ - [7] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_FC | \ - SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR, \ - .offset = { 0, 1, 4, -1, 2, 3, -1, -1, -1, \ - 5, 6, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#define SND_CHN_MATRIX_MAP_7_1 { \ - .id = SND_CHN_MATRIX_7_1, \ - .channels = 8, \ - .ext = 1, \ - .map = { \ - /* Left */ \ - [0] = { \ - .type = SND_CHN_T_FL, \ - .members = SND_CHN_T_MASK_FL \ - }, \ - /* Right */ \ - [1] = { \ - .type = SND_CHN_T_FR, \ - .members = SND_CHN_T_MASK_FR \ - }, \ - /* Rear Left */ \ - [2] = { \ - .type = SND_CHN_T_BL, \ - .members = \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BC \ - }, \ - /* Rear Right */ \ - [3] = { \ - .type = SND_CHN_T_BR, \ - .members = \ - SND_CHN_T_MASK_BR | SND_CHN_T_MASK_BC \ - }, \ - /* Center */ \ - [4] = { \ - .type = SND_CHN_T_FC, \ - .members = SND_CHN_T_MASK_FC \ - }, \ - /* LFE */ \ - [5] = { \ - .type = SND_CHN_T_LF, \ - .members = SND_CHN_T_MASK_LF \ - }, \ - /* Side Left */ \ - [6] = { \ - .type = SND_CHN_T_SL, \ - .members = SND_CHN_T_MASK_SL \ - }, \ - /* Side Right */ \ - [7] = { \ - .type = SND_CHN_T_SR, \ - .members = SND_CHN_T_MASK_SR \ - }, \ - [8] = { \ - .type = SND_CHN_T_MAX, \ - .members = 0 \ - } \ - }, \ - .mask = SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FR | \ - SND_CHN_T_MASK_BL | SND_CHN_T_MASK_BR | \ - SND_CHN_T_MASK_FC | SND_CHN_T_MASK_LF | \ - SND_CHN_T_MASK_SL | SND_CHN_T_MASK_SR, \ - .offset = { 0, 1, 4, 5, 2, 3, -1, -1, -1, \ - 6, 7, -1, -1, -1, -1, -1, -1, -1 } \ -} - -#endif /* !_SND_MATRIX_MAP_H_ */ diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h index ff2b618adff8..abbfc1111805 100644 --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -1,521 +1,520 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2005-2009 Ariff Abdullah * Copyright (c) 1999 Cameron Grant * Copyright (c) 1995 Hannu Savolainen * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * first, include kernel header files. */ #ifndef _OS_H_ #define _OS_H_ #ifdef _KERNEL #include #include #include #include #include #include #include #include #include #include /* for DATA_SET */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef KOBJMETHOD_END #define KOBJMETHOD_END { NULL, NULL } #endif struct pcm_channel; struct pcm_feeder; struct snd_dbuf; struct snd_mixer; #include #include -#include #include #include #include #include #include #define PCM_SOFTC_SIZE (sizeof(struct snddev_info)) #define SND_STATUSLEN 64 #define SOUND_MODVER 5 #define SOUND_MINVER SOUND_MODVER #define SOUND_PREFVER SOUND_MODVER #define SOUND_MAXVER SOUND_MODVER #define SND_MAXVCHANS 256 #define SD_F_SIMPLEX 0x00000001 #define SD_F_AUTOVCHAN 0x00000002 #define SD_F_SOFTPCMVOL 0x00000004 #define SD_F_BUSY 0x00000008 #define SD_F_MPSAFE 0x00000010 #define SD_F_REGISTERED 0x00000020 #define SD_F_BITPERFECT 0x00000040 #define SD_F_VPC 0x00000080 /* volume-per-channel */ #define SD_F_EQ 0x00000100 /* EQ */ #define SD_F_EQ_ENABLED 0x00000200 /* EQ enabled */ #define SD_F_EQ_BYPASSED 0x00000400 /* EQ bypassed */ #define SD_F_EQ_PC 0x00000800 /* EQ per-channel */ #define SD_F_EQ_DEFAULT (SD_F_EQ | SD_F_EQ_ENABLED) #define SD_F_EQ_MASK (SD_F_EQ | SD_F_EQ_ENABLED | \ SD_F_EQ_BYPASSED | SD_F_EQ_PC) #define SD_F_PRIO_RD 0x10000000 #define SD_F_PRIO_WR 0x20000000 #define SD_F_BITS "\020" \ "\001SIMPLEX" \ "\002AUTOVCHAN" \ "\003SOFTPCMVOL" \ "\004BUSY" \ "\005MPSAFE" \ "\006REGISTERED" \ "\007BITPERFECT" \ "\010VPC" \ "\011EQ" \ "\012EQ_ENABLED" \ "\013EQ_BYPASSED" \ "\014EQ_PC" \ "\035PRIO_RD" \ "\036PRIO_WR" #define PCM_ALIVE(x) ((x) != NULL && (x)->lock != NULL) #define PCM_REGISTERED(x) (PCM_ALIVE(x) && ((x)->flags & SD_F_REGISTERED)) #define PCM_CHANCOUNT(d) \ (d->playcount + d->pvchancount + d->reccount + d->rvchancount) /* many variables should be reduced to a range. Here define a macro */ #define RANGE(var, low, high) (var) = \ (((var)<(low))? (low) : ((var)>(high))? (high) : (var)) /* make figuring out what a format is easier. got AFMT_STEREO already */ #define AFMT_32BIT (AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE) #define AFMT_24BIT (AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE) #define AFMT_16BIT (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE) #define AFMT_G711 (AFMT_MU_LAW | AFMT_A_LAW) #define AFMT_8BIT (AFMT_G711 | AFMT_U8 | AFMT_S8) #define AFMT_SIGNED (AFMT_S32_LE | AFMT_S32_BE | AFMT_S24_LE | AFMT_S24_BE | \ AFMT_S16_LE | AFMT_S16_BE | AFMT_S8) #define AFMT_BIGENDIAN (AFMT_S32_BE | AFMT_U32_BE | AFMT_S24_BE | AFMT_U24_BE | \ AFMT_S16_BE | AFMT_U16_BE) #define AFMT_CONVERTIBLE (AFMT_8BIT | AFMT_16BIT | AFMT_24BIT | \ AFMT_32BIT) /* Supported vchan mixing formats */ #define AFMT_VCHAN (AFMT_CONVERTIBLE & ~AFMT_G711) #define AFMT_PASSTHROUGH AFMT_AC3 #define AFMT_PASSTHROUGH_RATE 48000 #define AFMT_PASSTHROUGH_CHANNEL 2 #define AFMT_PASSTHROUGH_EXTCHANNEL 0 /* * We're simply using unused, contiguous bits from various AFMT_ definitions. * ~(0xb00ff7ff) */ #define AFMT_ENCODING_MASK 0xf00fffff #define AFMT_CHANNEL_MASK 0x07f00000 #define AFMT_CHANNEL_SHIFT 20 #define AFMT_CHANNEL_MAX 0x7f #define AFMT_EXTCHANNEL_MASK 0x08000000 #define AFMT_EXTCHANNEL_SHIFT 27 #define AFMT_EXTCHANNEL_MAX 1 #define AFMT_ENCODING(v) ((v) & AFMT_ENCODING_MASK) #define AFMT_EXTCHANNEL(v) (((v) & AFMT_EXTCHANNEL_MASK) >> \ AFMT_EXTCHANNEL_SHIFT) #define AFMT_CHANNEL(v) (((v) & AFMT_CHANNEL_MASK) >> \ AFMT_CHANNEL_SHIFT) #define AFMT_BIT(v) (((v) & AFMT_32BIT) ? 32 : \ (((v) & AFMT_24BIT) ? 24 : \ ((((v) & AFMT_16BIT) || \ ((v) & AFMT_PASSTHROUGH)) ? 16 : 8))) #define AFMT_BPS(v) (AFMT_BIT(v) >> 3) #define AFMT_ALIGN(v) (AFMT_BPS(v) * AFMT_CHANNEL(v)) #define SND_FORMAT(f, c, e) (AFMT_ENCODING(f) | \ (((c) << AFMT_CHANNEL_SHIFT) & \ AFMT_CHANNEL_MASK) | \ (((e) << AFMT_EXTCHANNEL_SHIFT) & \ AFMT_EXTCHANNEL_MASK)) #define AFMT_U8_NE AFMT_U8 #define AFMT_S8_NE AFMT_S8 #define AFMT_SIGNED_NE (AFMT_S8_NE | AFMT_S16_NE | AFMT_S24_NE | AFMT_S32_NE) #define AFMT_NE (AFMT_SIGNED_NE | AFMT_U8_NE | AFMT_U16_NE | \ AFMT_U24_NE | AFMT_U32_NE) enum { SND_DEV_CTL = 0, /* Control port /dev/mixer */ SND_DEV_SEQ, /* Sequencer /dev/sequencer */ SND_DEV_MIDIN, /* Raw midi access */ SND_DEV_DSP, /* Digitized voice /dev/dsp */ SND_DEV_STATUS, /* /dev/sndstat */ }; #define DSP_DEFAULT_SPEED 8000 extern int snd_unit; extern int snd_verbose; extern devclass_t pcm_devclass; extern struct unrhdr *pcmsg_unrhdr; #ifndef DEB #define DEB(x) #endif SYSCTL_DECL(_hw_snd); int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, pid_t pid, char *comm); int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo); unsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz); void pcm_init(device_t dev, void *devinfo); int pcm_register(device_t dev, char *str); int pcm_unregister(device_t dev); u_int32_t pcm_getflags(device_t dev); void pcm_setflags(device_t dev, u_int32_t val); void *pcm_getdevinfo(device_t dev); int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep); void *snd_mtxcreate(const char *desc, const char *type); void snd_mtxfree(void *m); void snd_mtxassert(void *m); #define snd_mtxlock(m) mtx_lock(m) #define snd_mtxunlock(m) mtx_unlock(m) int sndstat_register(device_t dev, char *str); int sndstat_unregister(device_t dev); /* These are the function codes assigned to the children of sound cards. */ enum { SCF_PCM, SCF_MIDI, SCF_SYNTH, }; /* * This is the device information struct, used by a bridge device to pass the * device function code to the children. */ struct sndcard_func { int func; /* The function code. */ void *varinfo; /* Bridge-specific information. */ }; /* * this is rather kludgey- we need to duplicate these struct def'ns from sound.c * so that the macro versions of pcm_{,un}lock can dereference them. * we also have to do this now makedev() has gone away. */ struct snddev_info { struct { struct { SLIST_HEAD(, pcm_channel) head; struct { SLIST_HEAD(, pcm_channel) head; } busy; struct { SLIST_HEAD(, pcm_channel) head; } opened; } pcm; } channels; unsigned playcount, reccount, pvchancount, rvchancount; unsigned flags; unsigned int bufsz; void *devinfo; device_t dev; char status[SND_STATUSLEN]; struct mtx *lock; struct cdev *mixer_dev; struct cdev *dsp_dev; uint32_t pvchanrate, pvchanformat; uint32_t rvchanrate, rvchanformat; int32_t eqpreamp; struct sysctl_ctx_list play_sysctl_ctx, rec_sysctl_ctx; struct sysctl_oid *play_sysctl_tree, *rec_sysctl_tree; struct cv cv; struct unrhdr *p_unr; struct unrhdr *vp_unr; struct unrhdr *r_unr; struct unrhdr *vr_unr; }; void sound_oss_sysinfo(oss_sysinfo *); int sound_oss_card_info(oss_card_info *); #define PCM_MODE_MIXER 0x01 #define PCM_MODE_PLAY 0x02 #define PCM_MODE_REC 0x04 #define PCM_LOCKOWNED(d) mtx_owned((d)->lock) #define PCM_LOCK(d) mtx_lock((d)->lock) #define PCM_UNLOCK(d) mtx_unlock((d)->lock) #define PCM_TRYLOCK(d) mtx_trylock((d)->lock) #define PCM_LOCKASSERT(d) mtx_assert((d)->lock, MA_OWNED) #define PCM_UNLOCKASSERT(d) mtx_assert((d)->lock, MA_NOTOWNED) /* * For PCM_[WAIT | ACQUIRE | RELEASE], be sure to surround these * with PCM_LOCK/UNLOCK() sequence, or I'll come to gnaw upon you! */ #ifdef SND_DIAGNOSTIC #define PCM_WAIT(x) do { \ if (!PCM_LOCKOWNED(x)) \ panic("%s(%d): [PCM WAIT] Mutex not owned!", \ __func__, __LINE__); \ while ((x)->flags & SD_F_BUSY) { \ if (snd_verbose > 3) \ device_printf((x)->dev, \ "%s(%d): [PCM WAIT] calling cv_wait().\n", \ __func__, __LINE__); \ cv_wait(&(x)->cv, (x)->lock); \ } \ } while (0) #define PCM_ACQUIRE(x) do { \ if (!PCM_LOCKOWNED(x)) \ panic("%s(%d): [PCM ACQUIRE] Mutex not owned!", \ __func__, __LINE__); \ if ((x)->flags & SD_F_BUSY) \ panic("%s(%d): [PCM ACQUIRE] " \ "Trying to acquire BUSY cv!", __func__, __LINE__); \ (x)->flags |= SD_F_BUSY; \ } while (0) #define PCM_RELEASE(x) do { \ if (!PCM_LOCKOWNED(x)) \ panic("%s(%d): [PCM RELEASE] Mutex not owned!", \ __func__, __LINE__); \ if ((x)->flags & SD_F_BUSY) { \ (x)->flags &= ~SD_F_BUSY; \ if ((x)->cv.cv_waiters != 0) { \ if ((x)->cv.cv_waiters > 1 && snd_verbose > 3) \ device_printf((x)->dev, \ "%s(%d): [PCM RELEASE] " \ "cv_waiters=%d > 1!\n", \ __func__, __LINE__, \ (x)->cv.cv_waiters); \ cv_broadcast(&(x)->cv); \ } \ } else \ panic("%s(%d): [PCM RELEASE] Releasing non-BUSY cv!", \ __func__, __LINE__); \ } while (0) /* Quick version, for shorter path. */ #define PCM_ACQUIRE_QUICK(x) do { \ if (PCM_LOCKOWNED(x)) \ panic("%s(%d): [PCM ACQUIRE QUICK] Mutex owned!", \ __func__, __LINE__); \ PCM_LOCK(x); \ PCM_WAIT(x); \ PCM_ACQUIRE(x); \ PCM_UNLOCK(x); \ } while (0) #define PCM_RELEASE_QUICK(x) do { \ if (PCM_LOCKOWNED(x)) \ panic("%s(%d): [PCM RELEASE QUICK] Mutex owned!", \ __func__, __LINE__); \ PCM_LOCK(x); \ PCM_RELEASE(x); \ PCM_UNLOCK(x); \ } while (0) #define PCM_BUSYASSERT(x) do { \ if (!((x) != NULL && ((x)->flags & SD_F_BUSY))) \ panic("%s(%d): [PCM BUSYASSERT] " \ "Failed, snddev_info=%p", __func__, __LINE__, x); \ } while (0) #define PCM_GIANT_ENTER(x) do { \ int _pcm_giant = 0; \ if (PCM_LOCKOWNED(x)) \ panic("%s(%d): [GIANT ENTER] PCM lock owned!", \ __func__, __LINE__); \ if (mtx_owned(&Giant) != 0 && snd_verbose > 3) \ device_printf((x)->dev, \ "%s(%d): [GIANT ENTER] Giant owned!\n", \ __func__, __LINE__); \ if (!((x)->flags & SD_F_MPSAFE) && mtx_owned(&Giant) == 0) \ do { \ mtx_lock(&Giant); \ _pcm_giant = 1; \ } while (0) #define PCM_GIANT_EXIT(x) do { \ if (PCM_LOCKOWNED(x)) \ panic("%s(%d): [GIANT EXIT] PCM lock owned!", \ __func__, __LINE__); \ if (!(_pcm_giant == 0 || _pcm_giant == 1)) \ panic("%s(%d): [GIANT EXIT] _pcm_giant screwed!", \ __func__, __LINE__); \ if ((x)->flags & SD_F_MPSAFE) { \ if (_pcm_giant == 1) \ panic("%s(%d): [GIANT EXIT] MPSAFE Giant?", \ __func__, __LINE__); \ if (mtx_owned(&Giant) != 0 && snd_verbose > 3) \ device_printf((x)->dev, \ "%s(%d): [GIANT EXIT] Giant owned!\n", \ __func__, __LINE__); \ } \ if (_pcm_giant != 0) { \ if (mtx_owned(&Giant) == 0) \ panic("%s(%d): [GIANT EXIT] Giant not owned!", \ __func__, __LINE__); \ _pcm_giant = 0; \ mtx_unlock(&Giant); \ } \ } while (0) #else /* !SND_DIAGNOSTIC */ #define PCM_WAIT(x) do { \ PCM_LOCKASSERT(x); \ while ((x)->flags & SD_F_BUSY) \ cv_wait(&(x)->cv, (x)->lock); \ } while (0) #define PCM_ACQUIRE(x) do { \ PCM_LOCKASSERT(x); \ KASSERT(!((x)->flags & SD_F_BUSY), \ ("%s(%d): [PCM ACQUIRE] Trying to acquire BUSY cv!", \ __func__, __LINE__)); \ (x)->flags |= SD_F_BUSY; \ } while (0) #define PCM_RELEASE(x) do { \ PCM_LOCKASSERT(x); \ KASSERT((x)->flags & SD_F_BUSY, \ ("%s(%d): [PCM RELEASE] Releasing non-BUSY cv!", \ __func__, __LINE__)); \ (x)->flags &= ~SD_F_BUSY; \ if ((x)->cv.cv_waiters != 0) \ cv_broadcast(&(x)->cv); \ } while (0) /* Quick version, for shorter path. */ #define PCM_ACQUIRE_QUICK(x) do { \ PCM_UNLOCKASSERT(x); \ PCM_LOCK(x); \ PCM_WAIT(x); \ PCM_ACQUIRE(x); \ PCM_UNLOCK(x); \ } while (0) #define PCM_RELEASE_QUICK(x) do { \ PCM_UNLOCKASSERT(x); \ PCM_LOCK(x); \ PCM_RELEASE(x); \ PCM_UNLOCK(x); \ } while (0) #define PCM_BUSYASSERT(x) KASSERT(x != NULL && \ ((x)->flags & SD_F_BUSY), \ ("%s(%d): [PCM BUSYASSERT] " \ "Failed, snddev_info=%p", \ __func__, __LINE__, x)) #define PCM_GIANT_ENTER(x) do { \ int _pcm_giant = 0; \ PCM_UNLOCKASSERT(x); \ if (!((x)->flags & SD_F_MPSAFE) && mtx_owned(&Giant) == 0) \ do { \ mtx_lock(&Giant); \ _pcm_giant = 1; \ } while (0) #define PCM_GIANT_EXIT(x) do { \ PCM_UNLOCKASSERT(x); \ KASSERT(_pcm_giant == 0 || _pcm_giant == 1, \ ("%s(%d): [GIANT EXIT] _pcm_giant screwed!", \ __func__, __LINE__)); \ KASSERT(!((x)->flags & SD_F_MPSAFE) || \ (((x)->flags & SD_F_MPSAFE) && _pcm_giant == 0), \ ("%s(%d): [GIANT EXIT] MPSAFE Giant?", \ __func__, __LINE__)); \ if (_pcm_giant != 0) { \ mtx_assert(&Giant, MA_OWNED); \ _pcm_giant = 0; \ mtx_unlock(&Giant); \ } \ } while (0) #endif /* SND_DIAGNOSTIC */ #define PCM_GIANT_LEAVE(x) \ PCM_GIANT_EXIT(x); \ } while (0) #endif /* _KERNEL */ #endif /* _OS_H_ */