bool CAudioDecoder::Init(const CFileItem& file, unsigned int filecache) { if (!Initialized()) return false; // for replaygain CTagLoaderTagLib tag; tag.Load(file.GetPath(), XFILE::CMusicFileDirectory::m_tag, NULL); int channels; int sampleRate; m_context = m_struct.toAddon.Init(file.GetPath().c_str(), filecache, &channels, &sampleRate, &m_bitsPerSample, &m_TotalTime, &m_bitRate, &m_format.m_dataFormat, &m_channel); m_format.m_sampleRate = sampleRate; if (m_channel) m_format.m_channelLayout = CAEChannelInfo(m_channel); else m_format.m_channelLayout = CAEUtil::GuessChLayout(channels); return (m_context != NULL); }
CAEChannelInfo CDVDAudioCodecLibMad::GetChannelMap() { assert(m_iSourceChannels > 0 && m_iSourceChannels < 3); static enum AEChannel map[2][3] = { {AE_CH_FC, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR, AE_CH_NULL} }; return CAEChannelInfo(map[m_iSourceChannels -1]); }
CAEChannelInfo SIDCodec::GetChannelInfo() { static enum AEChannel map[1][2] = { {AE_CH_FC, AE_CH_NULL} }; if (m_Channels > 1) return CAEUtil::GuessChLayout(m_Channels); return CAEChannelInfo(map[m_Channels - 1]); }
CAEChannelInfo CDDACodec::GetChannelInfo() { static enum AEChannel map[2][3] = { {AE_CH_FC, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR , AE_CH_NULL} }; if (m_Channels > 2) return CAEUtil::GuessChLayout(m_Channels); return CAEChannelInfo(map[m_Channels - 1]); }
CAEChannelInfo Codec::GetChannelInfo() { static enum AEChannel map[2][3] = { {AE_CH_FC, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR , AE_CH_NULL} }; if (m_Channels > 2) { Logger::printOut("m_Channels is bigger than 2, please fix code, I can´t return a valid AEChannel map"); // return CAEUtil::GuessChLayout(m_Channels); } return CAEChannelInfo(map[m_Channels - 1]); }
CAEChannelInfo OGGCodec::GetChannelInfo() { static enum AEChannel map[8][9] = { {AE_CH_FC, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR, AE_CH_NULL}, {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_NULL}, {AE_CH_FL, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_BL, AE_CH_BR, AE_CH_LFE, AE_CH_NULL}, {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_SL, AE_CH_SR, AE_CH_BL, AE_CH_BR, AE_CH_NULL}, {AE_CH_FL, AE_CH_FC, AE_CH_FR, AE_CH_SL, AE_CH_SR, AE_CH_BL, AE_CH_BR, AE_CH_LFE, AE_CH_NULL} }; if (m_Channels > 8) return CAEUtil::GuessChLayout(m_Channels); return CAEChannelInfo(map[m_Channels - 1]); }
bool CCoreAudioAE::OpenCoreAudio(unsigned int sampleRate, bool forceRaw, enum AEDataFormat rawDataFormat) { // remove any deleted streams CSingleLock streamLock(m_streamLock); for (StreamList::iterator itt = m_streams.begin(); itt != m_streams.end();) { CCoreAudioAEStream *stream = *itt; if (stream->IsDestroyed()) { itt = m_streams.erase(itt); delete stream; continue; } else { // close all converter stream->CloseConverter(); } ++itt; } /* override the sample rate based on the oldest stream if there is one */ if (!m_streams.empty()) sampleRate = m_streams.front()->GetSampleRate(); if (forceRaw) m_rawPassthrough = true; else m_rawPassthrough = !m_streams.empty() && m_streams.front()->IsRaw(); streamLock.Leave(); if (m_rawPassthrough) CLog::Log(LOGINFO, "CCoreAudioAE::OpenCoreAudio - RAW passthrough enabled"); std::string m_outputDevice = g_guiSettings.GetString("audiooutput.audiodevice"); // on iOS devices we set fixed to two channels. m_stdChLayout = AE_CH_LAYOUT_2_0; #if defined(TARGET_DARWIN_OSX) switch (g_guiSettings.GetInt("audiooutput.channels")) { default: case 0: m_stdChLayout = AE_CH_LAYOUT_2_0; break; /* do not allow 1_0 output */ case 1: m_stdChLayout = AE_CH_LAYOUT_2_0; break; case 2: m_stdChLayout = AE_CH_LAYOUT_2_1; break; case 3: m_stdChLayout = AE_CH_LAYOUT_3_0; break; case 4: m_stdChLayout = AE_CH_LAYOUT_3_1; break; case 5: m_stdChLayout = AE_CH_LAYOUT_4_0; break; case 6: m_stdChLayout = AE_CH_LAYOUT_4_1; break; case 7: m_stdChLayout = AE_CH_LAYOUT_5_0; break; case 8: m_stdChLayout = AE_CH_LAYOUT_5_1; break; case 9: m_stdChLayout = AE_CH_LAYOUT_7_0; break; case 10: m_stdChLayout = AE_CH_LAYOUT_7_1; break; } #endif // force optical/coax to 2.0 output channels if (!m_rawPassthrough && g_guiSettings.GetInt("audiooutput.mode") == AUDIO_IEC958) m_stdChLayout = AE_CH_LAYOUT_2_0; // setup the desired format m_format.m_channelLayout = CAEChannelInfo(m_stdChLayout); // if there is an audio resample rate set, use it. if (g_advancedSettings.m_audioResample && !m_rawPassthrough) { sampleRate = g_advancedSettings.m_audioResample; CLog::Log(LOGINFO, "CCoreAudioAE::passthrough - Forcing samplerate to %d", sampleRate); } if (m_rawPassthrough) { switch (rawDataFormat) { case AE_FMT_AC3: case AE_FMT_DTS: m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_2_0); m_format.m_sampleRate = 48000; m_format.m_dataFormat = AE_FMT_S16NE; break; case AE_FMT_EAC3: m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_2_0); m_format.m_sampleRate = 192000; m_format.m_dataFormat = AE_FMT_S16NE; break; case AE_FMT_DTSHD: case AE_FMT_TRUEHD: m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_7_1); m_format.m_sampleRate = 192000; m_format.m_dataFormat = AE_FMT_S16NE; break; case AE_FMT_LPCM: m_format.m_channelLayout = CAEChannelInfo(AE_CH_LAYOUT_7_1); m_format.m_sampleRate = sampleRate; m_format.m_dataFormat = AE_FMT_FLOAT; break; default: break; } } else { m_format.m_sampleRate = sampleRate; m_format.m_channelLayout = CAEChannelInfo(m_stdChLayout); m_format.m_dataFormat = AE_FMT_FLOAT; } m_format.m_encodedRate = 0; if (m_outputDevice.empty()) m_outputDevice = "default"; AEAudioFormat initformat = m_format; // initialize audio hardware m_Initialized = HAL->Initialize(this, m_rawPassthrough, initformat, rawDataFormat, m_outputDevice, m_volume); unsigned int bps = CAEUtil::DataFormatToBits(m_format.m_dataFormat); m_chLayoutCount = m_format.m_channelLayout.Count(); m_format.m_frameSize = (bps>>3) * m_chLayoutCount; //initformat.m_frameSize; //m_format.m_frames = (unsigned int)(((float)m_format.m_sampleRate / 1000.0f) * (float)DELAY_FRAME_TIME); //m_format.m_frameSamples = m_format.m_frames * m_format.m_channelLayout.Count(); if ((initformat.m_channelLayout.Count() != m_chLayoutCount) && !m_rawPassthrough) { /* readjust parameters. hardware didn't accept channel count*/ CLog::Log(LOGINFO, "CCoreAudioAE::Initialize: Setup channels (%d) greater than possible hardware channels (%d).", m_chLayoutCount, initformat.m_channelLayout.Count()); m_format.m_channelLayout = CAEChannelInfo(initformat.m_channelLayout); m_chLayoutCount = m_format.m_channelLayout.Count(); m_format.m_frameSize = (bps>>3) * m_chLayoutCount; //initformat.m_frameSize; //m_format.m_frameSamples = m_format.m_frames * m_format.m_channelLayout.Count(); }
static void SinkInfoRequestCallback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) { SinkInfoStruct *sinkStruct = (SinkInfoStruct *)userdata; if (!sinkStruct) return; if(sinkStruct->list->empty()) { //add a default device first CAEDeviceInfo defaultDevice; defaultDevice.m_deviceName = std::string("Default"); defaultDevice.m_displayName = std::string("Default"); defaultDevice.m_displayNameExtra = std::string("Default Output Device (PULSEAUDIO)"); defaultDevice.m_dataFormats.insert(defaultDevice.m_dataFormats.end(), defaultDataFormats, defaultDataFormats + ARRAY_SIZE(defaultDataFormats)); defaultDevice.m_channels = CAEChannelInfo(AE_CH_LAYOUT_2_0); defaultDevice.m_sampleRates.assign(defaultSampleRates, defaultSampleRates + ARRAY_SIZE(defaultSampleRates)); defaultDevice.m_deviceType = AE_DEVTYPE_PCM; sinkStruct->list->push_back(defaultDevice); } if (i && i->name) { CAEDeviceInfo device; bool valid = true; device.m_deviceName = std::string(i->name); device.m_displayName = std::string(i->description); if (i->active_port && i->active_port->description) device.m_displayNameExtra = std::string((i->active_port->description)).append(" (PULSEAUDIO)"); else device.m_displayNameExtra = std::string((i->description)).append(" (PULSEAUDIO)"); unsigned int device_type = AE_DEVTYPE_PCM; //0 device.m_channels = PAChannelToAEChannelMap(i->channel_map); // Don't add devices that would not have a channel map if(device.m_channels.Count() == 0) valid = false; device.m_sampleRates.assign(defaultSampleRates, defaultSampleRates + ARRAY_SIZE(defaultSampleRates)); for (unsigned int j = 0; j < i->n_formats; j++) { switch(i->formats[j]->encoding) { case PA_ENCODING_AC3_IEC61937: device.m_dataFormats.push_back(AE_FMT_AC3); device_type = AE_DEVTYPE_IEC958; break; case PA_ENCODING_DTS_IEC61937: device.m_dataFormats.push_back(AE_FMT_DTS); device_type = AE_DEVTYPE_IEC958; break; case PA_ENCODING_EAC3_IEC61937: device.m_dataFormats.push_back(AE_FMT_EAC3); device_type = AE_DEVTYPE_IEC958; break; case PA_ENCODING_PCM: device.m_dataFormats.insert(device.m_dataFormats.end(), defaultDataFormats, defaultDataFormats + ARRAY_SIZE(defaultDataFormats)); break; default: break; } } // passthrough is only working when device has Stereo channel config if (device_type > AE_DEVTYPE_PCM && device.m_channels.Count() == 2) device.m_deviceType = AE_DEVTYPE_IEC958; else device.m_deviceType = AE_DEVTYPE_PCM; if(valid) { CLog::Log(LOGDEBUG, "PulseAudio: Found %s with devicestring %s", device.m_displayName.c_str(), device.m_deviceName.c_str()); sinkStruct->list->push_back(device); } else { CLog::Log(LOGDEBUG, "PulseAudio: Skipped %s with devicestring %s", device.m_displayName.c_str(), device.m_deviceName.c_str()); } } pa_threaded_mainloop_signal(sinkStruct->mainloop, 0); }