本文整理汇总了C++中CAEChannelInfo类的典型用法代码示例。如果您正苦于以下问题:C++ CAEChannelInfo类的具体用法?C++ CAEChannelInfo怎么用?C++ CAEChannelInfo使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CAEChannelInfo类的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: AddMissingChannels
void CAEChannelInfo::AddMissingChannels(const CAEChannelInfo& rhs)
{
for (unsigned int i = 0; i < rhs.Count(); i++)
if (!HasChannel(rhs[i]))
*this += rhs[i];
}
示例2: Reset
void CAEChannelInfo::ResolveChannels(const CAEChannelInfo& rhs)
{
/* mono gets upmixed to dual mono */
if (m_channelCount == 1 && m_channels[0] == AE_CH_FC)
{
Reset();
*this += AE_CH_FL;
*this += AE_CH_FR;
return;
}
bool srcHasSL = false;
bool srcHasSR = false;
bool srcHasRL = false;
bool srcHasRR = false;
bool srcHasBC = false;
bool dstHasSL = false;
bool dstHasSR = false;
bool dstHasRL = false;
bool dstHasRR = false;
bool dstHasBC = false;
for (unsigned int c = 0; c < rhs.m_channelCount; ++c)
switch(rhs.m_channels[c])
{
case AE_CH_SL: dstHasSL = true; break;
case AE_CH_SR: dstHasSR = true; break;
case AE_CH_BL: dstHasRL = true; break;
case AE_CH_BR: dstHasRR = true; break;
case AE_CH_BC: dstHasBC = true; break;
default:
break;
}
CAEChannelInfo newInfo;
for (unsigned int i = 0; i < m_channelCount; ++i)
{
switch (m_channels[i])
{
case AE_CH_SL: srcHasSL = true; break;
case AE_CH_SR: srcHasSR = true; break;
case AE_CH_BL: srcHasRL = true; break;
case AE_CH_BR: srcHasRR = true; break;
case AE_CH_BC: srcHasBC = true; break;
default:
break;
}
bool found = false;
for (unsigned int c = 0; c < rhs.m_channelCount; ++c)
if (m_channels[i] == rhs.m_channels[c])
{
found = true;
break;
}
if (found)
newInfo += m_channels[i];
}
/* we need to ensure we end up with rear or side channels for downmix to work */
if (srcHasSL && !dstHasSL && dstHasRL && !newInfo.HasChannel(AE_CH_BL))
newInfo += AE_CH_BL;
if (srcHasSR && !dstHasSR && dstHasRR && !newInfo.HasChannel(AE_CH_BR))
newInfo += AE_CH_BR;
if (srcHasRL && !dstHasRL && dstHasSL && !newInfo.HasChannel(AE_CH_SL))
newInfo += AE_CH_SL;
if (srcHasRR && !dstHasRR && dstHasSR && !newInfo.HasChannel(AE_CH_SR))
newInfo += AE_CH_SR;
// mix back center if not available in destination layout
// prefer mixing into backs if available
if (srcHasBC && !dstHasBC)
{
if (dstHasRL && !newInfo.HasChannel(AE_CH_BL))
newInfo += AE_CH_BL;
else if (dstHasSL && !newInfo.HasChannel(AE_CH_SL))
newInfo += AE_CH_SL;
if (dstHasRR && !newInfo.HasChannel(AE_CH_BR))
newInfo += AE_CH_BR;
else if (dstHasSR && !newInfo.HasChannel(AE_CH_SR))
newInfo += AE_CH_SR;
}
*this = newInfo;
}
示例3: InitRemapper
void CActiveAEStream::InitRemapper()
{
// check if input format follows ffmpeg channel mask
bool needRemap = false;
unsigned int avLast, avCur = 0;
for(unsigned int i=0; i<m_format.m_channelLayout.Count(); i++)
{
avLast = avCur;
avCur = CAEUtil::GetAVChannel(m_format.m_channelLayout[i]);
if(avCur < avLast)
{
needRemap = true;
break;
}
}
if(needRemap)
{
CLog::Log(LOGDEBUG, "CActiveAEStream::%s - initialize remapper", __FUNCTION__);
m_remapper = CAEResampleFactory::Create();
uint64_t avLayout = CAEUtil::GetAVChannelLayout(m_format.m_channelLayout);
// build layout according to ffmpeg channel order
// we need this for reference
CAEChannelInfo ffmpegLayout;
ffmpegLayout.Reset();
int idx = 0;
for(unsigned int i=0; i<m_format.m_channelLayout.Count(); i++)
{
for(unsigned int j=0; j<m_format.m_channelLayout.Count(); j++)
{
idx = CAEUtil::GetAVChannelIndex(m_format.m_channelLayout[j], avLayout);
if (idx == (int)i)
{
ffmpegLayout += m_format.m_channelLayout[j];
break;
}
}
}
// build remap layout we can pass to resampler as destination layout
CAEChannelInfo remapLayout;
remapLayout.Reset();
for(unsigned int i=0; i<m_format.m_channelLayout.Count(); i++)
{
for(unsigned int j=0; j<m_format.m_channelLayout.Count(); j++)
{
idx = CAEUtil::GetAVChannelIndex(m_format.m_channelLayout[j], avLayout);
if (idx == (int)i)
{
remapLayout += ffmpegLayout[j];
break;
}
}
}
// initialize resampler for only doing remapping
m_remapper->Init(avLayout,
m_format.m_channelLayout.Count(),
m_format.m_sampleRate,
CAEUtil::GetAVSampleFormat(m_format.m_dataFormat),
CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat),
CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat),
avLayout,
m_format.m_channelLayout.Count(),
m_format.m_sampleRate,
CAEUtil::GetAVSampleFormat(m_format.m_dataFormat),
CAEUtil::DataFormatToUsedBits(m_format.m_dataFormat),
CAEUtil::DataFormatToDitherBits(m_format.m_dataFormat),
false,
false,
&remapLayout,
AE_QUALITY_LOW, // not used for remapping
false);
// extra sound packet, we can't resample to the same buffer
m_remapBuffer = new CSoundPacket(m_inputBuffers->m_allSamples[0]->pkt->config, m_inputBuffers->m_allSamples[0]->pkt->max_nb_samples);
}
}
示例4: memset
bool CAERemap::Initialize(CAEChannelInfo input, CAEChannelInfo output, bool finalStage, bool forceNormalize/* = false */, enum AEStdChLayout stdChLayout/* = AE_CH_LAYOUT_INVALID */)
{
if (!input.Count() || !output.Count())
return false;
/* build the downmix matrix */
memset(m_mixInfo, 0, sizeof(m_mixInfo));
m_output = output;
/* figure which channels we have */
for (unsigned int o = 0; o < output.Count(); ++o)
m_mixInfo[output[o]].in_dst = true;
/* flag invalid channels for forced downmix */
if (stdChLayout != AE_CH_LAYOUT_INVALID)
{
CAEChannelInfo layout = stdChLayout;
for (unsigned int o = 0; o < output.Count(); ++o)
if (!layout.HasChannel(output[o]))
m_mixInfo[output[o]].in_dst = false;
}
m_outChannels = output.Count();
/* lookup the channels that exist in the output */
for (unsigned int i = 0; i < input.Count(); ++i)
{
AEMixInfo *info = &m_mixInfo[input[i]];
AEMixLevel *lvl = &info->srcIndex[info->srcCount++];
info->in_src = true;
lvl->index = i;
lvl->level = 1.0f;
if (!info->in_dst)
{
for (unsigned int o = 0; o < output.Count(); ++o)
{
if (input[i] == output[o])
{
info->outIndex = o;
break;
}
}
}
m_inChannels = i;
}
++m_inChannels;
/* the final stage does not need any down/upmix */
if (finalStage)
return true;
/* downmix from the specified channel to the specified list of channels */
#define RM(from, ...) \
static AEChannel downmix_##from[] = {__VA_ARGS__, AE_CH_NULL}; \
ResolveMix(from, CAEChannelInfo(downmix_##from));
/*
the order of this is important as we can not mix channels
into ones that have already been resolved... eg
TBR -> BR
TBC -> TBL & TBR
TBR will get resolved to BR, and then TBC will get
resolved to TBL, but since TBR has been resolved it will
never make it to the output. The order has to be reversed
as the TBC center depends on the TBR downmix... eg
TBC -> TBL & TBR
TBR -> BR
if for any reason out of order mapping becomes required
looping this list should resolve the channels.
*/
RM(AE_CH_TBC , AE_CH_TBL, AE_CH_TBR);
RM(AE_CH_TBR , AE_CH_BR);
RM(AE_CH_TBL , AE_CH_BL);
RM(AE_CH_TC , AE_CH_TFL, AE_CH_TFR);
RM(AE_CH_TFC , AE_CH_TFL, AE_CH_TFR);
RM(AE_CH_TFR , AE_CH_FR);
RM(AE_CH_TFL , AE_CH_FL);
RM(AE_CH_SR , AE_CH_BR, AE_CH_FR);
RM(AE_CH_SL , AE_CH_BL, AE_CH_FL);
RM(AE_CH_BC , AE_CH_BL, AE_CH_BR);
RM(AE_CH_FROC, AE_CH_FR, AE_CH_FC);
RM(AE_CH_FLOC, AE_CH_FL, AE_CH_FC);
RM(AE_CH_BL , AE_CH_FL);
RM(AE_CH_BR , AE_CH_FR);
RM(AE_CH_LFE , AE_CH_FL, AE_CH_FR);
RM(AE_CH_FL , AE_CH_FC);
RM(AE_CH_FR , AE_CH_FC);
RM(AE_CH_BROC, AE_CH_BR, AE_CH_BC);
RM(AE_CH_BLOC, AE_CH_BL, AE_CH_BC);
/* since everything eventually mixes down to FC we need special handling for it */
if (m_mixInfo[AE_CH_FC].in_src)
{
/* if there is no output FC channel, try to mix it the best possible way */
if (!m_mixInfo[AE_CH_FC].in_dst)
//.........这里部分代码省略.........
示例5: GetChannelLayout
bool CAESinkALSA::Initialize(AEAudioFormat &format, std::string &device)
{
CAEChannelInfo channelLayout = GetChannelLayout(format, 2, 8);
m_initDevice = device;
m_initFormat = format;
ALSAConfig inconfig, outconfig;
inconfig.format = format.m_dataFormat;
inconfig.sampleRate = format.m_sampleRate;
inconfig.channels = channelLayout.Count();
/* if we are raw, correct the data format */
if (AE_IS_RAW(format.m_dataFormat))
{
inconfig.format = AE_FMT_S16NE;
m_passthrough = true;
}
else
{
m_passthrough = false;
}
#if defined(HAS_LIBAMCODEC)
if (aml_present())
{
aml_set_audio_passthrough(m_passthrough);
device = "default";
}
#endif
if (inconfig.channels == 0)
{
CLog::Log(LOGERROR, "CAESinkALSA::Initialize - Unable to open the requested channel layout");
return false;
}
AEDeviceType devType = AEDeviceTypeFromName(device);
std::string AESParams;
/* digital interfaces should have AESx set, though in practice most
* receivers don't care */
if (m_passthrough || devType == AE_DEVTYPE_HDMI || devType == AE_DEVTYPE_IEC958)
GetAESParams(format, AESParams);
CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Attempting to open device \"%s\"", device.c_str());
/* get the sound config */
snd_config_t *config;
snd_config_copy(&config, snd_config);
if (!OpenPCMDevice(device, AESParams, inconfig.channels, &m_pcm, config))
{
CLog::Log(LOGERROR, "CAESinkALSA::Initialize - failed to initialize device \"%s\"", device.c_str());
snd_config_delete(config);
return false;
}
/* get the actual device name that was used */
device = snd_pcm_name(m_pcm);
m_device = device;
CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Opened device \"%s\"", device.c_str());
/* free the sound config */
snd_config_delete(config);
if (!InitializeHW(inconfig, outconfig) || !InitializeSW(outconfig))
return false;
// we want it blocking
snd_pcm_nonblock(m_pcm, 0);
snd_pcm_prepare (m_pcm);
if (m_passthrough && inconfig.channels != outconfig.channels)
{
CLog::Log(LOGINFO, "CAESinkALSA::Initialize - could not open required number of channels");
return false;
}
// adjust format to the configuration we got
format.m_channelLayout = GetChannelLayout(format, outconfig.channels, outconfig.channels);
format.m_sampleRate = outconfig.sampleRate;
format.m_frames = outconfig.periodSize;
format.m_frameSize = outconfig.frameSize;
format.m_frameSamples = outconfig.periodSize * outconfig.channels;
format.m_dataFormat = outconfig.format;
m_format = format;
m_formatSampleRateMul = 1.0 / (double)m_format.m_sampleRate;
return true;
}
示例6: GetAEChannelMap
//Note: in multichannel mode CA will either pull 2 channels of data (stereo) or 6/8 channels of data
//(every speaker setup with more then 2 speakers). The difference between the number of real speakers
//and 6/8 channels needs to be padded with unknown channels so that the sample size fits 6/8 channels
//
//device [in] - the device whose channel layout should be used
//channelMap [in/out] - if filled it will it indicates that we are called from initialize and we log the requested map, out returns the channelMap for device
//channelsPerFrame [in] - the number of channels this device is configured to (e.x. 2 or 6/8)
void AEDeviceEnumerationOSX::GetAEChannelMap(CAEChannelInfo &channelMap, unsigned int channelsPerFrame) const
{
CCoreAudioChannelLayout calayout;
bool logMapping = channelMap.Count() > 0; // only log if the engine requests a layout during init
bool mapAvailable = false;
unsigned int numberChannelsInDeviceLayout = CA_MAX_CHANNELS; // default number of channels from CAChannelMap
AudioChannelLayout *layout = NULL;
// try to fetch either the multichannel or the stereo channel layout from the device
if (channelsPerFrame == 2 || channelMap.Count() == 2)
mapAvailable = m_caDevice.GetPreferredChannelLayoutForStereo(calayout);
else
mapAvailable = m_caDevice.GetPreferredChannelLayout(calayout);
// if a map was fetched - check if it is usable
if (mapAvailable)
{
layout = calayout;
if (layout == NULL || layout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions)
mapAvailable = false;// wrong map format
else
numberChannelsInDeviceLayout = layout->mNumberChannelDescriptions;
}
// start the mapping action
// the number of channels to be added to the outgoing channelmap
// this is CA_MAX_CHANNELS at max and might be lower for some output devices (channelsPerFrame)
unsigned int numChannelsToMap = std::min((unsigned int)CA_MAX_CHANNELS, (unsigned int)channelsPerFrame);
// if there was a map fetched we force the number of
// channels to map to channelsPerFrame (this allows mapping
// of more then CA_MAX_CHANNELS if needed)
if (mapAvailable)
numChannelsToMap = channelsPerFrame;
std::string layoutStr;
if (logMapping)
{
CLog::Log(LOGDEBUG, "%s Engine requests layout %s", __FUNCTION__, ((std::string)channelMap).c_str());
if (mapAvailable)
CLog::Log(LOGDEBUG, "%s trying to map to %s layout: %s", __FUNCTION__, channelsPerFrame == 2 ? "stereo" : "multichannel", calayout.ChannelLayoutToString(*layout, layoutStr));
else
CLog::Log(LOGDEBUG, "%s no map available - using static multichannel map layout", __FUNCTION__);
}
channelMap.Reset();// start with an empty map
for (unsigned int channel = 0; channel < numChannelsToMap; channel++)
{
// we only try to map channels which are defined in the device layout
enum AEChannel currentChannel;
if (channel < numberChannelsInDeviceLayout)
{
// get the channel from the fetched map
if (mapAvailable)
currentChannel = caChannelToAEChannel(layout->mChannelDescriptions[channel].mChannelLabel);
else// get the channel from the default map
currentChannel = CAChannelMap[channel];
}
else// fill with unknown channels
currentChannel = caChannelToAEChannel(kAudioChannelLabel_Unknown);
if(!channelMap.HasChannel(currentChannel))// only add if not already added
channelMap += currentChannel;
}
if (logMapping)
CLog::Log(LOGDEBUG, "%s mapped channels to layout %s", __FUNCTION__, ((std::string)channelMap).c_str());
}
示例7: EnumerateDevicesEx
void CAESinkWASAPI::EnumerateDevicesEx(AEDeviceInfoList &deviceInfoList, bool force)
{
IMMDeviceEnumerator* pEnumerator = NULL;
IMMDeviceCollection* pEnumDevices = NULL;
IMMDevice* pDefaultDevice = NULL;
CAEDeviceInfo deviceInfo;
CAEChannelInfo deviceChannels;
LPWSTR pwszID = NULL;
std::wstring wstrDDID;
WAVEFORMATEXTENSIBLE wfxex = {0};
HRESULT hr;
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
EXIT_ON_FAILURE(hr, __FUNCTION__": Could not allocate WASAPI device enumerator. CoCreateInstance error code: %li", hr)
UINT uiCount = 0;
// get the default audio endpoint
if(pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDefaultDevice) == S_OK)
{
if(pDefaultDevice->GetId(&pwszID) == S_OK)
{
wstrDDID = pwszID;
CoTaskMemFree(pwszID);
}
SAFE_RELEASE(pDefaultDevice);
}
// enumerate over all audio endpoints
hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pEnumDevices);
EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint enumeration failed.")
hr = pEnumDevices->GetCount(&uiCount);
EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of audio endpoint count failed.")
for (UINT i = 0; i < uiCount; i++)
{
IMMDevice *pDevice = NULL;
IPropertyStore *pProperty = NULL;
PROPVARIANT varName;
PropVariantInit(&varName);
deviceInfo.m_channels.Reset();
deviceInfo.m_dataFormats.clear();
deviceInfo.m_sampleRates.clear();
hr = pEnumDevices->Item(i, &pDevice);
if (FAILED(hr))
{
CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint failed.");
goto failed;
}
hr = pDevice->OpenPropertyStore(STGM_READ, &pProperty);
if (FAILED(hr))
{
CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint properties failed.");
SAFE_RELEASE(pDevice);
goto failed;
}
hr = pProperty->GetValue(PKEY_Device_FriendlyName, &varName);
if (FAILED(hr))
{
CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint device name failed.");
SAFE_RELEASE(pDevice);
SAFE_RELEASE(pProperty);
goto failed;
}
std::string strFriendlyName = localWideToUtf(varName.pwszVal);
PropVariantClear(&varName);
hr = pProperty->GetValue(PKEY_AudioEndpoint_GUID, &varName);
if(FAILED(hr))
{
CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint GUID failed.");
SAFE_RELEASE(pDevice);
SAFE_RELEASE(pProperty);
goto failed;
}
std::string strDevName = localWideToUtf(varName.pwszVal);
PropVariantClear(&varName);
hr = pProperty->GetValue(PKEY_AudioEndpoint_FormFactor, &varName);
if (FAILED(hr))
{
CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint form factor failed.");
SAFE_RELEASE(pDevice);
SAFE_RELEASE(pProperty);
goto failed;
}
std::string strWinDevType = winEndpoints[(EndpointFormFactor)varName.uiVal].winEndpointType;
AEDeviceType aeDeviceType = winEndpoints[(EndpointFormFactor)varName.uiVal].aeDeviceType;
PropVariantClear(&varName);
hr = pProperty->GetValue(PKEY_AudioEndpoint_PhysicalSpeakers, &varName);
//.........这里部分代码省略.........
示例8: Initialize
bool CAESinkALSA::Initialize(AEAudioFormat &format, std::string &device)
{
CAEChannelInfo channelLayout;
m_initDevice = device;
m_initFormat = format;
/* if we are raw, correct the data format */
if (AE_IS_RAW(format.m_dataFormat))
{
channelLayout = GetChannelLayout(format);
format.m_dataFormat = AE_FMT_S16NE;
m_passthrough = true;
}
else
{
channelLayout = GetChannelLayout(format);
m_passthrough = false;
}
#if defined(HAS_AMLPLAYER) || defined(HAS_LIBAMCODEC)
if (aml_present())
{
aml_set_audio_passthrough(m_passthrough);
device = "default";
}
#endif
if (channelLayout.Count() == 0)
{
CLog::Log(LOGERROR, "CAESinkALSA::Initialize - Unable to open the requested channel layout");
return false;
}
format.m_channelLayout = channelLayout;
AEDeviceType devType = AEDeviceTypeFromName(device);
std::string AESParams;
/* digital interfaces should have AESx set, though in practice most
* receivers don't care */
if (m_passthrough || devType == AE_DEVTYPE_HDMI || devType == AE_DEVTYPE_IEC958)
GetAESParams(format, AESParams);
CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Attempting to open device \"%s\"", device.c_str());
/* get the sound config */
snd_config_t *config;
snd_config_copy(&config, snd_config);
if (!OpenPCMDevice(device, AESParams, channelLayout.Count(), &m_pcm, config))
{
CLog::Log(LOGERROR, "CAESinkALSA::Initialize - failed to initialize device \"%s\"", device.c_str());
snd_config_delete(config);
return false;
}
/* get the actual device name that was used */
device = snd_pcm_name(m_pcm);
m_device = device;
CLog::Log(LOGINFO, "CAESinkALSA::Initialize - Opened device \"%s\"", device.c_str());
/* free the sound config */
snd_config_delete(config);
if (!InitializeHW(format) || !InitializeSW(format))
return false;
snd_pcm_nonblock(m_pcm, 1);
snd_pcm_prepare (m_pcm);
m_format = format;
m_formatSampleRateMul = 1.0 / (double)m_format.m_sampleRate;
return true;
}