DevCodec.cpp revision c7d7b8e996fc676c71441361102c88e997c1267e
/* $Id$ */
/** @file
* DevCodec - VBox ICH Intel HD Audio Codec.
*/
/*
* Copyright (C) 2006-2008 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#define LOG_GROUP LOG_GROUP_DEV_AUDIO
#include "VBoxDD.h"
extern "C" {
#include "audio.h"
}
#include "DevCodec.h"
#define CODECNODE_F0_PARAM_LENGTH 0x14
#define CODECNODE_F02_PARAM_LENGTH 16
typedef struct CODECCOMMONNODE
{
const char *name;
/* RPM 5.3.6 */
typedef struct ROOTCODECNODE
{
#define AMPLIFIER_SIZE 60
#define AMPLIFIER_IN 0
#define AMPLIFIER_OUT 1
#define AMPLIFIER_LEFT 1
#define AMPLIFIER_RIGHT 0
typedef struct DACNODE
{
typedef struct ADCNODE
{
typedef struct SPDIFOUTNODE
{
typedef struct SPDIFINNODE
{
} SPDIFINNODE, *PSPDIFINNODE;
typedef struct AFGCODECNODE
{
typedef struct PORTNODE
{
typedef struct DIGOUTNODE
{
} DIGOUTNODE, *PDIGOUTNODE;
typedef struct DIGINNODE
{
} DIGINNODE, *PDIGINNODE;
typedef struct ADCMUXNODE
{
} ADCMUXNODE, *PADCMUXNODE;
typedef struct PCBEEPNODE
{
} PCBEEPNODE, *PPCBEEPNODE;
typedef struct CDNODE
{
typedef struct VOLUMEKNOBNODE
{
typedef struct ADCVOLNODE
{
} ADCVOLNODE, *PADCVOLNODE;
typedef struct RESNODE
{
typedef union CODECNODE
{
} CODECNODE, *PCODECNODE;
/* STAC9220 */
{
return VINF_SUCCESS;
}
{
switch (nodenum)
{
/* Root Node*/
case 0:
break;
case 1:
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//(17 << 8)|RT_BIT(6)|RT_BIT(5)|RT_BIT(2)|RT_BIT(1)|RT_BIT(0);
pNode->node.au32F00_param[0xD] = CODEC_MAKE_F00_0D(1, 0x5, 0xE, 0);//RT_BIT(31)|(0x5 << 16)|(0xE)<<8;
pNode->afg.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D2, CODEC_F05_D2);//0x2 << 4| 0x2; /* PS-Act: D3, PS->Set D3 */
break;
case 2:
goto dac_init;
case 3:
goto dac_init;
case 4:
goto dac_init;
case 5:
pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 4)|0x1; /* 441000Hz/16bit/2ch */
| CODEC_F00_09_CAP_LSB;//(0xD << 16) | RT_BIT(11) | RT_BIT(10) | RT_BIT(2) | RT_BIT(0);
pNode->dac.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3, Set: D3 */
break;
case 6:
goto adc_init;
case 7:
pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//RT_BIT(14)|(0x1 << 3)|0x1; /* 441000Hz/16bit/2ch */
pNode->adc.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 Set: D3 */
| CODEC_F00_09_CAP_LSB;//RT_BIT(20)| (0xd << 16) | RT_BIT(10) | RT_BIT(8) | RT_BIT(6)| RT_BIT(0);
break;
case 8:
pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
| CODEC_F00_09_CAP_LSB;//(4 << 16) | RT_BIT(9)|RT_BIT(4)|0x1;
break;
case 9:
pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(0x1<<4) | 0x1;
| CODEC_F00_09_CAP_LSB;//(0x1 << 20)|(4 << 16) | RT_BIT(9)| RT_BIT(8)|RT_BIT(4)|0x1;
break;
case 0xA:
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x173f;
0x2, 0);//RT_MAKE_U32_FROM_U8(0x20, 0x40, 0x21, 0x02);
goto port_init;
case 0xB:
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
0x1, 0x1);//RT_MAKE_U32_FROM_U8(0x11, 0x60, 0x11, 0x01);
goto port_init;
case 0xC:
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
0x0, 0x1, 0x0);//RT_MAKE_U32_FROM_U8(0x10, 0x40, 0x11, 0x01);
goto port_init;
case 0xD:
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE;//0x1737;
0x0, 0x5, 0x0);//RT_MAKE_U32_FROM_U8(0x50, 0x90, 0xA1, 0x02); /* Microphone */
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(0);
break;
case 0xE:
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(7)|RT_BIT(0);
| CODEC_F00_0C_CAP_PRESENSE_DETECT;//0x34;
0x0, 0x4, 0x0);//0x01013040; /* Line Out */
break;
case 0xF:
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(8)|RT_BIT(7)|RT_BIT(2)|RT_BIT(0);
/* | CODEC_F00_0C_CAP_TRIGGER_REQUIRED
| CODEC_F00_0C_CAP_IMPENDANCE_SENSE */;//0x37;
0x0, 0x1, 0x2);//RT_MAKE_U32_FROM_U8(0x12, 0x60, 0x11, 0x01);
break;
case 0x10:
| CODEC_F00_09_CAP_LSB;//(4<<20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
0x0, 0x3, 0x0);//RT_MAKE_U32_FROM_U8(0x30, 0x10, 0x45, 0x01);
break;
case 0x11:
| CODEC_F00_0C_CAP_PRESENSE_DETECT;//RT_BIT(16)| RT_BIT(5)|RT_BIT(2);
pNode->digin.u32F05_param = CODEC_MAKE_F05(0, 0, 0, CODEC_F05_D3, CODEC_F05_D3);//0x3 << 4 | 0x3; /* PS-Act: D3 -> D3 */
0x0, 0x6, 0x0);//(0x1 << 24) | (0xc5 << 16) | (0x10 << 8) | 0x60;
break;
case 0x12:
goto adcmux_init;
case 0x13:
| CODEC_F00_09_CAP_LSB;//(3<<20)|RT_BIT(8)|RT_BIT(3)|RT_BIT(2)|RT_BIT(0);
/* STAC 9220 v10 6.21-22.{4,5} both(left and right) out amplefiers inited with 0*/
break;
case 0x14:
| CODEC_F00_09_CAP_OUT_AMP_PRESENT;//(7 << 20) | RT_BIT(3) | RT_BIT(2);
break;
case 0x15:
| CODEC_F00_09_CAP_LSB;//(4 << 20)|RT_BIT(0);
0x0, 0x7, 0x0);//RT_MAKE_U32_FROM_U8(0x70, 0x0, 0x33, 0x90);
break;
case 0x16:
pNode->node.au32F00_param[0x9] = CODEC_MAKE_F00_09(CODEC_F00_09_TYPE_VOLUME_KNOB, 0x0, 0x0);//(0x6 << 20);
break;
case 0x17:
goto adcvol_init;
case 0x18:
| CODEC_F00_09_CAP_LSB;//(0x3 << 20)|RT_BIT(11)|RT_BIT(8)|RT_BIT(1)|RT_BIT(0);
break;
case 0x19:
| CODEC_F00_09_CAP_LSB;//(0xF << 20)|(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
break;
case 0x1A:
| CODEC_F00_09_CAP_LSB;//(0x3 << 16)|RT_BIT(9)|RT_BIT(0);
break;
case 0x1B:
| CODEC_F00_09_CAP_LSB;//(0x4 << 20)|RT_BIT(9)|RT_BIT(8)|RT_BIT(0);
0x0, 0x0, 0xf);//0x4000000f;
break;
default:
break;
}
return VINF_SUCCESS;
}
/* ALC885 */
{
/* @todo: test more */
return VINF_SUCCESS;
}
{
switch (nodenum)
{
case 0: /* Root */
break;
case 0x1: /* AFG */
break;
/* DACs */
case 0x2:
goto dac_init;
case 0x3:
goto dac_init;
case 0x4:
goto dac_init;
case 0x5:
goto dac_init;
case 0x25:
pNode->dac.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
break;
/* SPDIFs */
case 0x6:
pNode->spdifout.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
break;
case 0xA:
pNode->spdifin.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
break;
/* VENDOR DEFINE */
case 0x10:
goto vendor_define_init;
case 0x11:
goto vendor_define_init;
case 0x12:
goto vendor_define_init;
case 0x13:
goto vendor_define_init;
case 0x20:
break;
/* DIGPIN */
case 0x1E:
/* N = 0~3 */
break;
case 0x1F:
/* N = 0~3 */
break;
/* ADCs */
case 0x7:
goto adc_init;
break;
case 0x8:
goto adc_init;
break;
case 0x9:
pNode->adc.u32A_param = CODEC_MAKE_A(0, 1, CODEC_A_MULT_1X, CODEC_A_DIV_1X, CODEC_A_16_BIT, 1);//(1<<14)|(0x1<<4) | 0x1;
break;
/* Ports */
case 0x14:
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
goto port_init;
break;
case 0x15:
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
goto port_init;
break;
case 0x16:
goto port_init;
break;
case 0x17:
goto port_init;
break;
case 0x18:
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
goto port_init;
break;
case 0x19:
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
goto port_init;
break;
case 0x1A:
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
goto port_init;
break;
case 0x1B:
pNode->node.au32F00_param[0xC] = RT_BIT(13)|RT_BIT(12)|RT_BIT(11)|RT_BIT(10)|RT_BIT(9)|RT_BIT(8)|RT_BIT(5)|RT_BIT(4)|RT_BIT(3)|RT_BIT(2);
/* N = 0~3 */
/* N = 4~7 */
break;
/* ADCVols */
case 0x26:
break;
case 0xF:
break;
case 0xE:
break;
case 0xD:
break;
case 0xC:
break;
case 0xB:
/* N = 0~3 */
/* N = 4~7 */
/* N = 8~11 */
break;
/* AdcMuxs */
case 0x22:
goto adc_mux_init;
case 0x23:
/* N = 0~3 */
/* N = 4~7 */
/* N = 8~11 */
break;
case 0x24:
/* N = 0~3 */
/* N = 4~7 */
/* N = 8~11 */
break;
/* PCBEEP */
case 0x1D:
break;
/* CD */
case 0x1C:
break;
case 0x21:
break;
default:
AssertMsgFailed(("Unsupported Node"));
}
return VINF_SUCCESS;
}
/* generic */
#define DECLISNODEOFTYPE(type) \
{ \
return 1; \
return 0; \
}
/* codecIsPortNode */
/* codecIsDacNode */
/* codecIsAdcVolNode */
/* codecIsAdcNode */
/* codecIsAdcMuxNode */
/* codecIsPcbeepNode */
/* codecIsSpdifOutNode */
/* codecIsSpdifInNode */
/* codecIsDigInPinNode */
/* codecIsDigOutPinNode */
/* codecIsCdNode */
/* codecIsVolKnobNode */
/* codecIsReservedNode */
static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd, uint8_t u8Offset, uint32_t mask)
{
}
{
}
{
}
{
*pResp = 0;
return VINF_SUCCESS;
}
{
int rc;
return rc;
}
/* B-- */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
/* HDA spec 7.3.3.7 Note A */
/* @todo: if index out of range response should be 0 */
u8Index);
u8Index);
u8Index);
u8Index);
u8Index);
u8Index);
else{
AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS);
}
return VINF_SUCCESS;
}
/* 3-- */
{
bool fIsLeft = false;
bool fIsRight = false;
bool fIsOut = false;
bool fIsIn = false;
{
return VINF_SUCCESS;
}
*pResp = 0;
if (pAmplifier)
{
return VINF_SUCCESS;
if (fIsIn)
{
if (fIsLeft)
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd, 0);
if (fIsRight)
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd, 0);
}
if (fIsOut)
{
if (fIsLeft)
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd, 0);
if (fIsRight)
codecSetRegisterU8(&LIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd, 0);
}
}
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* F01 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* 701 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
if (pu32Reg)
return VINF_SUCCESS;
}
/* F07 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
else
AssertMsgFailed(("Unsupported"));
return VINF_SUCCESS;
}
/* 707 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
if (pu32Reg)
return VINF_SUCCESS;
}
/* F08 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
else
return VINF_SUCCESS;
}
/* 708 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
else
if(pu32Reg)
return VINF_SUCCESS;
}
/* F09 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
else
return VINF_SUCCESS;
}
/* 709 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
if(pu32Reg)
return VINF_SUCCESS;
}
{
*pResp = 0;
{
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
}
return VINF_SUCCESS;
}
/* F03 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* 703 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
{
}
return VINF_SUCCESS;
}
/* F0D */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
static int codecSetDigitalConverter(struct CODECState *pState, uint32_t cmd, uint8_t u8Offset, uint64_t *pResp)
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* 70D */
{
}
/* 70E */
{
}
/* F20 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
{
}
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
if (pu32Reg)
return VINF_SUCCESS;
}
/* 720 */
{
*pResp = 0;
}
/* 721 */
{
*pResp = 0;
}
/* 722 */
{
*pResp = 0;
}
/* 723 */
{
*pResp = 0;
}
{
{
uint8_t i;
Log(("HDAcodec: enters reset\n"));
for (i = 0; i < pState->cTotalNodes; ++i)
{
}
Log(("HDAcodec: exits reset\n"));
}
*pResp = 0;
return VINF_SUCCESS;
}
/* F05 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* 705 */
{
if (!pu32F05_param)
return;
}
{
{
return VINF_SUCCESS;
}
*pResp = 0;
if (!pu32Reg)
return VINF_SUCCESS;
{
/*
* We shouldn't propogate actual power state, which actual for AFG
*/
CODEC_F05_SET(cmd));
}
/* Propagate next power state only if AFG is on or verb modifies AFG power state */
{
{
/* now we're powered on AFG and may propogate power states on nodes */
while (*(++pu8NodeIndex))
while (*(++pu8NodeIndex))
while (*(++pu8NodeIndex))
}
}
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
*pResp = 0;
*pResp = 0;
if (pu32addr)
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* F0C */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* 70C */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
*pResp = 0;
if (pu32Reg)
return VINF_SUCCESS;
}
/* F0F */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
/* 70F */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
if (pu32Reg)
return VINF_SUCCESS;
}
/* F17 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
/* note: this is true for ALC885 */
return VINF_SUCCESS;
}
/* 717 */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
if (pu32Reg)
return VINF_SUCCESS;
}
/* F1C */
{
{
return VINF_SUCCESS;
}
*pResp = 0;
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
if (pu32Reg)
return VINF_SUCCESS;
}
/* 71C */
{
*pResp = 0;
}
/* 71D */
{
*pResp = 0;
}
/* 71E */
{
*pResp = 0;
}
/* 71E */
{
*pResp = 0;
}
{
switch (mt)
{
case AUD_MIXER_VOLUME:
case AUD_MIXER_PCM:
dir = AMPLIFIER_OUT;
break;
case AUD_MIXER_LINE_IN:
dir = AMPLIFIER_IN;
break;
}
mute >>=7;
mute &= 0x1;
return VINF_SUCCESS;
}
static CODECVERB CODECVERBS[] =
{
/* verb | verb mask | callback */
/* ----------- -------------------- ----------------------- */
};
{
int rc = VINF_SUCCESS;
{
}
if ( CODEC_VERBDATA(cmd) == 0
{
//** @todo r=michaln: There needs to be a counter to avoid log flooding (see e.g. DevRTC.cpp)
return VINF_SUCCESS;
}
{
{
return VINF_SUCCESS;
}
}
return rc;
}
{
}
{
}
{
}
{
int rc;
switch (enmCodec)
{
case STAC9220_CODEC:
break;
case ALC885_CODEC:
break;
default:
AssertMsgFailed(("Unsupported Codec"));
}
/* common root node initializers */
pState->pNodes[0].node.au32F00_param[0] = CODEC_MAKE_F00_00(pState->u16VendorId, pState->u16DeviceId);
/* common AFG node initializers */
pState->pNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pState->u16VendorId, pState->u8BSKU, pState->u8AssemblyId);
//** @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)
/* 44.1 kHz */
as.endianness = 0;
do{ \
AUDIO_FORMAT_SELECTOR(pState, Out, (base), (mult), (div)), name ".out", (pState), (out_callback), &(as)); \
AUDIO_FORMAT_SELECTOR(pState, In, (base), (mult), (div)), name ".in", (pState), (in_callback), &(as)); \
} while(0)
#define IS_FORMAT_SUPPORTED_BY_HOST(pState, base, mult, div) (AUDIO_FORMAT_SELECTOR((pState), Out, (base), (mult), (div)) \
SETUP_AUDIO_FORMAT(pState, AFMT_HZ_44_1K, AFMT_MULT_X1, AFMT_DIV_X1, "hda44_1", as, pi_callback, po_callback);
pState->pNodes[1].node.au32F00_param[0xA] |= IS_FORMAT_SUPPORTED_BY_HOST(pState, AFMT_HZ_44_1K, AFMT_MULT_X1, AFMT_DIV_X1) ? CODEC_F00_0A_44_1KHZ : 0;
SETUP_AUDIO_FORMAT(pState, AFMT_HZ_44_1K, AFMT_MULT_X2, AFMT_DIV_X1, "hda44_1_2x", as, pi_callback, po_callback);
pState->pNodes[1].node.au32F00_param[0xA] |= IS_FORMAT_SUPPORTED_BY_HOST(pState, AFMT_HZ_44_1K, AFMT_MULT_X2, AFMT_DIV_X1) ? CODEC_F00_0A_44_1KHZ_MULT_2X : 0;
SETUP_AUDIO_FORMAT(pState, AFMT_HZ_44_1K, AFMT_MULT_X4, AFMT_DIV_X1, "hda44_1_4x", as, pi_callback, po_callback);
pState->pNodes[1].node.au32F00_param[0xA] |= IS_FORMAT_SUPPORTED_BY_HOST(pState, AFMT_HZ_44_1K, AFMT_MULT_X4, AFMT_DIV_X1) ? CODEC_F00_0A_44_1KHZ_MULT_4X : 0;
SETUP_AUDIO_FORMAT(pState, AFMT_HZ_48K, AFMT_MULT_X1, AFMT_DIV_X1, "hda48", as, pi_callback, po_callback);
pState->pNodes[1].node.au32F00_param[0xA] |= IS_FORMAT_SUPPORTED_BY_HOST(pState, AFMT_HZ_48K, AFMT_MULT_X1, AFMT_DIV_X1) ? CODEC_F00_0A_48KHZ : 0;
# if 0
SETUP_AUDIO_FORMAT(pState, AFMT_HZ_48K, AFMT_MULT_X2, AFMT_DIV_X1, "hda48_2x", as, pi_callback, po_callback);
pState->pNodes[1].node.au32F00_param[0xA] |= IS_FORMAT_SUPPORTED_BY_HOST(pState, AFMT_HZ_48K, AFMT_MULT_X2, AFMT_DIV_X1) ? CODEC_F00_0A_48KHZ_MULT_2X : 0;
SETUP_AUDIO_FORMAT(pState, AFMT_HZ_48K, AFMT_MULT_X4, AFMT_DIV_X1, "hda48_4x", as, pi_callback, po_callback);
pState->pNodes[1].node.au32F00_param[0xA] |= IS_FORMAT_SUPPORTED_BY_HOST(pState, AFMT_HZ_48K, AFMT_MULT_X4, AFMT_DIV_X1) ? CODEC_F00_0A_48KHZ_MULT_4X : 0;
# endif
#endif
uint8_t i;
for (i = 0; i < pState->cTotalNodes; ++i)
{
}
/* @todo If no host voices were created, then fallback to nul audio. */
#else
/* If no host voices were created, then fallback to nul audio. */
LogRel (("HDA: WARNING: Unable to open PCM IN!\n"));
LogRel (("HDA: WARNING: Unable to open PCM MC!\n"));
LogRel (("HDA: WARNING: Unable to open PCM OUT!\n"));
{
/* Was not able initialize *any* voice. Select the NULL audio driver instead */
AUD_init_null ();
N_ ("No audio devices could be opened. Selecting the NULL audio backend "
"with the consequence that no sound is audible"));
}
{
char szMissingVoices[128];
len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_mic" : "PCM_mic");
N_ ("Some audio devices (%s) could not be opened. Guest applications generating audio "
"output or depending on audio input may hang. Make sure your host audio device "
"is working properly. Check the logfile for error messages of the audio "
"subsystem"), szMissingVoices);
}
#endif /* VBOX_WITH_AUDIO_FLEXIBLE_FORMAT */
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
}
{
return VINF_SUCCESS;
}
{
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);
codecToAudVolume(&pCodecState->pNodes[pCodecState->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);
return VINF_SUCCESS;
}