void CCoreAudioDevice::Close() { if (!m_DeviceId) return; // Stop the device if it was started Stop(); // Unregister the IOProc if we have one if (m_IoProc) SetInputSource(NULL, 0, 0); SetHogStatus(false); CCoreAudioHardware::SetAutoHogMode(false); if (m_MixerRestore > -1) // We changed the mixer status SetMixingSupport((m_MixerRestore ? true : false)); m_MixerRestore = -1; if (m_SampleRateRestore != 0.0f) SetNominalSampleRate(m_SampleRateRestore); if (m_BufferSizeRestore && m_BufferSizeRestore != GetBufferSize()) { SetBufferSize(m_BufferSizeRestore); m_BufferSizeRestore = 0; } m_IoProc = NULL; m_pSource = NULL; m_DeviceId = 0; m_ObjectListenerProc = NULL; }
void CCoreAudioUnit::Close() { if (!m_Initialized && !m_audioUnit) return; if (m_renderProc) SetInputSource(NULL); Stop(); if (m_busNumber != INVALID_BUS) { OSStatus ret = AUGraphDisconnectNodeInput(m_audioGraph, m_audioNode, m_busNumber); if (ret) { CLog::Log(LOGERROR, "CCoreAudioUnit::Close: Unable to disconnect AudioUnit. Error = %s", GetError(ret).c_str()); } ret = AUGraphRemoveNode(m_audioGraph, m_audioNode); if (ret) { CLog::Log(LOGERROR, "CCoreAudioUnit::Close: Unable to disconnect AudioUnit. Error = %s", GetError(ret).c_str()); } } AUGraphUpdate(m_audioGraph, NULL); m_Initialized = false; m_audioUnit = NULL; m_audioNode = NULL; m_pSource = NULL; }
void CSTb710xHDMI::SetControl(stm_output_control_t ctrl, ULONG ulNewVal) { DEBUGF2(2,("CSTb710xHDMI::SetControl: 0x%.8x/%lu\n", ctrl, ulNewVal)); switch (ctrl) { case STM_CTRL_AV_SOURCE_SELECT: if(SetInputSource(ulNewVal)) m_ulInputSource = ulNewVal; break; default: CSTmHDMI::SetControl(ctrl, ulNewVal); break; } }
bool CCoreAudioGraph::Close() { if (!m_audioGraph) return false; OSStatus ret; Stop(); SetInputSource(NULL); while (!m_auUnitList.empty()) { CAUOutputDevice *d = m_auUnitList.front(); m_auUnitList.pop_front(); ReleaseBus(d->GetBus()); d->Close(); delete d; } if (m_inputUnit) { ReleaseBus(m_inputUnit->GetBus()); m_inputUnit->Close(); delete m_inputUnit; m_inputUnit = NULL; } if (m_mixerUnit) { m_mixerUnit->Close(); delete m_mixerUnit; m_mixerUnit = NULL; } if (m_audioUnit) { m_audioUnit->Close(); delete m_audioUnit; m_audioUnit = NULL; } ret = AUGraphUninitialize(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Close: Error unitialize. Error = %s", GetError(ret).c_str()); } ret = AUGraphClose(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Close: Error close. Error = %s", GetError(ret).c_str()); } ret = DisposeAUGraph(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Close: Error dispose. Error = %s", GetError(ret).c_str()); } return true; }
bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format, bool allowMixing) { OSStatus ret; AudioStreamBasicDescription inputFormat; AudioStreamBasicDescription outputFormat; m_allowMixing = allowMixing; ret = NewAUGraph(&m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error create audio grpah. Error = %s", GetError(ret).c_str()); return false; } ret = AUGraphOpen(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error open audio grpah. Error = %s", GetError(ret).c_str()); return false; } // get output unit if (m_audioUnit) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error audio unit already open. double call ?"); return false; } m_audioUnit = new CAUOutputDevice(); if (!m_audioUnit->Open(m_audioGraph, kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple)) return false; if (!m_audioUnit->EnableInputOuput()) return false; m_audioUnit->GetFormatDesc(format, &inputFormat); //if(!allowMixing) //{ if (!m_audioUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus)) return false; if (!m_audioUnit->SetFormat(&inputFormat, kAudioUnitScope_Output, kInputBus)) return false; //} if (allowMixing) { // get mixer unit if (m_mixerUnit) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?"); return false; } m_mixerUnit = new CAUMultiChannelMixer(); if (!m_mixerUnit->Open(m_audioGraph, kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple)) return false; // set number of input buses if (!m_mixerUnit->SetInputBusCount(MAX_CONNECTION_LIMIT)) return false; //if(!m_mixerUnit->SetFormat(&fmt, kAudioUnitScope_Output, kOutputBus)) // return false; m_mixerUnit->SetBus(0); if (!m_audioUnit->GetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus)) return false; /* if(!m_mixerUnit->SetInputBusFormat(MAX_CONNECTION_LIMIT, &outputFormat)) return false; */ ret = AUGraphConnectNodeInput(m_audioGraph, m_mixerUnit->GetNode(), 0, m_audioUnit->GetNode(), 0); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error connecting m_m_mixerNode. Error = %s", GetError(ret).c_str()); return false; } // get output unit if (m_inputUnit) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?"); return false; } m_inputUnit = new CAUOutputDevice(); if (!m_inputUnit->Open(m_audioGraph, kAudioUnitType_FormatConverter, kAudioUnitSubType_AUConverter, kAudioUnitManufacturer_Apple)) return false; if (!m_inputUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus)) return false; /* if(!m_inputUnit->SetFormat(&outputFormat, kAudioUnitScope_Output, kOutputBus)) return false; */ // configure output unit int busNumber = GetFreeBus(); ret = AUGraphConnectNodeInput(m_audioGraph, m_inputUnit->GetNode(), 0, m_mixerUnit->GetNode(), busNumber); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error connecting m_converterNode. Error = %s", GetError(ret).c_str()); return false; } m_inputUnit->SetBus(busNumber); ret = AUGraphUpdate(m_audioGraph, NULL); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error update graph. Error = %s", GetError(ret).c_str()); return false; } ret = AUGraphInitialize(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error initialize graph. Error = %s", GetError(ret).c_str()); return false; } // Regenerate audio format and copy format for the Output AU } ret = AUGraphUpdate(m_audioGraph, NULL); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error update graph. Error = %s", GetError(ret).c_str()); return false; } std::string formatString; AudioStreamBasicDescription inputDesc_end, outputDesc_end; m_audioUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus); m_audioUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kInputBus); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format %s", StreamDescriptionToString(inputDesc_end, formatString)); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString)); if (m_mixerUnit) { m_mixerUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus); m_mixerUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format %s", StreamDescriptionToString(inputDesc_end, formatString)); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString)); } if (m_inputUnit) { m_inputUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus); m_inputUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format %s", StreamDescriptionToString(inputDesc_end, formatString)); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString)); } ret = AUGraphInitialize(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error initialize graph. Error = %s", GetError(ret).c_str()); return false; } UInt32 bufferFrames = m_audioUnit->GetBufferFrameSize(); m_audioUnit->SetMaxFramesPerSlice(bufferFrames); if (m_inputUnit) m_inputUnit->SetMaxFramesPerSlice(bufferFrames); SetInputSource(pSource); ShowGraph(); return Start(); }
bool CCoreAudioGraph::Open(ICoreAudioSource *pSource, AEAudioFormat &format, AudioDeviceID deviceId, bool allowMixing, AudioChannelLayoutTag layoutTag) { AudioStreamBasicDescription fmt = {0}; AudioStreamBasicDescription inputFormat = {0}; AudioStreamBasicDescription outputFormat = {0}; m_deviceId = deviceId; m_allowMixing = allowMixing; OSStatus ret = NewAUGraph(&m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error create audio grpah. Error = %s", GetError(ret).c_str()); return false; } ret = AUGraphOpen(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error open audio grpah. Error = %s", GetError(ret).c_str()); return false; } // get output unit if (m_audioUnit) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error audio unit already open. double call ?"); return false; } m_audioUnit = new CAUOutputDevice(); if (!m_audioUnit->Open(m_audioGraph, kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple)) return false; m_audioUnit->SetBus(GetFreeBus()); m_audioUnit->GetFormatDesc(format, &inputFormat, &fmt); if (!m_audioUnit->EnableInputOuput()) return false; if (!m_audioUnit->SetCurrentDevice(deviceId)) return false; if (allowMixing) { delete m_mixMap; m_mixMap = CCoreAudioMixMap::CreateMixMap(m_audioUnit, format, layoutTag); if (m_mixMap || m_mixMap->IsValid()) { // maximum input channel ber input bus //fmt.mChannelsPerFrame = MAXIMUM_MIXER_CHANNELS; // get output unit if (m_inputUnit) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?"); return false; } m_inputUnit = new CAUOutputDevice(); if (!m_inputUnit->Open(m_audioGraph, kAudioUnitType_FormatConverter, kAudioUnitSubType_AUConverter, kAudioUnitManufacturer_Apple)) return false; if (!m_inputUnit->SetFormat(&inputFormat, kAudioUnitScope_Input, kOutputBus)) return false; if (!m_inputUnit->SetFormat(&fmt, kAudioUnitScope_Output, kOutputBus)) return false; // get mixer unit if (m_mixerUnit) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: Error mixer unit already open. double call ?"); return false; } m_mixerUnit = new CAUMatrixMixer(); if (!m_mixerUnit->Open(m_audioGraph, kAudioUnitType_Mixer, kAudioUnitSubType_MatrixMixer, kAudioUnitManufacturer_Apple)) return false; // set number of input buses if (!m_mixerUnit->SetInputBusCount(MAX_CONNECTION_LIMIT)) return false; // set number of output buses if (!m_mixerUnit->SetOutputBusCount(1)) return false; if (!m_mixerUnit->SetInputBusFormat(MAX_CONNECTION_LIMIT, &fmt)) return false; if (!m_mixerUnit->SetFormat(&fmt, kAudioUnitScope_Output, kOutputBus)) return false; ret = AUGraphConnectNodeInput(m_audioGraph, m_mixerUnit->GetNode(), 0, m_audioUnit->GetNode(), 0); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error connecting m_m_mixerNode. Error = %s", GetError(ret).c_str()); return false; } m_mixerUnit->SetBus(0); // configure output unit int busNumber = GetFreeBus(); ret = AUGraphConnectNodeInput(m_audioGraph, m_inputUnit->GetNode(), 0, m_mixerUnit->GetNode(), busNumber); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error connecting m_converterNode. Error = %s", GetError(ret).c_str()); return false; } m_inputUnit->SetBus(busNumber); ret = AUGraphUpdate(m_audioGraph, NULL); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error update graph. Error = %s", GetError(ret).c_str()); return false; } ret = AUGraphInitialize(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error initialize graph. Error = %s", GetError(ret).c_str()); return false; } // Update format structure to reflect the desired format from the mixer // The output format of the mixer is identical to the input format, except for the channel count fmt.mChannelsPerFrame = m_mixMap->GetOutputChannels(); UInt32 inputNumber = m_inputUnit->GetBus(); int channelOffset = GetMixerChannelOffset(inputNumber); if (!CCoreAudioMixMap::SetMixingMatrix(m_mixerUnit, m_mixMap, &inputFormat, &fmt, channelOffset)) return false; // Regenerate audio format and copy format for the Output AU outputFormat = fmt; } else { outputFormat = inputFormat; } } else { outputFormat = inputFormat; } if (!m_audioUnit->SetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus)) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error setting input format on audio device. Channel count %d, set it to %d", (int)outputFormat.mChannelsPerFrame, format.m_channelLayout.Count()); outputFormat.mChannelsPerFrame = format.m_channelLayout.Count(); if (!m_audioUnit->SetFormat(&outputFormat, kAudioUnitScope_Input, kOutputBus)) return false; } std::string formatString; // asume we are in dd-wave mode if (!m_inputUnit) { if (!m_audioUnit->SetFormat(&inputFormat, kAudioUnitScope_Output, kInputBus)) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error setting Device Output Stream Format %s", StreamDescriptionToString(inputFormat, formatString)); } } ret = AUGraphUpdate(m_audioGraph, NULL); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error update graph. Error = %s", GetError(ret).c_str()); return false; } AudioStreamBasicDescription inputDesc_end, outputDesc_end; m_audioUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus); m_audioUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kInputBus); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format %s", StreamDescriptionToString(inputDesc_end, formatString)); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString)); if (m_mixerUnit) { m_mixerUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus); m_mixerUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format %s", StreamDescriptionToString(inputDesc_end, formatString)); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString)); } if (m_inputUnit) { m_inputUnit->GetFormat(&inputDesc_end, kAudioUnitScope_Input, kOutputBus); m_inputUnit->GetFormat(&outputDesc_end, kAudioUnitScope_Output, kOutputBus); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Input Stream Format %s", StreamDescriptionToString(inputDesc_end, formatString)); CLog::Log(LOGINFO, "CCoreAudioGraph::Open: Output Stream Format %s", StreamDescriptionToString(outputDesc_end, formatString)); } ret = AUGraphInitialize(m_audioGraph); if (ret) { CLog::Log(LOGERROR, "CCoreAudioGraph::Open: " "Error initialize graph. Error = %s", GetError(ret).c_str()); return false; } UInt32 bufferFrames = m_audioUnit->GetBufferFrameSize(); if (!m_audioUnit->SetMaxFramesPerSlice(bufferFrames)) return false; SetInputSource(pSource); return Start(); }
bool CSTmHDFormatterHDMI::Create(void) { ULONG val; DENTRY(); if(!CSTmHDMI::Create()) return false; /* * Default digital configuration */ val = (HDFMT_CFG_RCTRL_R << HDFMT_CFG_REORDER_RSHIFT) | (HDFMT_CFG_RCTRL_G << HDFMT_CFG_REORDER_GSHIFT) | (HDFMT_CFG_RCTRL_B << HDFMT_CFG_REORDER_BSHIFT) | HDFMT_CFG_CLIP_SAV_EAV; WriteHDFmtReg(HDFMT_DIG1_CFG, val); /* * Default HDFormatter/HDMI glue configuration */ val = ReadHDMIReg(STM_HDMI_GPOUT); switch(m_Revision) { case STM_HDF_HDMI_REV1: { val &= ~(STM_HDMI_GPOUT_EXTERNAL_PCMPLAYER_EN | STM_HDMI_GPOUT_DTS_FORMAT_EN | STM_HDMI_GPOUT_CTS_CLK_DIV_BYPASS | STM_HDMI_GPOUT_DTS_SPDIF_MODE_EN); val |= (STM_HDMI_GPOUT_I2S_EN | STM_HDMI_GPOUT_SPDIF_EN | STM_HDMI_GPOUT_I2S_N_SPDIF_DATA | STM_HDMI_GPOUT_HDCP_VSYNC_DISABLE); break; } case STM_HDF_HDMI_REV2: { val &= ~(STM_HDMI_GPOUT_EXTERNAL_PCMPLAYER_EN | STM_HDMI_GPOUT_DTS_SPDIF_MODE_EN | STM_HDMI_GPOUT_DROP_CB_N_CR | STM_HDMI_GPOUT_DROP_EVEN_N_ODD_SAMPLES | STM_HDMI_GPOUT_IN_MASK); val |= (STM_HDMI_GPOUT_I2S_EN | STM_HDMI_GPOUT_SPDIF_EN | STM_HDMI_GPOUT_I2S_N_SPDIF_DATA | STM_HDMI_GPOUT_I2S_N_SPDIF_CLOCK | STM_HDMI_GPOUT_IN_HDFORMATTER | STM_HDMI_GPOUT_HDCP_VSYNC_DISABLE); break; } case STM_HDF_HDMI_REV3: { val &= ~STM_HDMI_GPOUT_EXTERNAL_PCMPLAYER_EN; val |= (STM_HDMI_GPOUT_I2S_EN | STM_HDMI_GPOUT_SPDIF_EN | STM_HDMI_GPOUT_I2S_N_SPDIF_DATA | STM_HDMI_GPOUT_I2S_N_SPDIF_CLOCK | STM_HDMI_GPOUT_HDCP_VSYNC_DISABLE); break; } } WriteHDMIReg(STM_HDMI_GPOUT, val); SetInputSource((STM_AV_SOURCE_MAIN_INPUT | STM_AV_SOURCE_2CH_I2S_INPUT)); DEXIT(); return true; }
void CSTmHDFormatterHDMI::SetControl(stm_output_control_t ctrl, ULONG ulNewVal) { DEBUGF2(3,("CSTmHDFormatterHDMI::SetControl\n")); switch (ctrl) { case STM_CTRL_AV_SOURCE_SELECT: { SetInputSource(ulNewVal); break; } case STM_CTRL_SIGNAL_RANGE: { if(ulNewVal> STM_SIGNAL_VIDEO_RANGE) break; m_signalRange = (stm_display_signal_range_t)ulNewVal; ULONG val = ReadHDFmtReg(HDFMT_DIG1_CFG) & ~(HDFMT_CFG_CLIP_SAV_EAV | HDFMT_CFG_CLIP_EN); switch(m_signalRange) { case STM_SIGNAL_FILTER_SAV_EAV: DEBUGF2(2,("CSTmHDFormatterHDMI::SetControl - Filter SAV/EAV\n")); val |= HDFMT_CFG_CLIP_SAV_EAV; break; case STM_SIGNAL_VIDEO_RANGE: DEBUGF2(2,("CSTmHDFormatterHDMI::SetControl - Clip input to video range\n")); val |= HDFMT_CFG_CLIP_EN; break; default: DEBUGF2(2,("CSTmHDFormatterHDMI::SetControl - Full signal range\n")); break; } WriteHDFmtReg(HDFMT_DIG1_CFG, val); m_pIFrameManager->ForceAVIUpdate(); break; } case STM_CTRL_HDMI_AUDIO_OUT_SELECT: { /* * We are not supporting anything other than basic audio on Rev1, i.e. * 7200cut1. */ if(m_Revision == STM_HDF_HDMI_REV1) return; /* * Don't do anything if the value isn't changing */ if(m_ulAudioOutputType == (stm_hdmi_audio_output_type_t)ulNewVal) return; /* * Check the validity of the setup */ switch(ulNewVal) { case STM_HDMI_AUDIO_TYPE_NORMAL: case STM_HDMI_AUDIO_TYPE_ONEBIT: break; case STM_HDMI_AUDIO_TYPE_DST: case STM_HDMI_AUDIO_TYPE_DST_DOUBLE: if(m_ulInputSource & STM_AV_SOURCE_8CH_I2S_INPUT) return; break; case STM_HDMI_AUDIO_TYPE_HBR: if((m_ulInputSource & STM_AV_SOURCE_2CH_I2S_INPUT) || ((m_Revision == STM_HDF_HDMI_REV3) && (m_ulInputSource & STM_AV_SOURCE_SPDIF_INPUT))) { return; } break; default: return; } DEBUGF2(2,("%s: change audio output type to %lu\n",__PRETTY_FUNCTION__,ulNewVal)); /* * We are being told there is a change to the audio stream, so stop the * current audio processing and get the audio update interrupt handling * to sort it out. */ g_pIOS->LockResource(m_statusLock); InvalidateAudioPackets(); m_ulAudioOutputType = (stm_hdmi_audio_output_type_t)ulNewVal; m_audioState.status = STM_HDMI_AUDIO_STOPPED; SetSPDIFPlayerMode(); g_pIOS->UnlockResource(m_statusLock); break; } default: { CSTmHDMI::SetControl(ctrl, ulNewVal); break; } } }