diff options
49 files changed, 3 insertions, 12433 deletions
diff --git a/Makefile.in b/Makefile.in index daf821d19e..2596c67a27 100755 --- a/Makefile.in +++ b/Makefile.in @@ -30,7 +30,6 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \ xbmc/addons/addons.a \ xbmc/cdrip/cdrip.a \ xbmc/commons/commons.a \ - xbmc/cores/AudioRenderers/audiorenderers.a \ xbmc/cores/AudioEngine/audioengine.a \ xbmc/cores/DllLoader/dllloader.a \ xbmc/cores/DllLoader/exports/exports.a \ diff --git a/XBMC-ATV2.xcodeproj/project.pbxproj b/XBMC-ATV2.xcodeproj/project.pbxproj index 2c40f93b23..0cf2d775b9 100644 --- a/XBMC-ATV2.xcodeproj/project.pbxproj +++ b/XBMC-ATV2.xcodeproj/project.pbxproj @@ -223,7 +223,6 @@ F56C78E7131EC154000AD0F6 /* DVDAudioCodecLPcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C725C131EC151000AD0F6 /* DVDAudioCodecLPcm.cpp */; }; F56C78E8131EC154000AD0F6 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C725E131EC151000AD0F6 /* DVDAudioCodecPassthroughFFmpeg.cpp */; }; F56C78E9131EC154000AD0F6 /* DVDAudioCodecPcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7260131EC151000AD0F6 /* DVDAudioCodecPcm.cpp */; }; - F56C78EA131EC154000AD0F6 /* DVDAudioEncoderFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7263131EC151000AD0F6 /* DVDAudioEncoderFFmpeg.cpp */; }; F56C78EB131EC154000AD0F6 /* DVDCodecUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7269131EC151000AD0F6 /* DVDCodecUtils.cpp */; }; F56C78EC131EC154000AD0F6 /* DVDFactoryCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C726B131EC151000AD0F6 /* DVDFactoryCodec.cpp */; }; F56C78ED131EC154000AD0F6 /* DVDOverlayCodecSSA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C726E131EC151000AD0F6 /* DVDOverlayCodecSSA.cpp */; }; @@ -304,8 +303,6 @@ F56C793C131EC154000AD0F6 /* TimidityCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C732D131EC151000AD0F6 /* TimidityCodec.cpp */; }; F56C793D131EC154000AD0F6 /* WAVcodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C732F131EC151000AD0F6 /* WAVcodec.cpp */; }; F56C793F131EC154000AD0F6 /* YMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7333131EC151000AD0F6 /* YMCodec.cpp */; }; - F56C7941131EC154000AD0F6 /* AudioRendererFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C733A131EC151000AD0F6 /* AudioRendererFactory.cpp */; }; - F56C7942131EC154000AD0F6 /* NullDirectSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C733B131EC151000AD0F6 /* NullDirectSound.cpp */; }; F56C7943131EC154000AD0F6 /* BaseRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C733E131EC151000AD0F6 /* BaseRenderer.cpp */; }; F56C7946131EC154000AD0F6 /* OverlayRendererGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7344131EC151000AD0F6 /* OverlayRendererGL.cpp */; }; F56C7947131EC154000AD0F6 /* OverlayRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7346131EC151000AD0F6 /* OverlayRenderer.cpp */; }; @@ -451,7 +448,6 @@ F56C79EE131EC154000AD0F6 /* ZipDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C749B131EC152000AD0F6 /* ZipDirectory.cpp */; }; F56C79EF131EC154000AD0F6 /* ZipManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C749D131EC152000AD0F6 /* ZipManager.cpp */; }; F56C79F0131EC154000AD0F6 /* AnimatedGif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C74FE131EC152000AD0F6 /* AnimatedGif.cpp */; }; - F56C79F1131EC154000AD0F6 /* AudioContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C74FF131EC152000AD0F6 /* AudioContext.cpp */; }; F56C79F2131EC154000AD0F6 /* D3DResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7500131EC152000AD0F6 /* D3DResource.cpp */; }; F56C79F3131EC154000AD0F6 /* DDSImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7501131EC152000AD0F6 /* DDSImage.cpp */; }; F56C79F4131EC154000AD0F6 /* DirectXGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7502131EC152000AD0F6 /* DirectXGraphics.cpp */; }; @@ -502,7 +498,6 @@ F56C7A22131EC154000AD0F6 /* GUISettingsSliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7530131EC152000AD0F6 /* GUISettingsSliderControl.cpp */; }; F56C7A23131EC154000AD0F6 /* GUIShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7531131EC152000AD0F6 /* GUIShader.cpp */; }; F56C7A24131EC154000AD0F6 /* GUISliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7532131EC152000AD0F6 /* GUISliderControl.cpp */; }; - F56C7A25131EC154000AD0F6 /* GUISound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7533131EC152000AD0F6 /* GUISound.cpp */; }; F56C7A26131EC154000AD0F6 /* GUISpinControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7534131EC152000AD0F6 /* GUISpinControl.cpp */; }; F56C7A27131EC154000AD0F6 /* GUISpinControlEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7535131EC152000AD0F6 /* GUISpinControlEx.cpp */; }; F56C7A28131EC154000AD0F6 /* GUIStandardWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7536131EC152000AD0F6 /* GUIStandardWindow.cpp */; }; @@ -750,8 +745,6 @@ F56C7B2F131EC155000AD0F6 /* LCD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7748131EC154000AD0F6 /* LCD.cpp */; }; F56C7B30131EC155000AD0F6 /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C774A131EC154000AD0F6 /* log.cpp */; }; F56C7B31131EC155000AD0F6 /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C774C131EC154000AD0F6 /* md5.cpp */; }; - F56C7B32131EC155000AD0F6 /* PCMAmplifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C774E131EC154000AD0F6 /* PCMAmplifier.cpp */; }; - F56C7B33131EC155000AD0F6 /* PCMRemap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7750131EC154000AD0F6 /* PCMRemap.cpp */; }; F56C7B34131EC155000AD0F6 /* PerformanceSample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7752131EC154000AD0F6 /* PerformanceSample.cpp */; }; F56C7B35131EC155000AD0F6 /* PerformanceStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7754131EC154000AD0F6 /* PerformanceStats.cpp */; }; F56C7B37131EC155000AD0F6 /* RegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7758131EC154000AD0F6 /* RegExp.cpp */; }; @@ -839,13 +832,11 @@ F56C7BC9131EC2DB000AD0F6 /* XBMCAppliance.m in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BC2131EC2DB000AD0F6 /* XBMCAppliance.m */; }; F56C7BCA131EC2DB000AD0F6 /* XBMCController.mm in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BC5131EC2DB000AD0F6 /* XBMCController.mm */; }; F56C7BD0131EC301000AD0F6 /* XBMC.png in Resources */ = {isa = PBXBuildFile; fileRef = F56C7BCD131EC301000AD0F6 /* XBMC.png */; }; - F56C7BD6131EC332000AD0F6 /* IOSCoreAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BD2131EC332000AD0F6 /* IOSCoreAudio.cpp */; }; F56C7BDC131EC390000AD0F6 /* WinEventsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BD9131EC390000AD0F6 /* WinEventsIOS.mm */; }; F56C7BDD131EC390000AD0F6 /* WinSystemIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BDB131EC390000AD0F6 /* WinSystemIOS.mm */; }; F56C7BE3131EC3F3000AD0F6 /* RenderSystemGLES.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BE0131EC3F3000AD0F6 /* RenderSystemGLES.cpp */; }; F56C7BE6131EC455000AD0F6 /* LinuxRendererGLES.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BE4131EC455000AD0F6 /* LinuxRendererGLES.cpp */; }; F56C7BE9131EC46E000AD0F6 /* yuv2rgb.neon.S in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BE7131EC46E000AD0F6 /* yuv2rgb.neon.S */; }; - F56C7BEC131EC495000AD0F6 /* IOSAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BEA131EC495000AD0F6 /* IOSAudioRenderer.cpp */; }; F56C7BF5131EC4E8000AD0F6 /* fastmemcpy-arm.S in Sources */ = {isa = PBXBuildFile; fileRef = F56C7BF3131EC4E8000AD0F6 /* fastmemcpy-arm.S */; }; F56C7D83131EF8D9000AD0F6 /* NptZip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7CB2131EF8D8000AD0F6 /* NptZip.cpp */; }; F56C7D84131EF8D9000AD0F6 /* NptStreams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C7CB4131EF8D8000AD0F6 /* NptStreams.cpp */; }; @@ -1037,7 +1028,6 @@ 7CEE2E6C13D6B7A8000ABF2A /* TimeSmoother.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeSmoother.h; sourceTree = "<group>"; }; 8316267613B670FF004AED87 /* README.ios */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.ios; sourceTree = "<group>"; }; 8D576316048677EA00EA77CD /* XBMC.frappliance */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XBMC.frappliance; sourceTree = BUILT_PRODUCTS_DIR; }; - A192FD47135E46C800D92E9B /* IOSAudioRingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOSAudioRingBuffer.h; path = AudioRenderers/IOSAudioRingBuffer.h; sourceTree = "<group>"; }; C807119D135DB842002F601B /* InputOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputOperations.cpp; sourceTree = "<group>"; }; C807119E135DB842002F601B /* InputOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputOperations.h; sourceTree = "<group>"; }; C893605E152C86EC00812418 /* PythonMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PythonMonitor.cpp; sourceTree = "<group>"; }; @@ -1505,9 +1495,6 @@ F56C725F131EC151000AD0F6 /* DVDAudioCodecPassthroughFFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDAudioCodecPassthroughFFmpeg.h; sourceTree = "<group>"; }; F56C7260131EC151000AD0F6 /* DVDAudioCodecPcm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDAudioCodecPcm.cpp; sourceTree = "<group>"; }; F56C7261131EC151000AD0F6 /* DVDAudioCodecPcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDAudioCodecPcm.h; sourceTree = "<group>"; }; - F56C7263131EC151000AD0F6 /* DVDAudioEncoderFFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DVDAudioEncoderFFmpeg.cpp; path = Encoders/DVDAudioEncoderFFmpeg.cpp; sourceTree = "<group>"; }; - F56C7264131EC151000AD0F6 /* DVDAudioEncoderFFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DVDAudioEncoderFFmpeg.h; path = Encoders/DVDAudioEncoderFFmpeg.h; sourceTree = "<group>"; }; - F56C7265131EC151000AD0F6 /* IDVDAudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IDVDAudioEncoder.h; path = Encoders/IDVDAudioEncoder.h; sourceTree = "<group>"; }; F56C7267131EC151000AD0F6 /* mad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mad.h; sourceTree = "<group>"; }; F56C7268131EC151000AD0F6 /* DVDCodecs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDCodecs.h; sourceTree = "<group>"; }; F56C7269131EC151000AD0F6 /* DVDCodecUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDCodecUtils.cpp; sourceTree = "<group>"; }; @@ -1697,11 +1684,6 @@ F56C7330131EC151000AD0F6 /* WAVcodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WAVcodec.h; sourceTree = "<group>"; }; F56C7333131EC151000AD0F6 /* YMCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YMCodec.cpp; sourceTree = "<group>"; }; F56C7334131EC151000AD0F6 /* YMCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YMCodec.h; sourceTree = "<group>"; }; - F56C7338131EC151000AD0F6 /* IAudioRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IAudioRenderer.h; path = AudioRenderers/IAudioRenderer.h; sourceTree = "<group>"; }; - F56C7339131EC151000AD0F6 /* AudioRendererFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioRendererFactory.h; path = AudioRenderers/AudioRendererFactory.h; sourceTree = "<group>"; }; - F56C733A131EC151000AD0F6 /* AudioRendererFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioRendererFactory.cpp; path = AudioRenderers/AudioRendererFactory.cpp; sourceTree = "<group>"; }; - F56C733B131EC151000AD0F6 /* NullDirectSound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NullDirectSound.cpp; path = AudioRenderers/NullDirectSound.cpp; sourceTree = "<group>"; }; - F56C733C131EC151000AD0F6 /* NullDirectSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NullDirectSound.h; path = AudioRenderers/NullDirectSound.h; sourceTree = "<group>"; }; F56C733E131EC151000AD0F6 /* BaseRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BaseRenderer.cpp; sourceTree = "<group>"; }; F56C733F131EC151000AD0F6 /* BaseRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseRenderer.h; sourceTree = "<group>"; }; F56C7344131EC151000AD0F6 /* OverlayRendererGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OverlayRendererGL.cpp; sourceTree = "<group>"; }; @@ -1991,7 +1973,6 @@ F56C749D131EC152000AD0F6 /* ZipManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZipManager.cpp; sourceTree = "<group>"; }; F56C749E131EC152000AD0F6 /* ZipManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipManager.h; sourceTree = "<group>"; }; F56C74A0131EC152000AD0F6 /* AnimatedGif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimatedGif.h; sourceTree = "<group>"; }; - F56C74A1131EC152000AD0F6 /* AudioContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContext.h; sourceTree = "<group>"; }; F56C74A2131EC152000AD0F6 /* D3DResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = D3DResource.h; sourceTree = "<group>"; }; F56C74A3131EC152000AD0F6 /* DDSImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDSImage.h; sourceTree = "<group>"; }; F56C74A4131EC152000AD0F6 /* DirectXGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectXGraphics.h; sourceTree = "<group>"; }; @@ -2045,7 +2026,6 @@ F56C74D6131EC152000AD0F6 /* GUISettingsSliderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISettingsSliderControl.h; sourceTree = "<group>"; }; F56C74D7131EC152000AD0F6 /* GUIShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIShader.h; sourceTree = "<group>"; }; F56C74D8131EC152000AD0F6 /* GUISliderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISliderControl.h; sourceTree = "<group>"; }; - F56C74D9131EC152000AD0F6 /* GUISound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISound.h; sourceTree = "<group>"; }; F56C74DA131EC152000AD0F6 /* GUISpinControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISpinControl.h; sourceTree = "<group>"; }; F56C74DB131EC152000AD0F6 /* GUISpinControlEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISpinControlEx.h; sourceTree = "<group>"; }; F56C74DC131EC152000AD0F6 /* GUIStandardWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIStandardWindow.h; sourceTree = "<group>"; }; @@ -2083,7 +2063,6 @@ F56C74FC131EC152000AD0F6 /* XBTF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBTF.h; sourceTree = "<group>"; }; F56C74FD131EC152000AD0F6 /* XBTFReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBTFReader.h; sourceTree = "<group>"; }; F56C74FE131EC152000AD0F6 /* AnimatedGif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimatedGif.cpp; sourceTree = "<group>"; }; - F56C74FF131EC152000AD0F6 /* AudioContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioContext.cpp; sourceTree = "<group>"; }; F56C7500131EC152000AD0F6 /* D3DResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = D3DResource.cpp; sourceTree = "<group>"; }; F56C7501131EC152000AD0F6 /* DDSImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DDSImage.cpp; sourceTree = "<group>"; }; F56C7502131EC152000AD0F6 /* DirectXGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectXGraphics.cpp; sourceTree = "<group>"; }; @@ -2134,7 +2113,6 @@ F56C7530131EC152000AD0F6 /* GUISettingsSliderControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISettingsSliderControl.cpp; sourceTree = "<group>"; }; F56C7531131EC152000AD0F6 /* GUIShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIShader.cpp; sourceTree = "<group>"; }; F56C7532131EC152000AD0F6 /* GUISliderControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISliderControl.cpp; sourceTree = "<group>"; }; - F56C7533131EC152000AD0F6 /* GUISound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISound.cpp; sourceTree = "<group>"; }; F56C7534131EC152000AD0F6 /* GUISpinControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISpinControl.cpp; sourceTree = "<group>"; }; F56C7535131EC152000AD0F6 /* GUISpinControlEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISpinControlEx.cpp; sourceTree = "<group>"; }; F56C7536131EC152000AD0F6 /* GUIStandardWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIStandardWindow.cpp; sourceTree = "<group>"; }; @@ -2604,10 +2582,6 @@ F56C774B131EC154000AD0F6 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = "<group>"; }; F56C774C131EC154000AD0F6 /* md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = md5.cpp; sourceTree = "<group>"; }; F56C774D131EC154000AD0F6 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = "<group>"; }; - F56C774E131EC154000AD0F6 /* PCMAmplifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMAmplifier.cpp; sourceTree = "<group>"; }; - F56C774F131EC154000AD0F6 /* PCMAmplifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMAmplifier.h; sourceTree = "<group>"; }; - F56C7750131EC154000AD0F6 /* PCMRemap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMRemap.cpp; sourceTree = "<group>"; }; - F56C7751131EC154000AD0F6 /* PCMRemap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMRemap.h; sourceTree = "<group>"; }; F56C7752131EC154000AD0F6 /* PerformanceSample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceSample.cpp; sourceTree = "<group>"; }; F56C7753131EC154000AD0F6 /* PerformanceSample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceSample.h; sourceTree = "<group>"; }; F56C7754131EC154000AD0F6 /* PerformanceStats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceStats.cpp; sourceTree = "<group>"; }; @@ -2791,8 +2765,6 @@ F56C7BC8131EC2DB000AD0F6 /* XBMCDebugHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCDebugHelpers.h; sourceTree = "<group>"; }; F56C7BCD131EC301000AD0F6 /* XBMC.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = XBMC.png; sourceTree = "<group>"; }; F56C7BCE131EC301000AD0F6 /* XBMCATV2-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "XBMCATV2-Info.plist"; sourceTree = "<group>"; }; - F56C7BD2131EC332000AD0F6 /* IOSCoreAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IOSCoreAudio.cpp; sourceTree = "<group>"; }; - F56C7BD3131EC332000AD0F6 /* IOSCoreAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSCoreAudio.h; sourceTree = "<group>"; }; F56C7BD8131EC390000AD0F6 /* WinEventsIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WinEventsIOS.h; sourceTree = "<group>"; }; F56C7BD9131EC390000AD0F6 /* WinEventsIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WinEventsIOS.mm; sourceTree = "<group>"; }; F56C7BDA131EC390000AD0F6 /* WinSystemIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WinSystemIOS.h; sourceTree = "<group>"; }; @@ -2803,8 +2775,6 @@ F56C7BE5131EC455000AD0F6 /* LinuxRendererGLES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinuxRendererGLES.h; sourceTree = "<group>"; }; F56C7BE7131EC46E000AD0F6 /* yuv2rgb.neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = yuv2rgb.neon.S; sourceTree = "<group>"; }; F56C7BE8131EC46E000AD0F6 /* yuv2rgb.neon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv2rgb.neon.h; sourceTree = "<group>"; }; - F56C7BEA131EC495000AD0F6 /* IOSAudioRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IOSAudioRenderer.cpp; path = AudioRenderers/IOSAudioRenderer.cpp; sourceTree = "<group>"; }; - F56C7BEB131EC495000AD0F6 /* IOSAudioRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOSAudioRenderer.h; path = AudioRenderers/IOSAudioRenderer.h; sourceTree = "<group>"; }; F56C7BF3131EC4E8000AD0F6 /* fastmemcpy-arm.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = "fastmemcpy-arm.S"; sourceTree = "<group>"; }; F56C7BF4131EC4E8000AD0F6 /* fastmemcpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fastmemcpy.h; sourceTree = "<group>"; }; F56C7CA6131EF8D8000AD0F6 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = Neptune/README.txt; sourceTree = "<group>"; }; @@ -3736,7 +3706,6 @@ F56C721B131EC151000AD0F6 /* cores */ = { isa = PBXGroup; children = ( - F56C7335131EC151000AD0F6 /* AudioRenderers */, DFB6628A15376810006B8FF1 /* AudioEngine */, F56C7222131EC151000AD0F6 /* DllLoader */, F56C724A131EC151000AD0F6 /* dvdplayer */, @@ -3890,7 +3859,6 @@ F56C7255131EC151000AD0F6 /* Audio */ = { isa = PBXGroup; children = ( - F56C7262131EC151000AD0F6 /* Encoders */, F56C7266131EC151000AD0F6 /* libmad */, F56C7256131EC151000AD0F6 /* DllLibMad.h */, F56C7257131EC151000AD0F6 /* DVDAudioCodec.h */, @@ -3910,16 +3878,6 @@ path = Audio; sourceTree = "<group>"; }; - F56C7262131EC151000AD0F6 /* Encoders */ = { - isa = PBXGroup; - children = ( - F56C7263131EC151000AD0F6 /* DVDAudioEncoderFFmpeg.cpp */, - F56C7264131EC151000AD0F6 /* DVDAudioEncoderFFmpeg.h */, - F56C7265131EC151000AD0F6 /* IDVDAudioEncoder.h */, - ); - name = Encoders; - sourceTree = "<group>"; - }; F56C7266131EC151000AD0F6 /* libmad */ = { isa = PBXGroup; children = ( @@ -4159,21 +4117,6 @@ path = paplayer; sourceTree = "<group>"; }; - F56C7335131EC151000AD0F6 /* AudioRenderers */ = { - isa = PBXGroup; - children = ( - F56C733A131EC151000AD0F6 /* AudioRendererFactory.cpp */, - F56C7339131EC151000AD0F6 /* AudioRendererFactory.h */, - F56C7338131EC151000AD0F6 /* IAudioRenderer.h */, - F56C7BEA131EC495000AD0F6 /* IOSAudioRenderer.cpp */, - F56C7BEB131EC495000AD0F6 /* IOSAudioRenderer.h */, - A192FD47135E46C800D92E9B /* IOSAudioRingBuffer.h */, - F56C733B131EC151000AD0F6 /* NullDirectSound.cpp */, - F56C733C131EC151000AD0F6 /* NullDirectSound.h */, - ); - name = AudioRenderers; - sourceTree = "<group>"; - }; F56C733D131EC151000AD0F6 /* VideoRenderers */ = { isa = PBXGroup; children = ( @@ -4601,8 +4544,6 @@ children = ( F56C74FE131EC152000AD0F6 /* AnimatedGif.cpp */, F56C74A0131EC152000AD0F6 /* AnimatedGif.h */, - F56C74FF131EC152000AD0F6 /* AudioContext.cpp */, - F56C74A1131EC152000AD0F6 /* AudioContext.h */, F56C7500131EC152000AD0F6 /* D3DResource.cpp */, F56C74A2131EC152000AD0F6 /* D3DResource.h */, F56C7501131EC152000AD0F6 /* DDSImage.cpp */, @@ -4713,8 +4654,6 @@ F56C74D7131EC152000AD0F6 /* GUIShader.h */, F56C7532131EC152000AD0F6 /* GUISliderControl.cpp */, F56C74D8131EC152000AD0F6 /* GUISliderControl.h */, - F56C7533131EC152000AD0F6 /* GUISound.cpp */, - F56C74D9131EC152000AD0F6 /* GUISound.h */, F56C7534131EC152000AD0F6 /* GUISpinControl.cpp */, F56C74DA131EC152000AD0F6 /* GUISpinControl.h */, F56C7535131EC152000AD0F6 /* GUISpinControlEx.cpp */, @@ -5196,8 +5135,6 @@ F5B13DFF13344F2A0045076D /* DarwinUtils.h */, F5B13E0013344F310045076D /* DarwinUtils.mm */, F56C7682131EC153000AD0F6 /* eprintf.cpp */, - F56C7BD2131EC332000AD0F6 /* IOSCoreAudio.cpp */, - F56C7BD3131EC332000AD0F6 /* IOSCoreAudio.h */, DFFD594B1506B6300088DE4B /* IOSEAGLView.h */, DFFD594C1506B6300088DE4B /* IOSEAGLView.mm */, DFFEFC2015160927001294DC /* IOSExternalTouchController.h */, @@ -5483,10 +5420,6 @@ F56C774D131EC154000AD0F6 /* md5.h */, 188F76271522186C009870CE /* Mime.cpp */, 188F76281522186C009870CE /* Mime.h */, - F56C774E131EC154000AD0F6 /* PCMAmplifier.cpp */, - F56C774F131EC154000AD0F6 /* PCMAmplifier.h */, - F56C7750131EC154000AD0F6 /* PCMRemap.cpp */, - F56C7751131EC154000AD0F6 /* PCMRemap.h */, F56C7752131EC154000AD0F6 /* PerformanceSample.cpp */, F56C7753131EC154000AD0F6 /* PerformanceSample.h */, F56C7754131EC154000AD0F6 /* PerformanceStats.cpp */, @@ -6417,7 +6350,6 @@ F56C78E7131EC154000AD0F6 /* DVDAudioCodecLPcm.cpp in Sources */, F56C78E8131EC154000AD0F6 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */, F56C78E9131EC154000AD0F6 /* DVDAudioCodecPcm.cpp in Sources */, - F56C78EA131EC154000AD0F6 /* DVDAudioEncoderFFmpeg.cpp in Sources */, F56C78EB131EC154000AD0F6 /* DVDCodecUtils.cpp in Sources */, F56C78EC131EC154000AD0F6 /* DVDFactoryCodec.cpp in Sources */, F56C78ED131EC154000AD0F6 /* DVDOverlayCodecSSA.cpp in Sources */, @@ -6498,8 +6430,6 @@ F56C793C131EC154000AD0F6 /* TimidityCodec.cpp in Sources */, F56C793D131EC154000AD0F6 /* WAVcodec.cpp in Sources */, F56C793F131EC154000AD0F6 /* YMCodec.cpp in Sources */, - F56C7941131EC154000AD0F6 /* AudioRendererFactory.cpp in Sources */, - F56C7942131EC154000AD0F6 /* NullDirectSound.cpp in Sources */, F56C7943131EC154000AD0F6 /* BaseRenderer.cpp in Sources */, F56C7946131EC154000AD0F6 /* OverlayRendererGL.cpp in Sources */, F56C7947131EC154000AD0F6 /* OverlayRenderer.cpp in Sources */, @@ -6645,7 +6575,6 @@ F56C79EE131EC154000AD0F6 /* ZipDirectory.cpp in Sources */, F56C79EF131EC154000AD0F6 /* ZipManager.cpp in Sources */, F56C79F0131EC154000AD0F6 /* AnimatedGif.cpp in Sources */, - F56C79F1131EC154000AD0F6 /* AudioContext.cpp in Sources */, F56C79F2131EC154000AD0F6 /* D3DResource.cpp in Sources */, F56C79F3131EC154000AD0F6 /* DDSImage.cpp in Sources */, F56C79F4131EC154000AD0F6 /* DirectXGraphics.cpp in Sources */, @@ -6696,7 +6625,6 @@ F56C7A22131EC154000AD0F6 /* GUISettingsSliderControl.cpp in Sources */, F56C7A23131EC154000AD0F6 /* GUIShader.cpp in Sources */, F56C7A24131EC154000AD0F6 /* GUISliderControl.cpp in Sources */, - F56C7A25131EC154000AD0F6 /* GUISound.cpp in Sources */, F56C7A26131EC154000AD0F6 /* GUISpinControl.cpp in Sources */, F56C7A27131EC154000AD0F6 /* GUISpinControlEx.cpp in Sources */, F56C7A28131EC154000AD0F6 /* GUIStandardWindow.cpp in Sources */, @@ -6944,8 +6872,6 @@ F56C7B2F131EC155000AD0F6 /* LCD.cpp in Sources */, F56C7B30131EC155000AD0F6 /* log.cpp in Sources */, F56C7B31131EC155000AD0F6 /* md5.cpp in Sources */, - F56C7B32131EC155000AD0F6 /* PCMAmplifier.cpp in Sources */, - F56C7B33131EC155000AD0F6 /* PCMRemap.cpp in Sources */, F56C7B34131EC155000AD0F6 /* PerformanceSample.cpp in Sources */, F56C7B35131EC155000AD0F6 /* PerformanceStats.cpp in Sources */, F56C7B37131EC155000AD0F6 /* RegExp.cpp in Sources */, @@ -7032,13 +6958,11 @@ F56C7B9B131EC1B4000AD0F6 /* AutoPool.mm in Sources */, F56C7BC9131EC2DB000AD0F6 /* XBMCAppliance.m in Sources */, F56C7BCA131EC2DB000AD0F6 /* XBMCController.mm in Sources */, - F56C7BD6131EC332000AD0F6 /* IOSCoreAudio.cpp in Sources */, F56C7BDC131EC390000AD0F6 /* WinEventsIOS.mm in Sources */, F56C7BDD131EC390000AD0F6 /* WinSystemIOS.mm in Sources */, F56C7BE3131EC3F3000AD0F6 /* RenderSystemGLES.cpp in Sources */, F56C7BE6131EC455000AD0F6 /* LinuxRendererGLES.cpp in Sources */, F56C7BE9131EC46E000AD0F6 /* yuv2rgb.neon.S in Sources */, - F56C7BEC131EC495000AD0F6 /* IOSAudioRenderer.cpp in Sources */, F56C7BF5131EC4E8000AD0F6 /* fastmemcpy-arm.S in Sources */, F56C7D83131EF8D9000AD0F6 /* NptZip.cpp in Sources */, F56C7D84131EF8D9000AD0F6 /* NptStreams.cpp in Sources */, diff --git a/XBMC-IOS.xcodeproj/project.pbxproj b/XBMC-IOS.xcodeproj/project.pbxproj index eb1d407b5d..9815942f67 100644 --- a/XBMC-IOS.xcodeproj/project.pbxproj +++ b/XBMC-IOS.xcodeproj/project.pbxproj @@ -281,9 +281,6 @@ F56C88B4131F42ED000AD0F6 /* EncoderLame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C81EF131F42E6000AD0F6 /* EncoderLame.cpp */; }; F56C88B5131F42ED000AD0F6 /* EncoderVorbis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C81F1131F42E6000AD0F6 /* EncoderVorbis.cpp */; }; F56C88B6131F42ED000AD0F6 /* EncoderWav.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C81F3131F42E6000AD0F6 /* EncoderWav.cpp */; }; - F56C88B7131F42ED000AD0F6 /* IOSAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C81FF131F42E6000AD0F6 /* IOSAudioRenderer.cpp */; }; - F56C88B8131F42ED000AD0F6 /* AudioRendererFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8203131F42E6000AD0F6 /* AudioRendererFactory.cpp */; }; - F56C88B9131F42ED000AD0F6 /* NullDirectSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8204131F42E6000AD0F6 /* NullDirectSound.cpp */; }; F56C88BA131F42ED000AD0F6 /* coff.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8207131F42E6000AD0F6 /* coff.cpp */; }; F56C88BB131F42ED000AD0F6 /* dll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C820A131F42E6000AD0F6 /* dll.cpp */; }; F56C88BC131F42ED000AD0F6 /* dll_tracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C820C131F42E6000AD0F6 /* dll_tracker.cpp */; }; @@ -306,7 +303,6 @@ F56C88CE131F42ED000AD0F6 /* DVDTSCorrection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8231131F42E6000AD0F6 /* DVDTSCorrection.cpp */; }; F56C88CF131F42ED000AD0F6 /* DVDAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8234131F42E6000AD0F6 /* DVDAudio.cpp */; }; F56C88D0131F42ED000AD0F6 /* DVDClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8236131F42E6000AD0F6 /* DVDClock.cpp */; }; - F56C88D1131F42ED000AD0F6 /* DVDAudioEncoderFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C823B131F42E6000AD0F6 /* DVDAudioEncoderFFmpeg.cpp */; }; F56C88D2131F42ED000AD0F6 /* DVDAudioCodecFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8240131F42E6000AD0F6 /* DVDAudioCodecFFmpeg.cpp */; }; F56C88D3131F42ED000AD0F6 /* DVDAudioCodecLibMad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8242131F42E6000AD0F6 /* DVDAudioCodecLibMad.cpp */; }; F56C88D4131F42ED000AD0F6 /* DVDAudioCodecLPcm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8244131F42E6000AD0F6 /* DVDAudioCodecLPcm.cpp */; }; @@ -542,7 +538,6 @@ F56C89D8131F42ED000AD0F6 /* ZipDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C847E131F42E9000AD0F6 /* ZipDirectory.cpp */; }; F56C89D9131F42ED000AD0F6 /* ZipManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8480131F42E9000AD0F6 /* ZipManager.cpp */; }; F56C89DA131F42ED000AD0F6 /* AnimatedGif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C84E1131F42E9000AD0F6 /* AnimatedGif.cpp */; }; - F56C89DB131F42ED000AD0F6 /* AudioContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C84E2131F42E9000AD0F6 /* AudioContext.cpp */; }; F56C89DC131F42ED000AD0F6 /* D3DResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C84E3131F42E9000AD0F6 /* D3DResource.cpp */; }; F56C89DD131F42ED000AD0F6 /* DDSImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C84E4131F42E9000AD0F6 /* DDSImage.cpp */; }; F56C89DE131F42ED000AD0F6 /* DirectXGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C84E5131F42E9000AD0F6 /* DirectXGraphics.cpp */; }; @@ -593,7 +588,6 @@ F56C8A0C131F42ED000AD0F6 /* GUISettingsSliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8513131F42E9000AD0F6 /* GUISettingsSliderControl.cpp */; }; F56C8A0D131F42ED000AD0F6 /* GUIShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8514131F42E9000AD0F6 /* GUIShader.cpp */; }; F56C8A0E131F42ED000AD0F6 /* GUISliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8515131F42E9000AD0F6 /* GUISliderControl.cpp */; }; - F56C8A0F131F42ED000AD0F6 /* GUISound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8516131F42E9000AD0F6 /* GUISound.cpp */; }; F56C8A10131F42ED000AD0F6 /* GUISpinControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8517131F42E9000AD0F6 /* GUISpinControl.cpp */; }; F56C8A11131F42ED000AD0F6 /* GUISpinControlEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8518131F42E9000AD0F6 /* GUISpinControlEx.cpp */; }; F56C8A12131F42ED000AD0F6 /* GUIStandardWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8519131F42E9000AD0F6 /* GUIStandardWindow.cpp */; }; @@ -760,7 +754,6 @@ F56C8AB9131F42ED000AD0F6 /* ZeroconfBrowser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8654131F42EB000AD0F6 /* ZeroconfBrowser.cpp */; }; F56C8ABA131F42ED000AD0F6 /* cddb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8656131F42EB000AD0F6 /* cddb.cpp */; }; F56C8ABB131F42ED000AD0F6 /* AutoPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = F56C865A131F42EB000AD0F6 /* AutoPool.mm */; }; - F56C8AC2131F42ED000AD0F6 /* IOSCoreAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8669131F42EB000AD0F6 /* IOSCoreAudio.cpp */; }; F56C8AC3131F42ED000AD0F6 /* OSXGNUReplacements.c in Sources */ = {isa = PBXBuildFile; fileRef = F56C866B131F42EB000AD0F6 /* OSXGNUReplacements.c */; }; F56C8AC5131F42ED000AD0F6 /* eprintf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C866F131F42EB000AD0F6 /* eprintf.cpp */; }; F56C8AC6131F42ED000AD0F6 /* GUIDialogPictureInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8673131F42EB000AD0F6 /* GUIDialogPictureInfo.cpp */; }; @@ -845,8 +838,6 @@ F56C8B1E131F42ED000AD0F6 /* LCD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8737131F42EC000AD0F6 /* LCD.cpp */; }; F56C8B1F131F42ED000AD0F6 /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8739131F42EC000AD0F6 /* log.cpp */; }; F56C8B20131F42ED000AD0F6 /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C873B131F42EC000AD0F6 /* md5.cpp */; }; - F56C8B21131F42ED000AD0F6 /* PCMAmplifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C873D131F42EC000AD0F6 /* PCMAmplifier.cpp */; }; - F56C8B22131F42ED000AD0F6 /* PCMRemap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C873F131F42EC000AD0F6 /* PCMRemap.cpp */; }; F56C8B23131F42ED000AD0F6 /* PerformanceSample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8741131F42EC000AD0F6 /* PerformanceSample.cpp */; }; F56C8B24131F42ED000AD0F6 /* PerformanceStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8743131F42EC000AD0F6 /* PerformanceStats.cpp */; }; F56C8B26131F42ED000AD0F6 /* RegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56C8747131F42EC000AD0F6 /* RegExp.cpp */; }; @@ -1632,13 +1623,7 @@ F56C81F2131F42E6000AD0F6 /* EncoderVorbis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncoderVorbis.h; sourceTree = "<group>"; }; F56C81F3131F42E6000AD0F6 /* EncoderWav.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EncoderWav.cpp; sourceTree = "<group>"; }; F56C81F4131F42E6000AD0F6 /* EncoderWav.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncoderWav.h; sourceTree = "<group>"; }; - F56C81FF131F42E6000AD0F6 /* IOSAudioRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IOSAudioRenderer.cpp; path = AudioRenderers/IOSAudioRenderer.cpp; sourceTree = "<group>"; }; - F56C8200131F42E6000AD0F6 /* IOSAudioRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOSAudioRenderer.h; path = AudioRenderers/IOSAudioRenderer.h; sourceTree = "<group>"; }; - F56C8201131F42E6000AD0F6 /* IAudioRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IAudioRenderer.h; path = AudioRenderers/IAudioRenderer.h; sourceTree = "<group>"; }; - F56C8202131F42E6000AD0F6 /* AudioRendererFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioRendererFactory.h; path = AudioRenderers/AudioRendererFactory.h; sourceTree = "<group>"; }; - F56C8203131F42E6000AD0F6 /* AudioRendererFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioRendererFactory.cpp; path = AudioRenderers/AudioRendererFactory.cpp; sourceTree = "<group>"; }; - F56C8204131F42E6000AD0F6 /* NullDirectSound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NullDirectSound.cpp; path = AudioRenderers/NullDirectSound.cpp; sourceTree = "<group>"; }; - F56C8205131F42E6000AD0F6 /* NullDirectSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NullDirectSound.h; path = AudioRenderers/NullDirectSound.h; sourceTree = "<group>"; }; + F56C81F6131F42E6000AD0F6 /* lame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lame.h; sourceTree = "<group>"; }; F56C8207131F42E6000AD0F6 /* coff.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coff.cpp; sourceTree = "<group>"; }; F56C8208131F42E6000AD0F6 /* coff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coff.h; sourceTree = "<group>"; }; F56C8209131F42E6000AD0F6 /* coffldr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coffldr.h; sourceTree = "<group>"; }; @@ -1684,9 +1669,6 @@ F56C8235131F42E6000AD0F6 /* DVDAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDAudio.h; sourceTree = "<group>"; }; F56C8236131F42E6000AD0F6 /* DVDClock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDClock.cpp; sourceTree = "<group>"; }; F56C8237131F42E6000AD0F6 /* DVDClock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDClock.h; sourceTree = "<group>"; }; - F56C823B131F42E6000AD0F6 /* DVDAudioEncoderFFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DVDAudioEncoderFFmpeg.cpp; path = Encoders/DVDAudioEncoderFFmpeg.cpp; sourceTree = "<group>"; }; - F56C823C131F42E6000AD0F6 /* DVDAudioEncoderFFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DVDAudioEncoderFFmpeg.h; path = Encoders/DVDAudioEncoderFFmpeg.h; sourceTree = "<group>"; }; - F56C823D131F42E6000AD0F6 /* IDVDAudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IDVDAudioEncoder.h; path = Encoders/IDVDAudioEncoder.h; sourceTree = "<group>"; }; F56C823E131F42E6000AD0F6 /* DllLibMad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DllLibMad.h; sourceTree = "<group>"; }; F56C823F131F42E6000AD0F6 /* DVDAudioCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDAudioCodec.h; sourceTree = "<group>"; }; F56C8240131F42E6000AD0F6 /* DVDAudioCodecFFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDAudioCodecFFmpeg.cpp; sourceTree = "<group>"; }; @@ -2188,7 +2170,6 @@ F56C8480131F42E9000AD0F6 /* ZipManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZipManager.cpp; sourceTree = "<group>"; }; F56C8481131F42E9000AD0F6 /* ZipManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipManager.h; sourceTree = "<group>"; }; F56C8483131F42E9000AD0F6 /* AnimatedGif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimatedGif.h; sourceTree = "<group>"; }; - F56C8484131F42E9000AD0F6 /* AudioContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContext.h; sourceTree = "<group>"; }; F56C8485131F42E9000AD0F6 /* D3DResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = D3DResource.h; sourceTree = "<group>"; }; F56C8486131F42E9000AD0F6 /* DDSImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDSImage.h; sourceTree = "<group>"; }; F56C8487131F42E9000AD0F6 /* DirectXGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectXGraphics.h; sourceTree = "<group>"; }; @@ -2242,7 +2223,6 @@ F56C84B9131F42E9000AD0F6 /* GUISettingsSliderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISettingsSliderControl.h; sourceTree = "<group>"; }; F56C84BA131F42E9000AD0F6 /* GUIShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIShader.h; sourceTree = "<group>"; }; F56C84BB131F42E9000AD0F6 /* GUISliderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISliderControl.h; sourceTree = "<group>"; }; - F56C84BC131F42E9000AD0F6 /* GUISound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISound.h; sourceTree = "<group>"; }; F56C84BD131F42E9000AD0F6 /* GUISpinControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISpinControl.h; sourceTree = "<group>"; }; F56C84BE131F42E9000AD0F6 /* GUISpinControlEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISpinControlEx.h; sourceTree = "<group>"; }; F56C84BF131F42E9000AD0F6 /* GUIStandardWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIStandardWindow.h; sourceTree = "<group>"; }; @@ -2280,7 +2260,6 @@ F56C84DF131F42E9000AD0F6 /* XBTF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBTF.h; sourceTree = "<group>"; }; F56C84E0131F42E9000AD0F6 /* XBTFReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBTFReader.h; sourceTree = "<group>"; }; F56C84E1131F42E9000AD0F6 /* AnimatedGif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimatedGif.cpp; sourceTree = "<group>"; }; - F56C84E2131F42E9000AD0F6 /* AudioContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioContext.cpp; sourceTree = "<group>"; }; F56C84E3131F42E9000AD0F6 /* D3DResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = D3DResource.cpp; sourceTree = "<group>"; }; F56C84E4131F42E9000AD0F6 /* DDSImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DDSImage.cpp; sourceTree = "<group>"; }; F56C84E5131F42E9000AD0F6 /* DirectXGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectXGraphics.cpp; sourceTree = "<group>"; }; @@ -2331,7 +2310,6 @@ F56C8513131F42E9000AD0F6 /* GUISettingsSliderControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISettingsSliderControl.cpp; sourceTree = "<group>"; }; F56C8514131F42E9000AD0F6 /* GUIShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIShader.cpp; sourceTree = "<group>"; }; F56C8515131F42E9000AD0F6 /* GUISliderControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISliderControl.cpp; sourceTree = "<group>"; }; - F56C8516131F42E9000AD0F6 /* GUISound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISound.cpp; sourceTree = "<group>"; }; F56C8517131F42E9000AD0F6 /* GUISpinControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISpinControl.cpp; sourceTree = "<group>"; }; F56C8518131F42E9000AD0F6 /* GUISpinControlEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISpinControlEx.cpp; sourceTree = "<group>"; }; F56C8519131F42E9000AD0F6 /* GUIStandardWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIStandardWindow.cpp; sourceTree = "<group>"; }; @@ -2629,8 +2607,6 @@ F56C8657131F42EB000AD0F6 /* cddb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cddb.h; sourceTree = "<group>"; }; F56C8659131F42EB000AD0F6 /* AutoPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoPool.h; sourceTree = "<group>"; }; F56C865A131F42EB000AD0F6 /* AutoPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutoPool.mm; sourceTree = "<group>"; }; - F56C8669131F42EB000AD0F6 /* IOSCoreAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IOSCoreAudio.cpp; sourceTree = "<group>"; }; - F56C866A131F42EB000AD0F6 /* IOSCoreAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSCoreAudio.h; sourceTree = "<group>"; }; F56C866B131F42EB000AD0F6 /* OSXGNUReplacements.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OSXGNUReplacements.c; sourceTree = "<group>"; }; F56C866C131F42EB000AD0F6 /* OSXGNUReplacements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSXGNUReplacements.h; sourceTree = "<group>"; }; F56C866F131F42EB000AD0F6 /* eprintf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = eprintf.cpp; sourceTree = "<group>"; }; @@ -2809,10 +2785,6 @@ F56C873A131F42EC000AD0F6 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = "<group>"; }; F56C873B131F42EC000AD0F6 /* md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = md5.cpp; sourceTree = "<group>"; }; F56C873C131F42EC000AD0F6 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = "<group>"; }; - F56C873D131F42EC000AD0F6 /* PCMAmplifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMAmplifier.cpp; sourceTree = "<group>"; }; - F56C873E131F42EC000AD0F6 /* PCMAmplifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMAmplifier.h; sourceTree = "<group>"; }; - F56C873F131F42EC000AD0F6 /* PCMRemap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMRemap.cpp; sourceTree = "<group>"; }; - F56C8740131F42EC000AD0F6 /* PCMRemap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMRemap.h; sourceTree = "<group>"; }; F56C8741131F42EC000AD0F6 /* PerformanceSample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceSample.cpp; sourceTree = "<group>"; }; F56C8742131F42EC000AD0F6 /* PerformanceSample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceSample.h; sourceTree = "<group>"; }; F56C8743131F42EC000AD0F6 /* PerformanceStats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceStats.cpp; sourceTree = "<group>"; }; @@ -3043,7 +3015,6 @@ F5AE415A134175520004BD79 /* XBMCOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCOperations.h; sourceTree = "<group>"; }; F5AE452E134D2E3E0004BD79 /* JSONServiceDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSONServiceDescription.cpp; sourceTree = "<group>"; }; F5AE452F134D2E3E0004BD79 /* JSONServiceDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONServiceDescription.h; sourceTree = "<group>"; }; - F5AE539813673FC70004BD79 /* IOSAudioRingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOSAudioRingBuffer.h; path = AudioRenderers/IOSAudioRingBuffer.h; sourceTree = "<group>"; }; F5B13DCD1334490D0045076D /* DarwinUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DarwinUtils.h; sourceTree = "<group>"; }; F5B13DCE1334490D0045076D /* DarwinUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DarwinUtils.mm; sourceTree = "<group>"; }; F5BD034D148D496A001B5583 /* CryptThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptThreading.cpp; sourceTree = "<group>"; }; @@ -4092,7 +4063,6 @@ F56C81FD131F42E6000AD0F6 /* cores */ = { isa = PBXGroup; children = ( - F56C81FE131F42E6000AD0F6 /* AudioRenderers */, DFB6620415376791006B8FF1 /* AudioEngine */, F56C8206131F42E6000AD0F6 /* DllLoader */, F56C822E131F42E6000AD0F6 /* dvdplayer */, @@ -4108,21 +4078,6 @@ path = cores; sourceTree = "<group>"; }; - F56C81FE131F42E6000AD0F6 /* AudioRenderers */ = { - isa = PBXGroup; - children = ( - F56C8203131F42E6000AD0F6 /* AudioRendererFactory.cpp */, - F56C8202131F42E6000AD0F6 /* AudioRendererFactory.h */, - F56C8201131F42E6000AD0F6 /* IAudioRenderer.h */, - F56C81FF131F42E6000AD0F6 /* IOSAudioRenderer.cpp */, - F56C8200131F42E6000AD0F6 /* IOSAudioRenderer.h */, - F5AE539813673FC70004BD79 /* IOSAudioRingBuffer.h */, - F56C8204131F42E6000AD0F6 /* NullDirectSound.cpp */, - F56C8205131F42E6000AD0F6 /* NullDirectSound.h */, - ); - name = AudioRenderers; - sourceTree = "<group>"; - }; F56C8206131F42E6000AD0F6 /* DllLoader */ = { isa = PBXGroup; children = ( @@ -4249,7 +4204,6 @@ F56C8239131F42E6000AD0F6 /* Audio */ = { isa = PBXGroup; children = ( - F56C823A131F42E6000AD0F6 /* Encoders */, F56C8249131F42E6000AD0F6 /* libmad */, F56C823E131F42E6000AD0F6 /* DllLibMad.h */, F56C823F131F42E6000AD0F6 /* DVDAudioCodec.h */, @@ -4269,16 +4223,6 @@ path = Audio; sourceTree = "<group>"; }; - F56C823A131F42E6000AD0F6 /* Encoders */ = { - isa = PBXGroup; - children = ( - F56C823B131F42E6000AD0F6 /* DVDAudioEncoderFFmpeg.cpp */, - F56C823C131F42E6000AD0F6 /* DVDAudioEncoderFFmpeg.h */, - F56C823D131F42E6000AD0F6 /* IDVDAudioEncoder.h */, - ); - name = Encoders; - sourceTree = "<group>"; - }; F56C8249131F42E6000AD0F6 /* libmad */ = { isa = PBXGroup; children = ( @@ -4957,8 +4901,6 @@ children = ( F56C84E1131F42E9000AD0F6 /* AnimatedGif.cpp */, F56C8483131F42E9000AD0F6 /* AnimatedGif.h */, - F56C84E2131F42E9000AD0F6 /* AudioContext.cpp */, - F56C8484131F42E9000AD0F6 /* AudioContext.h */, F56C84E3131F42E9000AD0F6 /* D3DResource.cpp */, F56C8485131F42E9000AD0F6 /* D3DResource.h */, F56C84E4131F42E9000AD0F6 /* DDSImage.cpp */, @@ -5069,8 +5011,6 @@ F56C84BA131F42E9000AD0F6 /* GUIShader.h */, F56C8515131F42E9000AD0F6 /* GUISliderControl.cpp */, F56C84BB131F42E9000AD0F6 /* GUISliderControl.h */, - F56C8516131F42E9000AD0F6 /* GUISound.cpp */, - F56C84BC131F42E9000AD0F6 /* GUISound.h */, F56C8517131F42E9000AD0F6 /* GUISpinControl.cpp */, F56C84BD131F42E9000AD0F6 /* GUISpinControl.h */, F56C8518131F42E9000AD0F6 /* GUISpinControlEx.cpp */, @@ -5552,8 +5492,6 @@ F5B13DCD1334490D0045076D /* DarwinUtils.h */, F5B13DCE1334490D0045076D /* DarwinUtils.mm */, F56C866F131F42EB000AD0F6 /* eprintf.cpp */, - F56C8669131F42EB000AD0F6 /* IOSCoreAudio.cpp */, - F56C866A131F42EB000AD0F6 /* IOSCoreAudio.h */, DFFD593E1506B5B10088DE4B /* IOSEAGLView.h */, DFFD593F1506B5B10088DE4B /* IOSEAGLView.mm */, DFFEFC0215160808001294DC /* IOSExternalTouchController.h */, @@ -5848,10 +5786,6 @@ F56C873C131F42EC000AD0F6 /* md5.h */, 188F761F1522184E009870CE /* Mime.cpp */, 188F76201522184E009870CE /* Mime.h */, - F56C873D131F42EC000AD0F6 /* PCMAmplifier.cpp */, - F56C873E131F42EC000AD0F6 /* PCMAmplifier.h */, - F56C873F131F42EC000AD0F6 /* PCMRemap.cpp */, - F56C8740131F42EC000AD0F6 /* PCMRemap.h */, F56C8741131F42EC000AD0F6 /* PerformanceSample.cpp */, F56C8742131F42EC000AD0F6 /* PerformanceSample.h */, F56C8743131F42EC000AD0F6 /* PerformanceStats.cpp */, @@ -6487,9 +6421,6 @@ F56C88B4131F42ED000AD0F6 /* EncoderLame.cpp in Sources */, F56C88B5131F42ED000AD0F6 /* EncoderVorbis.cpp in Sources */, F56C88B6131F42ED000AD0F6 /* EncoderWav.cpp in Sources */, - F56C88B7131F42ED000AD0F6 /* IOSAudioRenderer.cpp in Sources */, - F56C88B8131F42ED000AD0F6 /* AudioRendererFactory.cpp in Sources */, - F56C88B9131F42ED000AD0F6 /* NullDirectSound.cpp in Sources */, F56C88BA131F42ED000AD0F6 /* coff.cpp in Sources */, F56C88BB131F42ED000AD0F6 /* dll.cpp in Sources */, F56C88BC131F42ED000AD0F6 /* dll_tracker.cpp in Sources */, @@ -6512,7 +6443,6 @@ F56C88CE131F42ED000AD0F6 /* DVDTSCorrection.cpp in Sources */, F56C88CF131F42ED000AD0F6 /* DVDAudio.cpp in Sources */, F56C88D0131F42ED000AD0F6 /* DVDClock.cpp in Sources */, - F56C88D1131F42ED000AD0F6 /* DVDAudioEncoderFFmpeg.cpp in Sources */, F56C88D2131F42ED000AD0F6 /* DVDAudioCodecFFmpeg.cpp in Sources */, F56C88D3131F42ED000AD0F6 /* DVDAudioCodecLibMad.cpp in Sources */, F56C88D4131F42ED000AD0F6 /* DVDAudioCodecLPcm.cpp in Sources */, @@ -6748,7 +6678,6 @@ F56C89D8131F42ED000AD0F6 /* ZipDirectory.cpp in Sources */, F56C89D9131F42ED000AD0F6 /* ZipManager.cpp in Sources */, F56C89DA131F42ED000AD0F6 /* AnimatedGif.cpp in Sources */, - F56C89DB131F42ED000AD0F6 /* AudioContext.cpp in Sources */, F56C89DC131F42ED000AD0F6 /* D3DResource.cpp in Sources */, F56C89DD131F42ED000AD0F6 /* DDSImage.cpp in Sources */, F56C89DE131F42ED000AD0F6 /* DirectXGraphics.cpp in Sources */, @@ -6799,7 +6728,6 @@ F56C8A0C131F42ED000AD0F6 /* GUISettingsSliderControl.cpp in Sources */, F56C8A0D131F42ED000AD0F6 /* GUIShader.cpp in Sources */, F56C8A0E131F42ED000AD0F6 /* GUISliderControl.cpp in Sources */, - F56C8A0F131F42ED000AD0F6 /* GUISound.cpp in Sources */, F56C8A10131F42ED000AD0F6 /* GUISpinControl.cpp in Sources */, F56C8A11131F42ED000AD0F6 /* GUISpinControlEx.cpp in Sources */, F56C8A12131F42ED000AD0F6 /* GUIStandardWindow.cpp in Sources */, @@ -6966,7 +6894,6 @@ F56C8AB9131F42ED000AD0F6 /* ZeroconfBrowser.cpp in Sources */, F56C8ABA131F42ED000AD0F6 /* cddb.cpp in Sources */, F56C8ABB131F42ED000AD0F6 /* AutoPool.mm in Sources */, - F56C8AC2131F42ED000AD0F6 /* IOSCoreAudio.cpp in Sources */, F56C8AC3131F42ED000AD0F6 /* OSXGNUReplacements.c in Sources */, F56C8AC5131F42ED000AD0F6 /* eprintf.cpp in Sources */, F56C8AC6131F42ED000AD0F6 /* GUIDialogPictureInfo.cpp in Sources */, @@ -7051,8 +6978,6 @@ F56C8B1E131F42ED000AD0F6 /* LCD.cpp in Sources */, F56C8B1F131F42ED000AD0F6 /* log.cpp in Sources */, F56C8B20131F42ED000AD0F6 /* md5.cpp in Sources */, - F56C8B21131F42ED000AD0F6 /* PCMAmplifier.cpp in Sources */, - F56C8B22131F42ED000AD0F6 /* PCMRemap.cpp in Sources */, F56C8B23131F42ED000AD0F6 /* PerformanceSample.cpp in Sources */, F56C8B24131F42ED000AD0F6 /* PerformanceStats.cpp in Sources */, F56C8B26131F42ED000AD0F6 /* RegExp.cpp in Sources */, diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj index da591e1101..827ffd4b28 100644 --- a/XBMC.xcodeproj/project.pbxproj +++ b/XBMC.xcodeproj/project.pbxproj @@ -92,7 +92,6 @@ 18B7C3A812942132009E7A26 /* AdvancedSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C3A612942132009E7A26 /* AdvancedSettings.cpp */; }; 18B7C3A912942132009E7A26 /* AdvancedSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C3A612942132009E7A26 /* AdvancedSettings.cpp */; }; 18B7C7A91294222E009E7A26 /* AnimatedGif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7541294222E009E7A26 /* AnimatedGif.cpp */; }; - 18B7C7AA1294222E009E7A26 /* AudioContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7551294222E009E7A26 /* AudioContext.cpp */; }; 18B7C7AB1294222E009E7A26 /* D3DResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7561294222E009E7A26 /* D3DResource.cpp */; }; 18B7C7AC1294222E009E7A26 /* DDSImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7571294222E009E7A26 /* DDSImage.cpp */; }; 18B7C7AD1294222E009E7A26 /* DirectXGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7581294222E009E7A26 /* DirectXGraphics.cpp */; }; @@ -143,7 +142,6 @@ 18B7C7DB1294222E009E7A26 /* GUISettingsSliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7861294222E009E7A26 /* GUISettingsSliderControl.cpp */; }; 18B7C7DC1294222E009E7A26 /* GUIShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7871294222E009E7A26 /* GUIShader.cpp */; }; 18B7C7DD1294222E009E7A26 /* GUISliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7881294222E009E7A26 /* GUISliderControl.cpp */; }; - 18B7C7DE1294222E009E7A26 /* GUISound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7891294222E009E7A26 /* GUISound.cpp */; }; 18B7C7DF1294222E009E7A26 /* GUISpinControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C78A1294222E009E7A26 /* GUISpinControl.cpp */; }; 18B7C7E01294222E009E7A26 /* GUISpinControlEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C78B1294222E009E7A26 /* GUISpinControlEx.cpp */; }; 18B7C7E11294222E009E7A26 /* GUIStandardWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C78C1294222E009E7A26 /* GUIStandardWindow.cpp */; }; @@ -176,7 +174,6 @@ 18B7C7FC1294222E009E7A26 /* XBTF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7A71294222E009E7A26 /* XBTF.cpp */; }; 18B7C7FD1294222E009E7A26 /* XBTFReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7A81294222E009E7A26 /* XBTFReader.cpp */; }; 18B7C7FE1294222E009E7A26 /* AnimatedGif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7541294222E009E7A26 /* AnimatedGif.cpp */; }; - 18B7C7FF1294222E009E7A26 /* AudioContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7551294222E009E7A26 /* AudioContext.cpp */; }; 18B7C8001294222E009E7A26 /* D3DResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7561294222E009E7A26 /* D3DResource.cpp */; }; 18B7C8011294222E009E7A26 /* DDSImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7571294222E009E7A26 /* DDSImage.cpp */; }; 18B7C8021294222E009E7A26 /* DirectXGraphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7581294222E009E7A26 /* DirectXGraphics.cpp */; }; @@ -227,7 +224,6 @@ 18B7C8301294222E009E7A26 /* GUISettingsSliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7861294222E009E7A26 /* GUISettingsSliderControl.cpp */; }; 18B7C8311294222E009E7A26 /* GUIShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7871294222E009E7A26 /* GUIShader.cpp */; }; 18B7C8321294222E009E7A26 /* GUISliderControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7881294222E009E7A26 /* GUISliderControl.cpp */; }; - 18B7C8331294222E009E7A26 /* GUISound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C7891294222E009E7A26 /* GUISound.cpp */; }; 18B7C8341294222E009E7A26 /* GUISpinControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C78A1294222E009E7A26 /* GUISpinControl.cpp */; }; 18B7C8351294222E009E7A26 /* GUISpinControlEx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C78B1294222E009E7A26 /* GUISpinControlEx.cpp */; }; 18B7C8361294222E009E7A26 /* GUIStandardWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C78C1294222E009E7A26 /* GUIStandardWindow.cpp */; }; @@ -367,8 +363,6 @@ 18B7C9841294385F009E7A26 /* XMLUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18B7C9811294385F009E7A26 /* XMLUtils.cpp */; }; 18C1D22D13033F6A00CFFE59 /* GLUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18C1D22B13033F6A00CFFE59 /* GLUtils.cpp */; }; 18C1D22E13033F6A00CFFE59 /* GLUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18C1D22B13033F6A00CFFE59 /* GLUtils.cpp */; }; - 18CCEAEE1112F5B800615FC6 /* PCMRemap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18CCEAEC1112F5B800615FC6 /* PCMRemap.cpp */; }; - 18CCEAEF1112F5B800615FC6 /* PCMRemap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18CCEAEC1112F5B800615FC6 /* PCMRemap.cpp */; }; 18ECC96213CF178D00A9ED6C /* StreamUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18ECC96013CF178D00A9ED6C /* StreamUtils.cpp */; }; 32C631281423A90F00F18420 /* JpegIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32C631261423A90F00F18420 /* JpegIO.cpp */; }; 3802709A13D5A653009493DD /* SystemClock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3802709813D5A653009493DD /* SystemClock.cpp */; }; @@ -381,8 +375,6 @@ 431AE5D9109C1A63007428C3 /* OverlayRendererUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 431AE5D7109C1A63007428C3 /* OverlayRendererUtil.cpp */; }; 431AE5DA109C1A63007428C3 /* OverlayRendererUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 431AE5D7109C1A63007428C3 /* OverlayRendererUtil.cpp */; }; 43248C4E0FBE224000B88866 /* LockFree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B950FBC8E3B00171871 /* LockFree.cpp */; }; - 43248C510FBE224C00B88866 /* CoreAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B920FBC8DFF00171871 /* CoreAudio.cpp */; }; - 43248C520FBE224E00B88866 /* CoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B8E0FBC8DB000171871 /* CoreAudioRenderer.cpp */; }; 432D7CE412D86DA500CE4C49 /* NetworkLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 432D7CE312D86DA500CE4C49 /* NetworkLinux.cpp */; }; 432D7CE512D86DA500CE4C49 /* NetworkLinux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 432D7CE312D86DA500CE4C49 /* NetworkLinux.cpp */; }; 432D7CF712D870E800CE4C49 /* TCPServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 432D7CF612D870E800CE4C49 /* TCPServer.cpp */; }; @@ -588,8 +580,6 @@ 810C9FA90D67D1FB0095F5DD /* MythDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA50D67D1FB0095F5DD /* MythDirectory.cpp */; }; 810C9FAA0D67D1FB0095F5DD /* MythFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810C9FA70D67D1FB0095F5DD /* MythFile.cpp */; }; 815EE6350E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 815EE6330E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp */; }; - 83A72B910FBC8DB000171871 /* CoreAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B8E0FBC8DB000171871 /* CoreAudioRenderer.cpp */; }; - 83A72B940FBC8DFF00171871 /* CoreAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B920FBC8DFF00171871 /* CoreAudio.cpp */; }; 83A72B970FBC8E3B00171871 /* LockFree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A72B950FBC8E3B00171871 /* LockFree.cpp */; settings = {COMPILER_FLAGS = "-O0"; }; }; 83E0B2490F7C95FF0091643F /* Atomics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83E0B2480F7C95FF0091643F /* Atomics.cpp */; }; 83E0B24A0F7C95FF0091643F /* Atomics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83E0B2480F7C95FF0091643F /* Atomics.cpp */; }; @@ -1153,7 +1143,6 @@ E38E22E40D25F9FE00618676 /* MusicAlbumInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E650D25F9FD00618676 /* MusicAlbumInfo.cpp */; }; E38E22E50D25F9FE00618676 /* MusicInfoScraper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E670D25F9FD00618676 /* MusicInfoScraper.cpp */; }; E38E22E70D25F9FE00618676 /* Network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E6B0D25F9FD00618676 /* Network.cpp */; }; - E38E22E80D25F9FE00618676 /* PCMAmplifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E6D0D25F9FD00618676 /* PCMAmplifier.cpp */; }; E38E22E90D25F9FE00618676 /* PerformanceSample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E6F0D25F9FD00618676 /* PerformanceSample.cpp */; }; E38E22EA0D25F9FE00618676 /* PerformanceStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E710D25F9FD00618676 /* PerformanceStats.cpp */; }; E38E22EB0D25F9FE00618676 /* RegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E730D25F9FD00618676 /* RegExp.cpp */; }; @@ -1342,8 +1331,6 @@ F599CD2C108E65370010EC2A /* IoSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F599CD29108E65370010EC2A /* IoSupport.cpp */; }; F599CD74108E6A7A0010EC2A /* DarwinStorageProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F599CD73108E6A7A0010EC2A /* DarwinStorageProvider.cpp */; }; F599CD75108E6A7A0010EC2A /* DarwinStorageProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F599CD73108E6A7A0010EC2A /* DarwinStorageProvider.cpp */; }; - F5A00B080EFDDDFC00CD59F3 /* AudioRendererFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A00B070EFDDDFC00CD59F3 /* AudioRendererFactory.cpp */; }; - F5A00B260EFDE44100CD59F3 /* NullDirectSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A00B240EFDE44100CD59F3 /* NullDirectSound.cpp */; }; F5A1C8C00F6B06CF00A96ABD /* Application.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E14640D25F9F900618676 /* Application.cpp */; }; F5A1C8C10F6B06CF00A96ABD /* ApplicationMessenger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E14660D25F9F900618676 /* ApplicationMessenger.cpp */; }; F5A1C8C40F6B06CF00A96ABD /* Autorun.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E146E0D25F9F900618676 /* Autorun.cpp */; }; @@ -1719,7 +1706,6 @@ F5A1CAD60F6B06CF00A96ABD /* MusicAlbumInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E650D25F9FD00618676 /* MusicAlbumInfo.cpp */; }; F5A1CAD70F6B06CF00A96ABD /* MusicInfoScraper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E670D25F9FD00618676 /* MusicInfoScraper.cpp */; }; F5A1CAD90F6B06CF00A96ABD /* Network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E6B0D25F9FD00618676 /* Network.cpp */; }; - F5A1CADA0F6B06CF00A96ABD /* PCMAmplifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E6D0D25F9FD00618676 /* PCMAmplifier.cpp */; }; F5A1CADB0F6B06CF00A96ABD /* PerformanceSample.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E6F0D25F9FD00618676 /* PerformanceSample.cpp */; }; F5A1CADC0F6B06CF00A96ABD /* PerformanceStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E710D25F9FD00618676 /* PerformanceStats.cpp */; }; F5A1CADD0F6B06CF00A96ABD /* RegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38E1E730D25F9FD00618676 /* RegExp.cpp */; }; @@ -1821,8 +1807,6 @@ F5A1CB7C0F6B06CF00A96ABD /* VTPFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5FAB0700EFABAC800BAD4AE /* VTPFile.cpp */; }; F5A1CB7D0F6B06CF00A96ABD /* VTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5FAB0750EFABE2C00BAD4AE /* VTPDirectory.cpp */; }; F5A1CB7E0F6B06CF00A96ABD /* VTPSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5FAB0790EFABE4A00BAD4AE /* VTPSession.cpp */; }; - F5A1CB7F0F6B06CF00A96ABD /* AudioRendererFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A00B070EFDDDFC00CD59F3 /* AudioRendererFactory.cpp */; }; - F5A1CB800F6B06CF00A96ABD /* NullDirectSound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5A00B240EFDE44100CD59F3 /* NullDirectSound.cpp */; }; F5A1CB810F6B06CF00A96ABD /* ExternalPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C5608C40F1754930056433A /* ExternalPlayer.cpp */; }; F5A1CB830F6B06CF00A96ABD /* HTTPDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F584E12D0F257C5100DB26A5 /* HTTPDirectory.cpp */; }; F5A1CB840F6B06CF00A96ABD /* GUIDialogKaraokeSongSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F54C51D00F1E783200D46E3C /* GUIDialogKaraokeSongSelector.cpp */; }; @@ -1988,8 +1972,6 @@ F5F245DB1112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F245D81112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp */; }; F5F245EE1112C9AB009126C6 /* FileUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F245EC1112C9AB009126C6 /* FileUtils.cpp */; }; F5F245EF1112C9AB009126C6 /* FileUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F245EC1112C9AB009126C6 /* FileUtils.cpp */; }; - F5F24E8611232488009126C6 /* DVDAudioEncoderFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F24E8311232488009126C6 /* DVDAudioEncoderFFmpeg.cpp */; }; - F5F24E8711232488009126C6 /* DVDAudioEncoderFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F24E8311232488009126C6 /* DVDAudioEncoderFFmpeg.cpp */; }; F5F2EF4B0E593E0D0092C37F /* DVDFileInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F2EF4A0E593E0D0092C37F /* DVDFileInfo.cpp */; }; F5F8E1DA0E427E8000A8E96F /* VGMCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F8E1D90E427E8000A8E96F /* VGMCodec.cpp */; }; F5F8E1E80E427F6700A8E96F /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5F8E1E60E427F6700A8E96F /* md5.cpp */; }; @@ -2080,7 +2062,6 @@ 18B7C3A612942132009E7A26 /* AdvancedSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdvancedSettings.cpp; sourceTree = "<group>"; }; 18B7C3A712942132009E7A26 /* AdvancedSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedSettings.h; sourceTree = "<group>"; }; 18B7C6F61294222D009E7A26 /* AnimatedGif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimatedGif.h; sourceTree = "<group>"; }; - 18B7C6F71294222D009E7A26 /* AudioContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContext.h; sourceTree = "<group>"; }; 18B7C6F81294222D009E7A26 /* D3DResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = D3DResource.h; sourceTree = "<group>"; }; 18B7C6F91294222D009E7A26 /* DDSImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDSImage.h; sourceTree = "<group>"; }; 18B7C6FA1294222D009E7A26 /* DirectXGraphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectXGraphics.h; sourceTree = "<group>"; }; @@ -2134,7 +2115,6 @@ 18B7C72C1294222D009E7A26 /* GUISettingsSliderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISettingsSliderControl.h; sourceTree = "<group>"; }; 18B7C72D1294222D009E7A26 /* GUIShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIShader.h; sourceTree = "<group>"; }; 18B7C72E1294222D009E7A26 /* GUISliderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISliderControl.h; sourceTree = "<group>"; }; - 18B7C72F1294222D009E7A26 /* GUISound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISound.h; sourceTree = "<group>"; }; 18B7C7301294222D009E7A26 /* GUISpinControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISpinControl.h; sourceTree = "<group>"; }; 18B7C7311294222D009E7A26 /* GUISpinControlEx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUISpinControlEx.h; sourceTree = "<group>"; }; 18B7C7321294222D009E7A26 /* GUIStandardWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIStandardWindow.h; sourceTree = "<group>"; }; @@ -2172,7 +2152,6 @@ 18B7C7521294222E009E7A26 /* XBTF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBTF.h; sourceTree = "<group>"; }; 18B7C7531294222E009E7A26 /* XBTFReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBTFReader.h; sourceTree = "<group>"; }; 18B7C7541294222E009E7A26 /* AnimatedGif.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimatedGif.cpp; sourceTree = "<group>"; }; - 18B7C7551294222E009E7A26 /* AudioContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioContext.cpp; sourceTree = "<group>"; }; 18B7C7561294222E009E7A26 /* D3DResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = D3DResource.cpp; sourceTree = "<group>"; }; 18B7C7571294222E009E7A26 /* DDSImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DDSImage.cpp; sourceTree = "<group>"; }; 18B7C7581294222E009E7A26 /* DirectXGraphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectXGraphics.cpp; sourceTree = "<group>"; }; @@ -2223,7 +2202,6 @@ 18B7C7861294222E009E7A26 /* GUISettingsSliderControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISettingsSliderControl.cpp; sourceTree = "<group>"; }; 18B7C7871294222E009E7A26 /* GUIShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIShader.cpp; sourceTree = "<group>"; }; 18B7C7881294222E009E7A26 /* GUISliderControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISliderControl.cpp; sourceTree = "<group>"; }; - 18B7C7891294222E009E7A26 /* GUISound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISound.cpp; sourceTree = "<group>"; }; 18B7C78A1294222E009E7A26 /* GUISpinControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISpinControl.cpp; sourceTree = "<group>"; }; 18B7C78B1294222E009E7A26 /* GUISpinControlEx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUISpinControlEx.cpp; sourceTree = "<group>"; }; 18B7C78C1294222E009E7A26 /* GUIStandardWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIStandardWindow.cpp; sourceTree = "<group>"; }; @@ -2369,8 +2347,6 @@ 18B7C9E7129447B9009E7A26 /* MathUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathUtils.h; sourceTree = "<group>"; }; 18C1D22B13033F6A00CFFE59 /* GLUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GLUtils.cpp; sourceTree = "<group>"; }; 18C1D22C13033F6A00CFFE59 /* GLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLUtils.h; sourceTree = "<group>"; }; - 18CCEAEC1112F5B800615FC6 /* PCMRemap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMRemap.cpp; sourceTree = "<group>"; }; - 18CCEAED1112F5B800615FC6 /* PCMRemap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMRemap.h; sourceTree = "<group>"; }; 18ECC96013CF178D00A9ED6C /* StreamUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamUtils.cpp; sourceTree = "<group>"; }; 18ECC96113CF178D00A9ED6C /* StreamUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamUtils.h; sourceTree = "<group>"; }; 32C631261423A90F00F18420 /* JpegIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JpegIO.cpp; sourceTree = "<group>"; }; @@ -2621,11 +2597,6 @@ 810C9FA80D67D1FB0095F5DD /* MythFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MythFile.h; sourceTree = "<group>"; }; 815EE6330E17F1DC009FBE3C /* DVDInputStreamRTMP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDInputStreamRTMP.cpp; sourceTree = "<group>"; }; 815EE6340E17F1DC009FBE3C /* DVDInputStreamRTMP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDInputStreamRTMP.h; sourceTree = "<group>"; }; - 83A72B8E0FBC8DB000171871 /* CoreAudioRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoreAudioRenderer.cpp; path = AudioRenderers/CoreAudioRenderer.cpp; sourceTree = "<group>"; }; - 83A72B8F0FBC8DB000171871 /* CoreAudioRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreAudioRenderer.h; path = AudioRenderers/CoreAudioRenderer.h; sourceTree = "<group>"; }; - 83A72B900FBC8DB000171871 /* IAudioRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IAudioRenderer.h; path = AudioRenderers/IAudioRenderer.h; sourceTree = "<group>"; }; - 83A72B920FBC8DFF00171871 /* CoreAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoreAudio.cpp; sourceTree = "<group>"; }; - 83A72B930FBC8DFF00171871 /* CoreAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudio.h; sourceTree = "<group>"; }; 83A72B950FBC8E3B00171871 /* LockFree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LockFree.cpp; sourceTree = "<group>"; }; 83A72B960FBC8E3B00171871 /* LockFree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LockFree.h; sourceTree = "<group>"; }; 83E0B2470F7C95FF0091643F /* Atomics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atomics.h; sourceTree = "<group>"; }; @@ -3732,8 +3703,6 @@ E38E1E680D25F9FD00618676 /* MusicInfoScraper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicInfoScraper.h; sourceTree = "<group>"; }; E38E1E6B0D25F9FD00618676 /* Network.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Network.cpp; sourceTree = "<group>"; }; E38E1E6C0D25F9FD00618676 /* Network.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Network.h; sourceTree = "<group>"; }; - E38E1E6D0D25F9FD00618676 /* PCMAmplifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMAmplifier.cpp; sourceTree = "<group>"; }; - E38E1E6E0D25F9FD00618676 /* PCMAmplifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PCMAmplifier.h; sourceTree = "<group>"; }; E38E1E6F0D25F9FD00618676 /* PerformanceSample.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceSample.cpp; sourceTree = "<group>"; }; E38E1E700D25F9FD00618676 /* PerformanceSample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceSample.h; sourceTree = "<group>"; }; E38E1E710D25F9FD00618676 /* PerformanceStats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceStats.cpp; sourceTree = "<group>"; }; @@ -3969,10 +3938,6 @@ F599CD2A108E65370010EC2A /* IoSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IoSupport.h; sourceTree = "<group>"; }; F599CD72108E6A7A0010EC2A /* DarwinStorageProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DarwinStorageProvider.h; sourceTree = "<group>"; }; F599CD73108E6A7A0010EC2A /* DarwinStorageProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DarwinStorageProvider.cpp; sourceTree = "<group>"; }; - F5A00B070EFDDDFC00CD59F3 /* AudioRendererFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AudioRendererFactory.cpp; path = xbmc/cores/AudioRenderers/AudioRendererFactory.cpp; sourceTree = SOURCE_ROOT; }; - F5A00B090EFDDE5F00CD59F3 /* AudioRendererFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioRendererFactory.h; path = xbmc/cores/AudioRenderers/AudioRendererFactory.h; sourceTree = SOURCE_ROOT; }; - F5A00B240EFDE44100CD59F3 /* NullDirectSound.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = NullDirectSound.cpp; path = xbmc/cores/AudioRenderers/NullDirectSound.cpp; sourceTree = SOURCE_ROOT; }; - F5A00B250EFDE44100CD59F3 /* NullDirectSound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NullDirectSound.h; path = xbmc/cores/AudioRenderers/NullDirectSound.h; sourceTree = SOURCE_ROOT; }; F5A1CBD20F6B06CF00A96ABD /* XBMC */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = XBMC; sourceTree = BUILT_PRODUCTS_DIR; }; F5A7A700112893E50059D6AA /* AnnouncementManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnnouncementManager.cpp; sourceTree = "<group>"; }; F5A7A701112893E50059D6AA /* AnnouncementManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnnouncementManager.h; sourceTree = "<group>"; }; @@ -4103,9 +4068,6 @@ F5F245D91112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DVDAudioCodecPassthroughFFmpeg.h; sourceTree = "<group>"; }; F5F245EC1112C9AB009126C6 /* FileUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileUtils.cpp; sourceTree = "<group>"; }; F5F245ED1112C9AB009126C6 /* FileUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUtils.h; sourceTree = "<group>"; }; - F5F24E8311232488009126C6 /* DVDAudioEncoderFFmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DVDAudioEncoderFFmpeg.cpp; path = Encoders/DVDAudioEncoderFFmpeg.cpp; sourceTree = "<group>"; }; - F5F24E8411232488009126C6 /* IDVDAudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IDVDAudioEncoder.h; path = Encoders/IDVDAudioEncoder.h; sourceTree = "<group>"; }; - F5F24E8511232488009126C6 /* DVDAudioEncoderFFmpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DVDAudioEncoderFFmpeg.h; path = Encoders/DVDAudioEncoderFFmpeg.h; sourceTree = "<group>"; }; F5F2EF490E593E0D0092C37F /* DVDFileInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DVDFileInfo.h; sourceTree = "<group>"; }; F5F2EF4A0E593E0D0092C37F /* DVDFileInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DVDFileInfo.cpp; sourceTree = "<group>"; }; F5F8E1D80E427E8000A8E96F /* VGMCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VGMCodec.h; sourceTree = "<group>"; }; @@ -4296,8 +4258,6 @@ children = ( 18B7C7541294222E009E7A26 /* AnimatedGif.cpp */, 18B7C6F61294222D009E7A26 /* AnimatedGif.h */, - 18B7C7551294222E009E7A26 /* AudioContext.cpp */, - 18B7C6F71294222D009E7A26 /* AudioContext.h */, 18B7C7561294222E009E7A26 /* D3DResource.cpp */, 18B7C6F81294222D009E7A26 /* D3DResource.h */, 18B7C7571294222E009E7A26 /* DDSImage.cpp */, @@ -4408,8 +4368,6 @@ 18B7C72D1294222D009E7A26 /* GUIShader.h */, 18B7C7881294222E009E7A26 /* GUISliderControl.cpp */, 18B7C72E1294222D009E7A26 /* GUISliderControl.h */, - 18B7C7891294222E009E7A26 /* GUISound.cpp */, - 18B7C72F1294222D009E7A26 /* GUISound.h */, 18B7C78A1294222E009E7A26 /* GUISpinControl.cpp */, 18B7C7301294222D009E7A26 /* GUISpinControl.h */, 18B7C78B1294222E009E7A26 /* GUISpinControlEx.cpp */, @@ -5347,8 +5305,6 @@ F57A1D1D1329B15300498CC7 /* AutoPool.mm */, F5EA05C30F73381A005C2EC5 /* CocoaInterface.h */, F5EA05C00F733812005C2EC5 /* CocoaInterface.mm */, - 83A72B920FBC8DFF00171871 /* CoreAudio.cpp */, - 83A72B930FBC8DFF00171871 /* CoreAudio.h */, F5B13C8B1334056B0045076D /* DarwinUtils.h */, F5B13C8C1334056B0045076D /* DarwinUtils.mm */, F5ACB5370FC3DF3D00AAA056 /* eprintf.cpp */, @@ -5504,7 +5460,6 @@ E38E149A0D25F9F900618676 /* cores */ = { isa = PBXGroup; children = ( - F5A00B060EFDDDB700CD59F3 /* AudioRenderers */, DFB65F6315373AE7006B8FF1 /* AudioEngine */, E38E149D0D25F9F900618676 /* DllLoader */, E38E14F80D25F9F900618676 /* dvdplayer */, @@ -5646,7 +5601,6 @@ E38E15010D25F9F900618676 /* Audio */ = { isa = PBXGroup; children = ( - F5F24E801123242B009126C6 /* Encoders */, E38E151D0D25F9F900618676 /* libmad */, E38E15050D25F9F900618676 /* DllLibMad.h */, E38E15060D25F9F900618676 /* DVDAudioCodec.h */, @@ -6942,10 +6896,6 @@ F5F8E1E70E427F6700A8E96F /* md5.h */, 188F75FC152217BC009870CE /* Mime.cpp */, 188F75FD152217BC009870CE /* Mime.h */, - E38E1E6D0D25F9FD00618676 /* PCMAmplifier.cpp */, - E38E1E6E0D25F9FD00618676 /* PCMAmplifier.h */, - 18CCEAEC1112F5B800615FC6 /* PCMRemap.cpp */, - 18CCEAED1112F5B800615FC6 /* PCMRemap.h */, E38E1E6F0D25F9FD00618676 /* PerformanceSample.cpp */, E38E1E700D25F9FD00618676 /* PerformanceSample.h */, E38E1E710D25F9FD00618676 /* PerformanceStats.cpp */, @@ -7045,20 +6995,6 @@ name = "internal libs"; sourceTree = "<group>"; }; - F5A00B060EFDDDB700CD59F3 /* AudioRenderers */ = { - isa = PBXGroup; - children = ( - F5A00B070EFDDDFC00CD59F3 /* AudioRendererFactory.cpp */, - F5A00B090EFDDE5F00CD59F3 /* AudioRendererFactory.h */, - 83A72B8E0FBC8DB000171871 /* CoreAudioRenderer.cpp */, - 83A72B8F0FBC8DB000171871 /* CoreAudioRenderer.h */, - 83A72B900FBC8DB000171871 /* IAudioRenderer.h */, - F5A00B240EFDE44100CD59F3 /* NullDirectSound.cpp */, - F5A00B250EFDE44100CD59F3 /* NullDirectSound.h */, - ); - name = AudioRenderers; - sourceTree = "<group>"; - }; F5AE406E13415D8C0004BD79 /* http-api */ = { isa = PBXGroup; children = ( @@ -7282,16 +7218,6 @@ name = playercorefactory; sourceTree = "<group>"; }; - F5F24E801123242B009126C6 /* Encoders */ = { - isa = PBXGroup; - children = ( - F5F24E8311232488009126C6 /* DVDAudioEncoderFFmpeg.cpp */, - F5F24E8511232488009126C6 /* DVDAudioEncoderFFmpeg.h */, - F5F24E8411232488009126C6 /* IDVDAudioEncoder.h */, - ); - name = Encoders; - sourceTree = "<group>"; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -7826,7 +7752,6 @@ E38E22E40D25F9FE00618676 /* MusicAlbumInfo.cpp in Sources */, E38E22E50D25F9FE00618676 /* MusicInfoScraper.cpp in Sources */, E38E22E70D25F9FE00618676 /* Network.cpp in Sources */, - E38E22E80D25F9FE00618676 /* PCMAmplifier.cpp in Sources */, E38E22E90D25F9FE00618676 /* PerformanceSample.cpp in Sources */, E38E22EA0D25F9FE00618676 /* PerformanceStats.cpp in Sources */, E38E22EB0D25F9FE00618676 /* RegExp.cpp in Sources */, @@ -7928,8 +7853,6 @@ F5FAB0710EFABAC800BAD4AE /* VTPFile.cpp in Sources */, F5FAB0760EFABE2C00BAD4AE /* VTPDirectory.cpp in Sources */, F5FAB07A0EFABE4A00BAD4AE /* VTPSession.cpp in Sources */, - F5A00B080EFDDDFC00CD59F3 /* AudioRendererFactory.cpp in Sources */, - F5A00B260EFDE44100CD59F3 /* NullDirectSound.cpp in Sources */, 7C5608C70F1754930056433A /* ExternalPlayer.cpp in Sources */, F584E12E0F257C5100DB26A5 /* HTTPDirectory.cpp in Sources */, F54C51D20F1E783200D46E3C /* GUIDialogKaraokeSongSelector.cpp in Sources */, @@ -7969,8 +7892,6 @@ F59876C00FBA351D008EF4FB /* VideoReferenceClock.cpp in Sources */, F5987B250FBB9682008EF4FB /* librefmscrobbler.cpp in Sources */, F5987B260FBB9682008EF4FB /* lastfmscrobbler.cpp in Sources */, - 83A72B910FBC8DB000171871 /* CoreAudioRenderer.cpp in Sources */, - 83A72B940FBC8DFF00171871 /* CoreAudio.cpp in Sources */, 83A72B970FBC8E3B00171871 /* LockFree.cpp in Sources */, F5987F050FBDF274008EF4FB /* DPMSSupport.cpp in Sources */, F5987FDB0FBE2DFD008EF4FB /* PAPlayer.cpp in Sources */, @@ -8076,8 +7997,6 @@ F5F244651110DC6B009126C6 /* FileOperationJob.cpp in Sources */, F5F245DA1112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */, F5F245EE1112C9AB009126C6 /* FileUtils.cpp in Sources */, - 18CCEAEE1112F5B800615FC6 /* PCMRemap.cpp in Sources */, - F5F24E8611232488009126C6 /* DVDAudioEncoderFFmpeg.cpp in Sources */, F5A7A702112893E50059D6AA /* AnnouncementManager.cpp in Sources */, F5A7A85B112908F00059D6AA /* WebServer.cpp in Sources */, 7C7B2B301134F36400713D6D /* mysqldataset.cpp in Sources */, @@ -8121,7 +8040,6 @@ 18B7C3A112942114009E7A26 /* GUIWindowSettingsScreenCalibration.cpp in Sources */, 18B7C3A812942132009E7A26 /* AdvancedSettings.cpp in Sources */, 18B7C7A91294222E009E7A26 /* AnimatedGif.cpp in Sources */, - 18B7C7AA1294222E009E7A26 /* AudioContext.cpp in Sources */, 18B7C7AB1294222E009E7A26 /* D3DResource.cpp in Sources */, 18B7C7AC1294222E009E7A26 /* DDSImage.cpp in Sources */, 18B7C7AD1294222E009E7A26 /* DirectXGraphics.cpp in Sources */, @@ -8172,7 +8090,6 @@ 18B7C7DB1294222E009E7A26 /* GUISettingsSliderControl.cpp in Sources */, 18B7C7DC1294222E009E7A26 /* GUIShader.cpp in Sources */, 18B7C7DD1294222E009E7A26 /* GUISliderControl.cpp in Sources */, - 18B7C7DE1294222E009E7A26 /* GUISound.cpp in Sources */, 18B7C7DF1294222E009E7A26 /* GUISpinControl.cpp in Sources */, 18B7C7E01294222E009E7A26 /* GUISpinControlEx.cpp in Sources */, 18B7C7E11294222E009E7A26 /* GUIStandardWindow.cpp in Sources */, @@ -8787,7 +8704,6 @@ F5A1CAD60F6B06CF00A96ABD /* MusicAlbumInfo.cpp in Sources */, F5A1CAD70F6B06CF00A96ABD /* MusicInfoScraper.cpp in Sources */, F5A1CAD90F6B06CF00A96ABD /* Network.cpp in Sources */, - F5A1CADA0F6B06CF00A96ABD /* PCMAmplifier.cpp in Sources */, F5A1CADB0F6B06CF00A96ABD /* PerformanceSample.cpp in Sources */, F5A1CADC0F6B06CF00A96ABD /* PerformanceStats.cpp in Sources */, F5A1CADD0F6B06CF00A96ABD /* RegExp.cpp in Sources */, @@ -8889,8 +8805,6 @@ F5A1CB7C0F6B06CF00A96ABD /* VTPFile.cpp in Sources */, F5A1CB7D0F6B06CF00A96ABD /* VTPDirectory.cpp in Sources */, F5A1CB7E0F6B06CF00A96ABD /* VTPSession.cpp in Sources */, - F5A1CB7F0F6B06CF00A96ABD /* AudioRendererFactory.cpp in Sources */, - F5A1CB800F6B06CF00A96ABD /* NullDirectSound.cpp in Sources */, F5A1CB810F6B06CF00A96ABD /* ExternalPlayer.cpp in Sources */, F5A1CB830F6B06CF00A96ABD /* HTTPDirectory.cpp in Sources */, F5A1CB840F6B06CF00A96ABD /* GUIDialogKaraokeSongSelector.cpp in Sources */, @@ -8932,8 +8846,6 @@ F5987B280FBB9682008EF4FB /* lastfmscrobbler.cpp in Sources */, F5987F060FBDF274008EF4FB /* DPMSSupport.cpp in Sources */, 43248C4E0FBE224000B88866 /* LockFree.cpp in Sources */, - 43248C510FBE224C00B88866 /* CoreAudio.cpp in Sources */, - 43248C520FBE224E00B88866 /* CoreAudioRenderer.cpp in Sources */, F5987FDC0FBE2DFD008EF4FB /* PAPlayer.cpp in Sources */, F548786E0FE060FF00E506FD /* DVDSubtitleParserMPL2.cpp in Sources */, F5487B4D0FE6F02700E506FD /* StreamDetails.cpp in Sources */, @@ -9035,8 +8947,6 @@ F5F244661110DC6B009126C6 /* FileOperationJob.cpp in Sources */, F5F245DB1112C6AC009126C6 /* DVDAudioCodecPassthroughFFmpeg.cpp in Sources */, F5F245EF1112C9AB009126C6 /* FileUtils.cpp in Sources */, - 18CCEAEF1112F5B800615FC6 /* PCMRemap.cpp in Sources */, - F5F24E8711232488009126C6 /* DVDAudioEncoderFFmpeg.cpp in Sources */, F5A7A703112893E50059D6AA /* AnnouncementManager.cpp in Sources */, F5A7A85C112908F00059D6AA /* WebServer.cpp in Sources */, 7C7B2B311134F36400713D6D /* mysqldataset.cpp in Sources */, @@ -9081,7 +8991,6 @@ 18B7C3A512942114009E7A26 /* GUIWindowSettingsScreenCalibration.cpp in Sources */, 18B7C3A912942132009E7A26 /* AdvancedSettings.cpp in Sources */, 18B7C7FE1294222E009E7A26 /* AnimatedGif.cpp in Sources */, - 18B7C7FF1294222E009E7A26 /* AudioContext.cpp in Sources */, 18B7C8001294222E009E7A26 /* D3DResource.cpp in Sources */, 18B7C8011294222E009E7A26 /* DDSImage.cpp in Sources */, 18B7C8021294222E009E7A26 /* DirectXGraphics.cpp in Sources */, @@ -9132,7 +9041,6 @@ 18B7C8301294222E009E7A26 /* GUISettingsSliderControl.cpp in Sources */, 18B7C8311294222E009E7A26 /* GUIShader.cpp in Sources */, 18B7C8321294222E009E7A26 /* GUISliderControl.cpp in Sources */, - 18B7C8331294222E009E7A26 /* GUISound.cpp in Sources */, 18B7C8341294222E009E7A26 /* GUISpinControl.cpp in Sources */, 18B7C8351294222E009E7A26 /* GUISpinControlEx.cpp in Sources */, 18B7C8361294222E009E7A26 /* GUIStandardWindow.cpp in Sources */, diff --git a/configure.in b/configure.in index 7eef73539c..85e5d1016b 100755 --- a/configure.in +++ b/configure.in @@ -1909,7 +1909,6 @@ OUTPUT_FILES="Makefile \ xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile \ xbmc/cores/dvdplayer/DVDDemuxers/Makefile \ xbmc/cores/dvdplayer/DVDSubtitles/Makefile \ - xbmc/cores/AudioRenderers/Makefile \ xbmc/cores/AudioEngine/Makefile \ xbmc/cores/paplayer/Makefile \ lib/timidity/Makefile \ diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj index 45bb069f9f..133f2cec20 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -462,7 +462,6 @@ <ClCompile Include="..\..\xbmc\GUIInfoManager.cpp" /> <ClCompile Include="..\..\xbmc\GUILargeTextureManager.cpp" /> <ClCompile Include="..\..\xbmc\guilib\AnimatedGif.cpp" /> - <ClCompile Include="..\..\xbmc\guilib\AudioContext.cpp" /> <ClCompile Include="..\..\xbmc\guilib\D3DResource.cpp" /> <ClCompile Include="..\..\xbmc\guilib\DDSImage.cpp" /> <ClCompile Include="..\..\xbmc\guilib\DirectXGraphics.cpp" /> @@ -522,7 +521,6 @@ <ClCompile Include="..\..\xbmc\guilib\GUISettingsSliderControl.cpp" /> <ClCompile Include="..\..\xbmc\guilib\GUIShader.cpp" /> <ClCompile Include="..\..\xbmc\guilib\GUISliderControl.cpp" /> - <ClCompile Include="..\..\xbmc\guilib\GUISound.cpp" /> <ClCompile Include="..\..\xbmc\guilib\GUISpinControl.cpp" /> <ClCompile Include="..\..\xbmc\guilib\GUISpinControlEx.cpp" /> <ClCompile Include="..\..\xbmc\guilib\GUIStandardWindow.cpp" /> @@ -901,7 +899,6 @@ <ClCompile Include="..\..\xbmc\threads\Event.cpp" /> <ClCompile Include="..\..\xbmc\threads\LockFree.cpp" /> <ClCompile Include="..\..\xbmc\threads\platform\Implementation.cpp" /> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\IAudioRenderer.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEAudioFormat.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AEFactory.h" /> <ClInclude Include="..\..\xbmc\cores\AudioEngine\AESinkFactory.h" /> @@ -1102,7 +1099,6 @@ <ClCompile Include="..\..\xbmc\utils\log.cpp" /> <ClCompile Include="..\..\xbmc\utils\md5.cpp" /> <ClCompile Include="..\..\xbmc\utils\Mime.cpp" /> - <ClCompile Include="..\..\xbmc\utils\PCMAmplifier.cpp" /> <ClCompile Include="..\..\xbmc\utils\PerformanceSample.cpp" /> <ClCompile Include="..\..\xbmc\utils\PerformanceStats.cpp" /> <ClCompile Include="..\..\xbmc\utils\POUtils.cpp" /> @@ -1195,7 +1191,6 @@ <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLPcm.cpp" /> <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPassthroughFFmpeg.cpp" /> <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.cpp" /> - <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\Encoders\DVDAudioEncoderFFmpeg.cpp" /> <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecCrystalHD.cpp" /> <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecFFmpeg.cpp" /> <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecLibMpeg2.cpp" /> @@ -1313,12 +1308,6 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.cpp" /> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\AudioRendererFactory.cpp" /> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\NullDirectSound.cpp" /> - <ClCompile Include="..\..\xbmc\utils\PCMRemap.cpp" /> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\PulseAudioDirectSound.cpp" /> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\Win32DirectSound.cpp" /> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\Win32WASAPI.cpp" /> <ClCompile Include="..\..\xbmc\cores\ExternalPlayer\ExternalPlayer.cpp" /> <ClCompile Include="..\..\xbmc\cores\playercorefactory\PlayerCoreFactory.cpp" /> <ClCompile Include="..\..\xbmc\cores\playercorefactory\PlayerSelectionRule.cpp" /> @@ -1504,7 +1493,6 @@ <ClInclude Include="..\..\xbmc\GUIInfoManager.h" /> <ClInclude Include="..\..\xbmc\GUILargeTextureManager.h" /> <ClInclude Include="..\..\xbmc\guilib\AnimatedGif.h" /> - <ClInclude Include="..\..\xbmc\guilib\AudioContext.h" /> <ClInclude Include="..\..\xbmc\guilib\D3DResource.h" /> <ClInclude Include="..\..\xbmc\guilib\DDSImage.h" /> <ClInclude Include="..\..\xbmc\guilib\DirectXGraphics.h" /> @@ -1568,7 +1556,6 @@ <ClInclude Include="..\..\xbmc\guilib\GUISettingsSliderControl.h" /> <ClInclude Include="..\..\xbmc\guilib\GUIShader.h" /> <ClInclude Include="..\..\xbmc\guilib\GUISliderControl.h" /> - <ClInclude Include="..\..\xbmc\guilib\GUISound.h" /> <ClInclude Include="..\..\xbmc\guilib\GUISpinControl.h" /> <ClInclude Include="..\..\xbmc\guilib\GUISpinControlEx.h" /> <ClInclude Include="..\..\xbmc\guilib\GUIStandardWindow.h" /> @@ -1906,7 +1893,6 @@ <ClInclude Include="..\..\xbmc\utils\MathUtils.h" /> <ClInclude Include="..\..\xbmc\utils\md5.h" /> <ClInclude Include="..\..\xbmc\utils\Mime.h" /> - <ClInclude Include="..\..\xbmc\utils\PCMAmplifier.h" /> <ClInclude Include="..\..\xbmc\utils\PerformanceSample.h" /> <ClInclude Include="..\..\xbmc\utils\PerformanceStats.h" /> <ClInclude Include="..\..\xbmc\utils\POUtils.h" /> @@ -2011,8 +1997,6 @@ <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecLPcm.h" /> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPassthroughFFmpeg.h" /> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.h" /> - <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\Encoders\DVDAudioEncoderFFmpeg.h" /> - <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\Encoders\IDVDAudioEncoder.h" /> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DllLibMpeg2.h" /> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodec.h" /> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecCrystalHD.h" /> @@ -2147,12 +2131,6 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild> </ClInclude> <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.h" /> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\AudioRendererFactory.h" /> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\NullDirectSound.h" /> - <ClInclude Include="..\..\xbmc\utils\PCMRemap.h" /> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\PulseAudioDirectSound.h" /> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\Win32DirectSound.h" /> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\Win32WASAPI.h" /> <ClInclude Include="..\..\xbmc\cores\ExternalPlayer\ExternalPlayer.h" /> <ClInclude Include="..\..\xbmc\cores\playercorefactory\PlayerCoreConfig.h" /> <ClInclude Include="..\..\xbmc\cores\playercorefactory\PlayerCoreFactory.h" /> diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters index 3a61afa7f9..0613aa9680 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters @@ -16,9 +16,6 @@ <Filter Include="cores\dvdplayer\DVDCodecs\Audio"> <UniqueIdentifier>{5bee29f5-b152-4416-9413-0bed2a669575}</UniqueIdentifier> </Filter> - <Filter Include="cores\dvdplayer\DVDCodecs\Audio\Encoders"> - <UniqueIdentifier>{950294bc-2e98-414e-8bf4-57c43fb73b31}</UniqueIdentifier> - </Filter> <Filter Include="cores\dvdplayer\DVDCodecs\Video"> <UniqueIdentifier>{09e9057e-7017-4f3d-b5d3-2f5e9a23a53c}</UniqueIdentifier> </Filter> @@ -375,9 +372,6 @@ <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.cpp"> <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\Encoders\DVDAudioEncoderFFmpeg.cpp"> - <Filter>cores\dvdplayer\DVDCodecs\Audio\Encoders</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecCrystalHD.cpp"> <Filter>cores\dvdplayer\DVDCodecs\Video</Filter> </ClCompile> @@ -636,24 +630,6 @@ <ClCompile Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.cpp"> <Filter>cores\VideoRenderers\Shaders</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\AudioRendererFactory.cpp"> - <Filter>cores\AudioRenderers</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\NullDirectSound.cpp"> - <Filter>cores\AudioRenderers</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\utils\PCMRemap.cpp"> - <Filter>cores\AudioRenderers</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\PulseAudioDirectSound.cpp"> - <Filter>cores\AudioRenderers</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\Win32DirectSound.cpp"> - <Filter>cores\AudioRenderers</Filter> - </ClCompile> - <ClCompile Include="..\..\xbmc\cores\AudioRenderers\Win32WASAPI.cpp"> - <Filter>cores\AudioRenderers</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\cores\ExternalPlayer\ExternalPlayer.cpp"> <Filter>cores\ExternalPlayer</Filter> </ClCompile> @@ -1015,9 +991,6 @@ <ClCompile Include="..\..\xbmc\guilib\AnimatedGif.cpp"> <Filter>guilib</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\guilib\AudioContext.cpp"> - <Filter>guilib</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\guilib\D3DResource.cpp"> <Filter>guilib</Filter> </ClCompile> @@ -1153,9 +1126,6 @@ <ClCompile Include="..\..\xbmc\guilib\GUISliderControl.cpp"> <Filter>guilib</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\guilib\GUISound.cpp"> - <Filter>guilib</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\guilib\GUISpinControl.cpp"> <Filter>guilib</Filter> </ClCompile> @@ -1681,9 +1651,6 @@ <ClCompile Include="..\..\xbmc\utils\md5.cpp"> <Filter>utils</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\utils\PCMAmplifier.cpp"> - <Filter>utils</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\utils\PerformanceSample.cpp"> <Filter>utils</Filter> </ClCompile> @@ -1822,9 +1789,6 @@ <ClCompile Include="..\..\xbmc\windowing\windows\WinSystemWin32DX.cpp"> <Filter>windowing\windows</Filter> </ClCompile> - <ClCompile Include="..\..\xbmc\windowing\windows\WinSystemWin32GL.cpp"> - <Filter>windowing\windows</Filter> - </ClCompile> <ClCompile Include="..\..\xbmc\addons\GUIViewStateAddonBrowser.cpp"> <Filter>addons</Filter> </ClCompile> @@ -2830,12 +2794,6 @@ <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\DVDAudioCodecPcm.h"> <Filter>cores\dvdplayer\DVDCodecs\Audio</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\Encoders\DVDAudioEncoderFFmpeg.h"> - <Filter>cores\dvdplayer\DVDCodecs\Audio\Encoders</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Audio\Encoders\IDVDAudioEncoder.h"> - <Filter>cores\dvdplayer\DVDCodecs\Audio\Encoders</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DllLibMpeg2.h"> <Filter>cores\dvdplayer\DVDCodecs\Video</Filter> </ClInclude> @@ -3205,24 +3163,6 @@ <ClInclude Include="..\..\xbmc\cores\VideoRenderers\VideoShaders\YUV2RGBShader.h"> <Filter>cores\VideoRenderers\Shaders</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\AudioRendererFactory.h"> - <Filter>cores\AudioRenderers</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\NullDirectSound.h"> - <Filter>cores\AudioRenderers</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\utils\PCMRemap.h"> - <Filter>cores\AudioRenderers</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\PulseAudioDirectSound.h"> - <Filter>cores\AudioRenderers</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\Win32DirectSound.h"> - <Filter>cores\AudioRenderers</Filter> - </ClInclude> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\Win32WASAPI.h"> - <Filter>cores\AudioRenderers</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\cores\ExternalPlayer\ExternalPlayer.h"> <Filter>cores\ExternalPlayer</Filter> </ClInclude> @@ -3612,9 +3552,6 @@ <ClInclude Include="..\..\xbmc\guilib\AnimatedGif.h"> <Filter>guilib</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\guilib\AudioContext.h"> - <Filter>guilib</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\guilib\D3DResource.h"> <Filter>guilib</Filter> </ClInclude> @@ -3759,9 +3696,6 @@ <ClInclude Include="..\..\xbmc\guilib\GUISliderControl.h"> <Filter>guilib</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\guilib\GUISound.h"> - <Filter>guilib</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\guilib\GUISpinControl.h"> <Filter>guilib</Filter> </ClInclude> @@ -4368,9 +4302,6 @@ <ClInclude Include="..\..\xbmc\utils\md5.h"> <Filter>utils</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\utils\PCMAmplifier.h"> - <Filter>utils</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\utils\PerformanceSample.h"> <Filter>utils</Filter> </ClInclude> @@ -5327,9 +5258,6 @@ <ClInclude Include="..\..\xbmc\utils\POUtils.h"> <Filter>utils</Filter> </ClInclude> - <ClInclude Include="..\..\xbmc\cores\AudioRenderers\IAudioRenderer.h"> - <Filter>cores\AudioRenderers</Filter> - </ClInclude> <ClInclude Include="..\..\xbmc\interfaces\python\xbmcmodule\pythreadstate.h"> <Filter>interfaces\python\xbmcmodule</Filter> </ClInclude> diff --git a/xbmc/cores/AudioRenderers/ALSADirectSound.cpp b/xbmc/cores/AudioRenderers/ALSADirectSound.cpp deleted file mode 100644 index 3c891cff67..0000000000 --- a/xbmc/cores/AudioRenderers/ALSADirectSound.cpp +++ /dev/null @@ -1,699 +0,0 @@ -/* -* XBMC Media Center -* Copyright (c) 2002 d7o3g4q and RUNTiME -* Portions Copyright (c) by the authors of ffmpeg and xvid -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "ALSADirectSound.h" -#include "guilib/AudioContext.h" -#include "filesystem/SpecialProtocol.h" -#include "settings/GUISettings.h" -#include "settings/Settings.h" -#include "utils/log.h" -#include "limits.h" -#include "guilib/LocalizeStrings.h" - -#define CHECK_ALSA(l,s,e) if ((e)<0) CLog::Log(l,"%s - %s, alsa error: %d - %s",__FUNCTION__,s,e,snd_strerror(e)); -#define CHECK_ALSA_RETURN(l,s,e) CHECK_ALSA((l),(s),(e)); if ((e)<0) return false; - -using namespace std; - -static CStdString QuoteDevice(const CStdString& device) -{ - CStdString result(device); - result.Replace("'", "\\'"); - return "'" + result + "'"; -} - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// -//*********************************************************************************************** -CALSADirectSound::CALSADirectSound() -{ - m_pPlayHandle = NULL; - m_bIsAllocated = false; -} - -bool CALSADirectSound::Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, EEncoded encoded) -{ - enum PCMChannels *outLayout; - - static enum PCMChannels ALSAChannelMap[8] = - { - PCM_FRONT_LEFT , PCM_FRONT_RIGHT , - PCM_BACK_LEFT , PCM_BACK_RIGHT , - PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, - PCM_SIDE_LEFT , PCM_SIDE_RIGHT - }; - - CStdString deviceuse; - - /* setup the channel mapping */ - m_uiDataChannels = iChannels; - m_remap.Reset(); - - if (encoded == ENCODED_NONE && channelMap) - { - /* set the input format, and get the channel layout so we know what we need to open */ - outLayout = m_remap.SetInputFormat (iChannels, channelMap, uiBitsPerSample / 8, uiSamplesPerSec); - unsigned int outChannels = 0; - unsigned int ch = 0, map; - while(outLayout[ch] != PCM_INVALID) - { - for(map = 0; map < 8; ++map) - if (outLayout[ch] == ALSAChannelMap[map]) - { - if (map > outChannels) - outChannels = map; - break; - } - ++ch; - } - - m_remap.SetOutputFormat(++outChannels, ALSAChannelMap); - if (m_remap.CanRemap()) - { - iChannels = outChannels; - if (m_uiDataChannels != (unsigned int)iChannels) - CLog::Log(LOGDEBUG, "CALSADirectSound::CALSADirectSound - Requested channels changed from %i to %i", m_uiDataChannels, iChannels); - } - } - - bool bAudioOnAllSpeakers(false); - g_audioContext.SetupSpeakerConfig(iChannels, bAudioOnAllSpeakers, bIsMusic); - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE); - - m_pPlayHandle = NULL; - m_bPause = false; - m_bCanPause = false; - m_bIsAllocated = false; - m_uiChannels = iChannels; - m_uiSamplesPerSec = uiSamplesPerSec; - m_uiBitsPerSample = uiBitsPerSample; - m_bPassthrough = encoded != ENCODED_NONE; - m_drc = 0; - - m_nCurrentVolume = g_settings.m_nVolumeLevel; - if (!m_bPassthrough) - m_amp.SetVolume(m_nCurrentVolume); - - m_dwFrameCount = 512; - m_dwNumPackets = 16; - m_uiBufferSize = 0; - - snd_pcm_hw_params_t *hw_params=NULL; - snd_pcm_sw_params_t *sw_params=NULL; - - /* Open the device */ - int nErr; - - /* if this is first access to audio, global sound config might not be loaded */ - if(!snd_config) - snd_config_update(); - - snd_config_t *config = snd_config; - deviceuse = device; - - nErr = snd_config_copy(&config, snd_config); - CHECK_ALSA_RETURN(LOGERROR,"config_copy",nErr); - - if(m_bPassthrough) - { - /* http://www.alsa-project.org/alsa-doc/alsa-lib/group___digital___audio___interface.html */ - deviceuse += (deviceuse.Find(':') >= 0) ? ',' : ':'; - deviceuse += "AES0=0x6"; - deviceuse += ",AES1=0x82"; - deviceuse += ",AES2=0x0"; - if(uiSamplesPerSec == 192000) - deviceuse += ",AES3=0xe"; - else if(uiSamplesPerSec == 176400) - deviceuse += ",AES3=0xc"; - else if(uiSamplesPerSec == 96000) - deviceuse += ",AES3=0xa"; - else if(uiSamplesPerSec == 88200) - deviceuse += ",AES3=0x8"; - else if(uiSamplesPerSec == 48000) - deviceuse += ",AES3=0x2"; - else if(uiSamplesPerSec == 44100) - deviceuse += ",AES3=0x0"; - else if(uiSamplesPerSec == 32000) - deviceuse += ",AES3=0x3"; - else - deviceuse += ",AES3=0x1"; - } - else - { - if((deviceuse + ":").Left(5) == "hdmi:" - || (deviceuse + ":").Left(7) == "iec958:" - || (deviceuse + ":").Left(6) == "spdif:") - deviceuse = "plug:" + QuoteDevice(deviceuse); - - if(deviceuse == "default") - switch(iChannels) - { - case 8: deviceuse = "plug:surround71"; break; - case 6: deviceuse = "plug:surround51"; break; - case 5: deviceuse = "plug:surround50"; break; - case 4: deviceuse = "plug:surround40"; break; - } - - if(deviceuse != device) - { - snd_input_t* input; - nErr = snd_input_stdio_open(&input, CSpecialProtocol::TranslatePath("special://xbmc/system/asound.conf").c_str(), "r"); - if(nErr >= 0) - { - nErr = snd_config_load(config, input); - CHECK_ALSA_RETURN(LOGERROR,"config_load", nErr); - - snd_input_close(input); - CHECK_ALSA_RETURN(LOGERROR,"input_close", nErr); - } - else - { - CLog::Log(LOGWARNING, "%s - Unable to load alsa configuration \"%s\" for device \"%s\" - %s", __FUNCTION__, "special://xbmc/system/asound.conf", deviceuse.c_str(), snd_strerror(nErr)); - deviceuse = device; - } - } - } - - CLog::Log(LOGDEBUG, "%s - using alsa device %s", __FUNCTION__, deviceuse.c_str()); - - nErr = snd_pcm_open_lconf(&m_pPlayHandle, deviceuse.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, config); - - if(nErr == -EBUSY) - { - // this could happen if we are in the middle of a resolution switch sometimes - CLog::Log(LOGERROR, "%s - device %s busy retrying...", __FUNCTION__, deviceuse.c_str()); - if(m_pPlayHandle) - { - snd_pcm_close(m_pPlayHandle); - m_pPlayHandle = NULL; - } - Sleep(200); - nErr = snd_pcm_open_lconf(&m_pPlayHandle, deviceuse.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, config); - } - - if(nErr < 0 && deviceuse != device) - { - CLog::Log(LOGERROR, "%s - failed to open custom device %s (error:%s), retry with default %s", __FUNCTION__, deviceuse.c_str(), snd_strerror(nErr), device.c_str()); - if(m_pPlayHandle) - { - snd_pcm_close(m_pPlayHandle); - m_pPlayHandle = NULL; - } - nErr = snd_pcm_open_lconf(&m_pPlayHandle, device.c_str(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, config); - - } - - CHECK_ALSA_RETURN(LOGERROR,"pcm_open_lconf",nErr); - - snd_config_delete(config); - - /* Allocate Hardware Parameters structures and fills it with config space for PCM */ - snd_pcm_hw_params_malloc(&hw_params); - - /* Allocate Software Parameters structures and fills it with config space for PCM */ - snd_pcm_sw_params_malloc(&sw_params); - - nErr = snd_pcm_hw_params_any(m_pPlayHandle, hw_params); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_any",nErr); - - nErr = snd_pcm_hw_params_set_access(m_pPlayHandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_access",nErr); - - // always use 16 bit samples - nErr = snd_pcm_hw_params_set_format(m_pPlayHandle, hw_params, SND_PCM_FORMAT_S16); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_format",nErr); - - nErr = snd_pcm_hw_params_set_rate_near(m_pPlayHandle, hw_params, &m_uiSamplesPerSec, NULL); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_rate",nErr); - - nErr = snd_pcm_hw_params_set_channels(m_pPlayHandle, hw_params, iChannels); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_channels",nErr); - - nErr = snd_pcm_hw_params_set_period_size_near(m_pPlayHandle, hw_params, &m_dwFrameCount, NULL); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_period_size",nErr); - - nErr = snd_pcm_hw_params_set_periods_near(m_pPlayHandle, hw_params, &m_dwNumPackets, NULL); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_set_periods",nErr); - - nErr = snd_pcm_hw_params_get_buffer_size(hw_params, &m_uiBufferSize); - CHECK_ALSA_RETURN(LOGERROR,"hw_params_get_buffer_size",nErr); - - /* Assign them to the playback handle and free the parameters structure */ - nErr = snd_pcm_hw_params(m_pPlayHandle, hw_params); - CHECK_ALSA_RETURN(LOGERROR,"snd_pcm_hw_params",nErr); - - nErr = snd_pcm_sw_params_current(m_pPlayHandle, sw_params); - CHECK_ALSA_RETURN(LOGERROR,"sw_params_current",nErr); - - nErr = snd_pcm_sw_params_set_start_threshold(m_pPlayHandle, sw_params, INT_MAX); - CHECK_ALSA_RETURN(LOGERROR,"sw_params_set_start_threshold",nErr); - - snd_pcm_uframes_t boundary; - nErr = snd_pcm_sw_params_get_boundary( sw_params, &boundary ); - CHECK_ALSA_RETURN(LOGERROR,"snd_pcm_sw_params_get_boundary",nErr); - - nErr = snd_pcm_sw_params_set_silence_threshold(m_pPlayHandle, sw_params, 0 ); - CHECK_ALSA_RETURN(LOGERROR,"snd_pcm_sw_params_set_silence_threshold",nErr); - - nErr = snd_pcm_sw_params_set_silence_size( m_pPlayHandle, sw_params, boundary ); - CHECK_ALSA_RETURN(LOGERROR,"snd_pcm_sw_params_set_silence_size",nErr); - - nErr = snd_pcm_sw_params(m_pPlayHandle, sw_params); - CHECK_ALSA_RETURN(LOGERROR,"snd_pcm_sw_params",nErr); - - m_bCanPause = !!snd_pcm_hw_params_can_pause(hw_params); - - snd_pcm_hw_params_free (hw_params); - snd_pcm_sw_params_free (sw_params); - - - CLog::Log(LOGDEBUG, "CALSADirectSound::Initialize - frame count:%u, packet count:%u, buffer size:%u" - , (unsigned int)m_dwFrameCount - , m_dwNumPackets - , (unsigned int)m_uiBufferSize); - - if(m_uiSamplesPerSec != uiSamplesPerSec) - CLog::Log(LOGWARNING, "CALSADirectSound::CALSADirectSound - requested samplerate (%d) not supported by hardware, using %d instead", uiSamplesPerSec, m_uiSamplesPerSec); - - - nErr = snd_pcm_prepare (m_pPlayHandle); - CHECK_ALSA(LOGERROR,"snd_pcm_prepare",nErr); - - m_bIsAllocated = true; - return true; -} - -//*********************************************************************************************** -CALSADirectSound::~CALSADirectSound() -{ - Deinitialize(); -} - - -//*********************************************************************************************** -bool CALSADirectSound::Deinitialize() -{ - m_bIsAllocated = false; - if (m_pPlayHandle) - { - snd_pcm_drop(m_pPlayHandle); - snd_pcm_close(m_pPlayHandle); - } - - m_pPlayHandle=NULL; - g_audioContext.SetActiveDevice(CAudioContext::DEFAULT_DEVICE); - return true; -} - -void CALSADirectSound::Flush() -{ - if (!m_bIsAllocated) - return; - - int nErr = snd_pcm_drop(m_pPlayHandle); - CHECK_ALSA(LOGERROR,"flush-drop",nErr); - nErr = snd_pcm_prepare(m_pPlayHandle); - CHECK_ALSA(LOGERROR,"flush-prepare",nErr); -} - -//*********************************************************************************************** -bool CALSADirectSound::Pause() -{ - if (!m_bIsAllocated) - return -1; - - if (m_bPause) return true; - m_bPause = true; - - snd_pcm_state_t state = snd_pcm_state(m_pPlayHandle); - - if(state != SND_PCM_STATE_RUNNING) - { - if(state != SND_PCM_STATE_PAUSED - && state != SND_PCM_STATE_PREPARED) - { - CLog::Log(LOGWARNING, "CALSADirectSound::Pause - device in weird state %d", (int)state); - Flush(); - } - return true; - } - - if(m_bCanPause) - { - int nErr = snd_pcm_pause(m_pPlayHandle,1); // this is not supported on all devices. - CHECK_ALSA(LOGERROR,"pcm_pause",nErr); - if(nErr<0) - m_bCanPause = false; - } - - if(!m_bCanPause) - { - snd_pcm_sframes_t avail = snd_pcm_avail_update(m_pPlayHandle); - snd_pcm_sframes_t delay = 0; - if(avail >= 0) - delay = (snd_pcm_sframes_t)m_uiBufferSize - avail; - - CLog::Log(LOGWARNING, "CALSADirectSound::CALSADirectSound - device is not able to pause playback, will flush and prefix with %d frames", (int)delay); - Flush(); - - if(delay > 0) - { - void* silence = calloc(snd_pcm_frames_to_bytes(m_pPlayHandle, delay), 1); - int nErr = snd_pcm_writei(m_pPlayHandle, silence, delay); - CHECK_ALSA(LOGERROR,"snd_pcm_writei", nErr); - free(silence); - } - } - - return true; -} - -//*********************************************************************************************** -bool CALSADirectSound::Resume() -{ - if (!m_bIsAllocated) - return -1; - - snd_pcm_state_t state = snd_pcm_state(m_pPlayHandle); - if(state == SND_PCM_STATE_PAUSED) - snd_pcm_pause(m_pPlayHandle,0); - - else if(state == SND_PCM_STATE_PREPARED) - { - snd_pcm_sframes_t avail = snd_pcm_avail_update(m_pPlayHandle); - if(avail >= 0 && avail < (snd_pcm_sframes_t)m_uiBufferSize) - snd_pcm_start(m_pPlayHandle); - } - else if(state == SND_PCM_STATE_RUNNING) - {} - else - { - CLog::Log(LOGWARNING, "CALSADirectSound::Resume - unexpected device state %d flushing", state); - Flush(); - snd_pcm_start(m_pPlayHandle); - } - - m_bPause = false; - - return true; -} - -//*********************************************************************************************** -bool CALSADirectSound::Stop() -{ - if (!m_bIsAllocated) - return -1; - - Flush(); - - m_bPause = false; - - return true; -} - -//*********************************************************************************************** -long CALSADirectSound::GetCurrentVolume() const -{ - return m_nCurrentVolume; -} - -//*********************************************************************************************** -void CALSADirectSound::Mute(bool bMute) -{ - if (!m_bIsAllocated) - return; - - if (bMute) - SetCurrentVolume(VOLUME_MINIMUM); - else - SetCurrentVolume(m_nCurrentVolume); - -} - -//*********************************************************************************************** -bool CALSADirectSound::SetCurrentVolume(long nVolume) -{ - if (!m_bIsAllocated) return -1; - m_nCurrentVolume = nVolume; - m_amp.SetVolume(nVolume); - return true; -} - - -//*********************************************************************************************** -unsigned int CALSADirectSound::GetSpaceFrames() -{ - if (!m_bIsAllocated) return 0; - - int nSpace = snd_pcm_avail_update(m_pPlayHandle); - if (nSpace == 0) - { - snd_pcm_state_t state = snd_pcm_state(m_pPlayHandle); - if(state != SND_PCM_STATE_RUNNING && state != SND_PCM_STATE_PREPARED && !m_bPause) - { - CLog::Log(LOGWARNING,"CALSADirectSound::GetSpace - buffer underun (%d)", state); - Flush(); - return m_uiBufferSize; - } - } - if (nSpace < 0) - { - CLog::Log(LOGWARNING,"CALSADirectSound::GetSpace - get space failed. err: %d (%s)", nSpace, snd_strerror(nSpace)); - Flush(); - return m_uiBufferSize; - } - return nSpace; -} - -unsigned int CALSADirectSound::GetSpace() -{ - return GetSpaceFrames() * m_uiDataChannels * m_uiBitsPerSample / 8; -} - -//*********************************************************************************************** -unsigned int CALSADirectSound::AddPackets(const void* data, unsigned int len) -{ - if (!m_bIsAllocated) - { - CLog::Log(LOGERROR,"CALSADirectSound::AddPackets - sanity failed. no valid play handle!"); - return len; - } - // if we are paused we don't accept any data as pause doesn't always - // work, and then playback would start again - if(m_bPause) - return 0; - - int framesToWrite, bytesToWrite; - - framesToWrite = std::min(GetSpaceFrames(), len / ( m_uiDataChannels * m_uiBitsPerSample / 8 ) ); - framesToWrite /= m_dwFrameCount; - framesToWrite *= m_dwFrameCount; - bytesToWrite = snd_pcm_frames_to_bytes(m_pPlayHandle, framesToWrite); - - if(framesToWrite == 0) - { - // if we haven't started playback, do so now - if(snd_pcm_state(m_pPlayHandle) == SND_PCM_STATE_PREPARED && !m_bPause) - snd_pcm_start(m_pPlayHandle); - return 0; - } - - int writeResult; - if (m_bPassthrough && m_nCurrentVolume == VOLUME_MINIMUM) - { - char dummy[bytesToWrite]; - memset(dummy,0,sizeof(dummy)); - writeResult = snd_pcm_writei(m_pPlayHandle, dummy, framesToWrite); - } - else - { - if (m_remap.CanRemap()) - { - /* remap the data to the correct channels */ - uint8_t outData[bytesToWrite]; - m_remap.Remap((void *)data, outData, framesToWrite, m_drc); - m_amp.DeAmplify((short *)outData, bytesToWrite / 2); - writeResult = snd_pcm_writei(m_pPlayHandle, outData, framesToWrite); - } - else - { - if (!m_bPassthrough) - m_amp.DeAmplify((short *)data, framesToWrite * m_uiDataChannels); - - writeResult = snd_pcm_writei(m_pPlayHandle, data, framesToWrite); - } - } - if ( writeResult == -EPIPE ) - { - CLog::Log(LOGDEBUG, "CALSADirectSound::AddPackets - buffer underun (tried to write %d frames)", - framesToWrite); - Flush(); - return 0; - } - else if (writeResult != framesToWrite) - { - CLog::Log(LOGERROR, "CALSADirectSound::AddPackets - failed to write %d frames. " - "bad write (err: %d) - %s", - framesToWrite, writeResult, snd_strerror(writeResult)); - Flush(); - } - - if (writeResult > 0) - { - if(snd_pcm_state(m_pPlayHandle) == SND_PCM_STATE_PREPARED && !m_bPause && GetSpaceFrames() <= m_dwFrameCount) - snd_pcm_start(m_pPlayHandle); - - return writeResult * m_uiBitsPerSample * m_uiDataChannels / 8; - } - - return 0; -} - -//*********************************************************************************************** -float CALSADirectSound::GetDelay() -{ - if (!m_bIsAllocated) - return 0.0; - - snd_pcm_sframes_t frames = 0; - - int nErr = snd_pcm_delay(m_pPlayHandle, &frames); - CHECK_ALSA(LOGERROR,"snd_pcm_delay",nErr); - if (nErr < 0) - { - frames = 0; - Flush(); - } - - if (frames < 0) - { -#if SND_LIB_VERSION >= 0x000901 /* snd_pcm_forward() exists since 0.9.0rc8 */ - snd_pcm_forward(m_pPlayHandle, -frames); -#endif - frames = 0; - } - - return (double)frames / m_uiSamplesPerSec; -} - -float CALSADirectSound::GetCacheTime() -{ - return (float)(m_uiBufferSize - GetSpaceFrames()) / m_uiSamplesPerSec; -} - -float CALSADirectSound::GetCacheTotal() -{ - return (float)m_uiBufferSize / m_uiSamplesPerSec; -} - -//*********************************************************************************************** -unsigned int CALSADirectSound::GetChunkLen() -{ - return m_dwFrameCount * m_uiDataChannels * m_uiBitsPerSample / 8; -} -//*********************************************************************************************** -int CALSADirectSound::SetPlaySpeed(int iSpeed) -{ - return 0; -} - -void CALSADirectSound::RegisterAudioCallback(IAudioCallback *pCallback) -{ - m_pCallback = pCallback; -} - -void CALSADirectSound::UnRegisterAudioCallback() -{ - m_pCallback = NULL; -} - -void CALSADirectSound::WaitCompletion() -{ - if (!m_bIsAllocated || m_bPause) - return; - - snd_pcm_wait(m_pPlayHandle, -1); -} - -void CALSADirectSound::SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) -{ - return ; -} - -void CALSADirectSound::EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough) -{ - if (!passthrough) - { - vAudioSinks.push_back(AudioSink(g_localizeStrings.Get(409) + " (ALSA)", "alsa:default")); - vAudioSinks.push_back(AudioSink("iec958 (ALSA)" , "alsa:plug:iec958")); - vAudioSinks.push_back(AudioSink("hdmi (ALSA)" , "alsa:plug:hdmi")); - } - else - { - vAudioSinks.push_back(AudioSink("iec958 (ALSA)" , "alsa:iec958")); - vAudioSinks.push_back(AudioSink("hdmi (ALSA)" , "alsa:hdmi")); - } - - snd_ctl_t *handle; - snd_ctl_card_info_t *info; - snd_ctl_card_info_alloca( &info ); - CStdString strHwName; - int n_cards = -1; - - while ( snd_card_next( &n_cards ) == 0 && n_cards >= 0 ) - { - strHwName.Format("hw:%d", n_cards); - if ( snd_ctl_open( &handle, strHwName.c_str(), 0 ) == 0 ) - { - if ( snd_ctl_card_info( handle, info ) == 0 ) - { - CStdString strReadableCardName = snd_ctl_card_info_get_name( info ); - CStdString strCardName = snd_ctl_card_info_get_id( info ); - - int dev = -1; - while( snd_ctl_pcm_next_device( handle, &dev ) == 0 && dev >= 0 ) - { - if (!passthrough) - GenSoundLabel(vAudioSinks, "default", strCardName, dev, strReadableCardName); - GenSoundLabel(vAudioSinks, "iec958", strCardName, dev, strReadableCardName); - GenSoundLabel(vAudioSinks, "hdmi", strCardName, dev, strReadableCardName); - } - } - else - CLog::Log(LOGERROR,"((ALSAENUM))control hardware info (%i): failed.\n", n_cards ); - snd_ctl_close( handle ); - } - else - CLog::Log(LOGERROR,"((ALSAENUM))control open (%i) failed.\n", n_cards ); - } -} - -void CALSADirectSound::GenSoundLabel(AudioSinkList& vAudioSinks, CStdString sink, CStdString card, int dev, CStdString readableCard) -{ - CStdString deviceString; - deviceString.Format("%s:CARD=%s,DEV=%d", sink, card.c_str(), dev); - - CStdString finalSink; - finalSink.Format("alsa:%s", deviceString.c_str()); - CStdString label; - label.Format("%s - %s - %d (ALSA)", readableCard.c_str(), sink.c_str(), dev); - vAudioSinks.push_back(AudioSink(label, finalSink)); -} diff --git a/xbmc/cores/AudioRenderers/ALSADirectSound.h b/xbmc/cores/AudioRenderers/ALSADirectSound.h deleted file mode 100644 index 21b5acb2cd..0000000000 --- a/xbmc/cores/AudioRenderers/ALSADirectSound.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -* XBMC Media Center -* Copyright (c) 2002 d7o3g4q and RUNTiME -* Portions Copyright (c) by the authors of ffmpeg and xvid -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -// AsyncAudioRenderer.h: interface for the CAsyncDirectSound class. -// -////////////////////////////////////////////////////////////////////// - -#ifndef __ALSA_DIRECT_SOUND_H__ -#define __ALSA_DIRECT_SOUND_H__ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "IAudioRenderer.h" -#include "cores/IAudioCallback.h" - -#define ALSA_PCM_NEW_HW_PARAMS_API -#include <alsa/asoundlib.h> - -#include "../../utils/PCMAmplifier.h" - -extern void RegisterAudioCallback(IAudioCallback* pCallback); -extern void UnRegisterAudioCallback(); - -class CALSADirectSound : public IAudioRenderer -{ -public: - virtual void UnRegisterAudioCallback(); - virtual void RegisterAudioCallback(IAudioCallback* pCallback); - virtual unsigned int GetChunkLen(); - virtual float GetDelay(); - virtual float GetCacheTime(); - virtual float GetCacheTotal(); - CALSADirectSound(); - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = IAudioRenderer::ENCODED_NONE); - virtual ~CALSADirectSound(); - - virtual unsigned int AddPackets(const void* data, unsigned int len); - virtual unsigned int GetSpace(); - virtual bool Deinitialize(); - virtual bool Pause(); - virtual bool Stop(); - virtual bool Resume(); - - virtual long GetCurrentVolume() const; - virtual void Mute(bool bMute); - virtual bool SetCurrentVolume(long nVolume); - virtual void SetDynamicRangeCompression(long drc) { m_drc = drc; } - virtual int SetPlaySpeed(int iSpeed); - virtual void WaitCompletion(); - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers); - - virtual void Flush(); - static void EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough); -private: - unsigned int GetSpaceFrames(); - static void GenSoundLabel(AudioSinkList& vAudioSinks, CStdString sink, CStdString card, int dev, CStdString readableCard); - snd_pcm_t *m_pPlayHandle; - - IAudioCallback* m_pCallback; - CPCMAmplifier m_amp; - long m_nCurrentVolume; - long m_drc; - snd_pcm_uframes_t m_dwFrameCount; - snd_pcm_uframes_t m_uiBufferSize; - unsigned int m_dwNumPackets; - bool m_bPause; - bool m_bIsAllocated; - bool m_bCanPause; - - unsigned int m_uiSamplesPerSec; - unsigned int m_uiBitsPerSample; - unsigned int m_uiDataChannels; - unsigned int m_uiChannels; - - bool m_bPassthrough; -}; - -#endif - diff --git a/xbmc/cores/AudioRenderers/AudioRendererFactory.cpp b/xbmc/cores/AudioRenderers/AudioRendererFactory.cpp deleted file mode 100644 index 927e8ea8f1..0000000000 --- a/xbmc/cores/AudioRenderers/AudioRendererFactory.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "system.h" -#include "AudioRendererFactory.h" -#include "settings/GUISettings.h" -#include "utils/log.h" -#include "NullDirectSound.h" - -#ifdef HAS_PULSEAUDIO -#include "PulseAudioDirectSound.h" -#endif - -#ifdef _WIN32 -#include "Win32WASAPI.h" -#include "Win32DirectSound.h" -#endif -#if defined(__APPLE__) -#if defined(__arm__) - #include "IOSAudioRenderer.h" -#else - #include "CoreAudioRenderer.h" -#endif -#elif defined(USE_ALSA) -#include "ALSADirectSound.h" -#endif - -#define ReturnOnValidInitialize(rendererName) \ -{ \ - if (audioSink->Initialize(pCallback, device, iChannels, channelMap, uiSamplesPerSec, uiBitsPerSample, bResample, bIsMusic, encoded)) \ - { \ - CLog::Log(LOGDEBUG, "%s::Initialize" \ - " - Channels: %i" \ - " - SampleRate: %i" \ - " - SampleBit: %i" \ - " - Resample %s" \ - " - IsMusic %s" \ - " - IsPassthrough %d" \ - " - audioDevice: %s", \ - rendererName, \ - iChannels, \ - uiSamplesPerSec, \ - uiBitsPerSample, \ - bResample ? "true" : "false", \ - bIsMusic ? "true" : "false", \ - encoded, \ - device.c_str() \ - ); \ - return audioSink; \ - } \ - else \ - { \ - audioSink->Deinitialize(); \ - delete audioSink; \ - audioSink = NULL; \ - } \ -} - -#define CreateAndReturnOnValidInitialize(rendererClass) \ -{ \ - audioSink = new rendererClass(); \ - ReturnOnValidInitialize(#rendererClass); \ -} - -#define ReturnNewRenderer(rendererClass) \ -{ \ - renderer = #rendererClass; \ - return new rendererClass(); \ -} - -/* windows channel order */ -static const enum PCMChannels dsound_default_channel_layout[][8] = -{ - {PCM_FRONT_CENTER}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_SIDE_LEFT, PCM_SIDE_RIGHT} -}; - -IAudioRenderer* CAudioRendererFactory::Create(IAudioCallback* pCallback, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, IAudioRenderer::EEncoded encoded) -{ - IAudioRenderer* audioSink = NULL; - CStdString renderer; - - if(channelMap == NULL) - { - CLog::Log(LOGINFO, "CAudioRendererFactory: no input channel map specified assume windows\n"); - channelMap = (enum PCMChannels *)dsound_default_channel_layout[iChannels - 1]; - } - - CStdString deviceString, device; - if (encoded) - { -#if defined(_LINUX) && !defined(__APPLE__) - deviceString = g_guiSettings.GetString("audiooutput.passthroughdevice"); - if (deviceString.Equals("custom")) - deviceString = g_guiSettings.GetString("audiooutput.custompassthrough"); -#else - // osx/win platforms do not have an "audiooutput.passthroughdevice" setting but can do passthrough - deviceString = g_guiSettings.GetString("audiooutput.audiodevice"); -#endif - } - else - { - deviceString = g_guiSettings.GetString("audiooutput.audiodevice"); - if (deviceString.Equals("custom")) - deviceString = g_guiSettings.GetString("audiooutput.customdevice"); - } - int iPos = deviceString.Find(":"); - if (iPos > 0) - { - audioSink = CreateFromUri(deviceString.Left(iPos), renderer); - if (audioSink) - { - device = deviceString.Right(deviceString.length() - iPos - 1); - ReturnOnValidInitialize(renderer.c_str()); - -#ifdef _WIN32 - //If WASAPI failed try DirectSound. - if(deviceString.Left(iPos).Equals("wasapi")) - { - audioSink = CreateFromUri("directsound", renderer); - ReturnOnValidInitialize(renderer.c_str()); - } -#endif - - CreateAndReturnOnValidInitialize(CNullDirectSound); - /* should never get here */ - assert(false); - } - } - CLog::Log(LOGINFO, "AudioRendererFactory: %s not a explicit device, trying to autodetect.", device.c_str()); - - device = deviceString; - -/* First pass creation */ -#ifdef HAS_PULSEAUDIO - CreateAndReturnOnValidInitialize(CPulseAudioDirectSound); -#endif - -/* incase none in the first pass was able to be created, fall back to os specific */ -#ifdef WIN32 - CreateAndReturnOnValidInitialize(CWin32DirectSound); -#endif -#if defined(__APPLE__) - #if defined(__arm__) - CreateAndReturnOnValidInitialize(CIOSAudioRenderer); - #else - CreateAndReturnOnValidInitialize(CCoreAudioRenderer); - #endif -#elif defined(USE_ALSA) - CreateAndReturnOnValidInitialize(CALSADirectSound); -#endif - - CreateAndReturnOnValidInitialize(CNullDirectSound); - /* should never get here */ - assert(false); - return NULL; -} - -void CAudioRendererFactory::EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough) -{ -#ifdef HAS_PULSEAUDIO - CPulseAudioDirectSound::EnumerateAudioSinks(vAudioSinks, passthrough); -#endif - -#ifdef WIN32 - CWin32DirectSound::EnumerateAudioSinks(vAudioSinks, passthrough); - CWin32WASAPI::EnumerateAudioSinks(vAudioSinks, passthrough); -#endif - -#if defined(__APPLE__) - #if !defined(__arm__) - CCoreAudioRenderer::EnumerateAudioSinks(vAudioSinks, passthrough); - #endif -#elif defined(USE_ALSA) - CALSADirectSound::EnumerateAudioSinks(vAudioSinks, passthrough); -#endif -} - -IAudioRenderer *CAudioRendererFactory::CreateFromUri(const CStdString &soundsystem, CStdString &renderer) -{ -#ifdef HAS_PULSEAUDIO - if (soundsystem.Equals("pulse")) - ReturnNewRenderer(CPulseAudioDirectSound); -#endif - -#ifdef WIN32 - if (soundsystem.Equals("wasapi")) - ReturnNewRenderer(CWin32WASAPI) - else if (soundsystem.Equals("directsound")) - ReturnNewRenderer(CWin32DirectSound); -#endif - -#if defined(__APPLE__) - #if defined(__arm__) - if (soundsystem.Equals("ioscoreaudio")) - ReturnNewRenderer(CIOSAudioRenderer); - #else - if (soundsystem.Equals("coreaudio")) - ReturnNewRenderer(CCoreAudioRenderer); - #endif -#elif defined(USE_ALSA) - if (soundsystem.Equals("alsa")) - ReturnNewRenderer(CALSADirectSound); -#endif - - if (soundsystem.Equals("null")) - ReturnNewRenderer(CNullDirectSound); - - return NULL; -} diff --git a/xbmc/cores/AudioRenderers/AudioRendererFactory.h b/xbmc/cores/AudioRenderers/AudioRendererFactory.h deleted file mode 100644 index 6d714e795d..0000000000 --- a/xbmc/cores/AudioRenderers/AudioRendererFactory.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ -#ifndef __AUDIO_RENDERER_FACTORY_H__ -#define __AUDIO_RENDERER_FACTORY_H__ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "IAudioRenderer.h" -#include "cores/IAudioCallback.h" - -class CAudioRendererFactory -{ -public: - static IAudioRenderer *Create(IAudioCallback* pCallback, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, IAudioRenderer::EEncoded encoded = IAudioRenderer::ENCODED_NONE); - static void EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough); -private: - static IAudioRenderer *CreateFromUri(const CStdString &soundsystem, CStdString &renderer); -}; -#endif diff --git a/xbmc/cores/AudioRenderers/CoreAudioRenderer.cpp b/xbmc/cores/AudioRenderers/CoreAudioRenderer.cpp deleted file mode 100644 index e850e25313..0000000000 --- a/xbmc/cores/AudioRenderers/CoreAudioRenderer.cpp +++ /dev/null @@ -1,1650 +0,0 @@ -#ifdef __APPLE__ -/* - * Copyright (C) 2005-2011 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#if !defined(__arm__) -#include "threads/SystemClock.h" -#include <CoreServices/CoreServices.h> - -#include "CoreAudioRenderer.h" -#include "Application.h" -#include "guilib/AudioContext.h" -#include "osx/CocoaInterface.h" -#include "settings/GUISettings.h" -#include "settings/Settings.h" -#include "settings/AdvancedSettings.h" -#include "threads/Atomics.h" -#include "windowing/WindowingFactory.h" -#include "utils/log.h" -#include "utils/SystemInfo.h" -#include "utils/TimeUtils.h" - -const AudioChannelLabel g_LabelMap[] = -{ - kAudioChannelLabel_Left, // PCM_FRONT_LEFT, - kAudioChannelLabel_Right, // PCM_FRONT_RIGHT, - kAudioChannelLabel_Center, // PCM_FRONT_CENTER, - kAudioChannelLabel_LFEScreen, // PCM_LOW_FREQUENCY, - kAudioChannelLabel_LeftSurroundDirect, // PCM_BACK_LEFT, *** This is incorrect, but has been changed to match dvdplayer - kAudioChannelLabel_RightSurroundDirect, // PCM_BACK_RIGHT, *** This is incorrect, but has been changed to match dvdplayer - kAudioChannelLabel_LeftCenter, // PCM_FRONT_LEFT_OF_CENTER, - kAudioChannelLabel_RightCenter, // PCM_FRONT_RIGHT_OF_CENTER, - kAudioChannelLabel_CenterSurround, // PCM_BACK_CENTER, - kAudioChannelLabel_LeftSurround, // PCM_SIDE_LEFT, *** This is incorrect, but has been changed to match dvdplayer - kAudioChannelLabel_RightSurround, // PCM_SIDE_RIGHT, *** This is incorrect, but has been changed to match dvdplayer - kAudioChannelLabel_VerticalHeightLeft, // PCM_TOP_FRONT_LEFT, - kAudioChannelLabel_VerticalHeightRight, // PCM_TOP_FRONT_RIGHT, - kAudioChannelLabel_VerticalHeightCenter, // PCM_TOP_FRONT_CENTER, - kAudioChannelLabel_TopCenterSurround, // PCM_TOP_CENTER, - kAudioChannelLabel_TopBackLeft, // PCM_TOP_BACK_LEFT, - kAudioChannelLabel_TopBackRight, // PCM_TOP_BACK_RIGHT, - kAudioChannelLabel_TopBackCenter // PCM_TOP_BACK_CENTER -}; - -#define MAX_AUDIO_CHANNEL_LABEL kAudioChannelLabel_CenterSurroundDirect - -const AudioChannelLayoutTag g_LayoutMap[] = -{ - kAudioChannelLayoutTag_Stereo, // PCM_LAYOUT_2_0 = 0, - kAudioChannelLayoutTag_DVD_4, // PCM_LAYOUT_2_1, - kAudioChannelLayoutTag_MPEG_3_0_A, // PCM_LAYOUT_3_0, - kAudioChannelLayoutTag_DVD_10, // PCM_LAYOUT_3_1, - kAudioChannelLayoutTag_DVD_3, // PCM_LAYOUT_4_0, - kAudioChannelLayoutTag_DVD_6, // PCM_LAYOUT_4_1, - kAudioChannelLayoutTag_MPEG_5_0_A, // PCM_LAYOUT_5_0, - kAudioChannelLayoutTag_MPEG_5_1_A, // PCM_LAYOUT_5_1, - kAudioChannelLayoutTag_AudioUnit_7_0, // PCM_LAYOUT_7_0, ** This layout may be incorrect...no content to test ** - kAudioChannelLayoutTag_MPEG_7_1_A, // PCM_LAYOUT_7_1 -}; - -///////////////////////////////////////////////////////////////////////////////// -// CAtomicAllocator: Wrapper class for lf_heap. -//////////////////////////////////////////////////////////////////////////////// -CAtomicAllocator::CAtomicAllocator(size_t blockSize) : - m_BlockSize(blockSize) -{ - lf_heap_init(&m_Heap, blockSize); -} - -CAtomicAllocator::~CAtomicAllocator() -{ - lf_heap_deinit(&m_Heap); -} - -void* CAtomicAllocator::Alloc() -{ - return lf_heap_alloc(&m_Heap); -} - -void CAtomicAllocator::Free(void* p) -{ - lf_heap_free(&m_Heap, p); -} - -size_t CAtomicAllocator::GetBlockSize() -{ - return m_BlockSize; -} - -////////////////////////////////////////////////////////////////////////////////////// -// CSliceQueue: Lock-free queue for audio_slices -////////////////////////////////////////////////////////////////////////////////////// -CSliceQueue::CSliceQueue(size_t sliceSize) : - m_TotalBytes(0), - m_pPartialSlice(NULL), - m_RemainderSize(0) -{ - m_pAllocator = new CAtomicAllocator(sliceSize + offsetof(audio_slice, data)); - lf_queue_init(&m_Queue); -} - -CSliceQueue::~CSliceQueue() -{ - Clear(); - lf_queue_deinit(&m_Queue); - delete m_pAllocator; -} - -// NOTE: The value of m_TotalBytes is only guaranteed to be accurate to within one slice, -// but is sufficient. This means that it may at times be one slice too high or one slice -// tool low, but will never be < 0. -void CSliceQueue::Push(audio_slice* pSlice) -{ - if (pSlice) - { - lf_queue_enqueue(&m_Queue, pSlice); - AtomicAdd((long*)&m_TotalBytes, (long)pSlice->header.data_len); - } -} - -audio_slice* CSliceQueue::Pop() -{ - audio_slice* pSlice = (audio_slice*)lf_queue_dequeue(&m_Queue); - if (pSlice) - AtomicSubtract((long*)&m_TotalBytes, (long)pSlice->header.data_len); - return pSlice; -} - -// *** NOTE: AddData and GetData are thread-safe for multiple writers and one reader -size_t CSliceQueue::AddData(void* pBuf, size_t bufLen) -{ - size_t bytesLeft = bufLen; - unsigned char* pData = (unsigned char*)pBuf; - if (pBuf && bufLen) - { - while (bytesLeft) - { - // TODO: find a way to ensure success... - audio_slice* pSlice = (audio_slice*)m_pAllocator->Alloc(); // Allocation should never fail. The heap grows automatically. - if (!pSlice) - { - CLog::Log(LOGDEBUG, "CSliceQueue::AddData: Failed to allocate new slice"); - return bufLen - bytesLeft; - } - pSlice->header.data_len = m_pAllocator->GetBlockSize() - offsetof(audio_slice, data); - if (pSlice->header.data_len >= bytesLeft) // plenty of room. move it all in. - { - memcpy(pSlice->get_data(), pData, bytesLeft); - pSlice->header.data_len = bytesLeft; // Adjust the reported size of the container - } - else - { - memcpy(pSlice->get_data(), pData, pSlice->header.data_len); // Copy all we can into this slice. More to come. - } - bytesLeft -= pSlice->header.data_len; - pData += pSlice->header.data_len; - Push(pSlice); - } - } - return bufLen - bytesLeft; -} - -size_t CSliceQueue::GetData(void* pBuf, size_t bufLen) -{ - if (!pBuf || !bufLen) - return 0; - - size_t remainder = 0; - audio_slice* pNext = NULL; - size_t bytesUsed = 0; - - // See if we can fill the request out of our partial slice (if there is one) - if (m_RemainderSize >= bufLen) - { - memcpy(pBuf, m_pPartialSlice->get_data() + m_pPartialSlice->header.data_len - m_RemainderSize , bufLen); - m_RemainderSize -= bufLen; - bytesUsed = bufLen; - } - else // Pull what we can from the partial slice and get the rest from complete slices - { - // Take what we can from the partial slice (if there is one) - if (m_RemainderSize) - { - memcpy(pBuf, m_pPartialSlice->get_data() + m_pPartialSlice->header.data_len - m_RemainderSize , m_RemainderSize); - bytesUsed += m_RemainderSize; - m_RemainderSize = 0; - } - - // Pull slices from the fifo until we have enough data - do // TODO: The efficiency of this loop can be improved (a lot I imagine) - { - pNext = Pop(); - if (!pNext) - break; - size_t nextLen = pNext->header.data_len; - if (bytesUsed + nextLen > bufLen) // Check for a partial slice - remainder = nextLen - (bufLen - bytesUsed); - memcpy((BYTE*)pBuf + bytesUsed, pNext->get_data(), nextLen - remainder); - bytesUsed += (nextLen - remainder); // Increment output size (remainder will be captured separately) - if (!remainder) - m_pAllocator->Free(pNext); // Free the copied slice - } while (bytesUsed < bufLen); - } - - // Clean up the previous partial slice - if (!m_RemainderSize && m_pPartialSlice) - { - m_pAllocator->Free(m_pPartialSlice); - m_pPartialSlice = NULL; - } - - // Save off the new partial slice (if there is one) - if (remainder) - { - m_pPartialSlice = pNext; - m_RemainderSize = remainder; - } - - return bytesUsed; -} - -size_t CSliceQueue::GetTotalBytes() -{ - return m_TotalBytes + m_RemainderSize; -} - -void CSliceQueue::Clear() -{ - while (audio_slice* pSlice = Pop()) - m_pAllocator->Free(pSlice); - m_pAllocator->Free(m_pPartialSlice); - m_pPartialSlice = NULL; - m_RemainderSize = 0; -} - -//*********************************************************************************************** -// Performance Monitoring Helper Class -//*********************************************************************************************** -CCoreAudioPerformance::CCoreAudioPerformance() : - m_TotalBytesIn(0), - m_TotalBytesOut(0), - m_ExpectedBytesPerSec(0), - m_ActualBytesPerSec(0), - m_Flags(0), - m_WatchdogEnable(false), - m_WatchdogInterval(0), - m_LastWatchdogCheck(0), - m_LastWatchdogBytesIn(0), - m_LastWatchdogBytesOut(0), - m_WatchdogBitrateSensitivity(0.99f), - m_WatchdogPreroll(0) -{ - -} - -CCoreAudioPerformance::~CCoreAudioPerformance() -{ - -} - -void CCoreAudioPerformance::Init(UInt32 expectedBytesPerSec, UInt32 watchdogInterval /*= 1000*/, UInt32 flags /*=0*/) -{ - m_ExpectedBytesPerSec = expectedBytesPerSec; - m_WatchdogInterval = watchdogInterval; - m_Flags = flags; -} - -void CCoreAudioPerformance::ReportData(UInt32 bytesIn, UInt32 bytesOut) -{ - m_TotalBytesIn += bytesIn; - m_TotalBytesOut += bytesOut; - - if (!m_WatchdogEnable) - return; - - // Perform watchdog funtions - UInt32 time = XbmcThreads::SystemClockMillis(); - if (!m_LastWatchdogCheck) - m_LastWatchdogCheck = time; - UInt32 deltaTime = time - m_LastWatchdogCheck; - m_ActualBytesPerSec = (m_TotalBytesOut - m_LastWatchdogBytesOut) / ((float)deltaTime/1000.0f); - if (deltaTime > m_WatchdogInterval) - { - if (m_TotalBytesOut > m_WatchdogPreroll) // Allow m_WatchdogPreroll bytes to go by unmonitored - { - // Check outgoing bitrate - if (m_ActualBytesPerSec < m_WatchdogBitrateSensitivity * m_ExpectedBytesPerSec) - CLog::Log(LOGWARNING, "CCoreAudioPerformance: Outgoing bitrate is lagging. Target: %lu, Actual: %lu. deltaTime was %lu", m_ExpectedBytesPerSec, m_ActualBytesPerSec, deltaTime); - } - m_LastWatchdogCheck = time; - m_LastWatchdogBytesIn = m_TotalBytesIn; - m_LastWatchdogBytesOut = m_TotalBytesOut; - } -} - -void CCoreAudioPerformance::EnableWatchdog(bool enable) -{ - if (!m_WatchdogEnable && enable) - Reset(); - m_WatchdogEnable = enable; -} - -void CCoreAudioPerformance::SetPreroll(UInt32 bytes) -{ - m_WatchdogPreroll = bytes; -} - -void CCoreAudioPerformance::SetPreroll(float seconds) -{ - SetPreroll((UInt32)(seconds * m_ExpectedBytesPerSec)); -} - -void CCoreAudioPerformance::Reset() -{ - m_TotalBytesIn = 0; - m_TotalBytesOut = 0; - m_ActualBytesPerSec = 0; - m_LastWatchdogCheck = 0; - m_LastWatchdogBytesIn = 0; - m_LastWatchdogBytesOut = 0; -} - -//*********************************************************************************************** -// Surround Up/Down Mapping Class -//*********************************************************************************************** -struct ChannelPatch -{ - AudioChannelLabel label; // Target Channel - Float32 coeff; // Output level -}; - -// TODO: There is not a lot of logic behind these mapping coefficients -// Routings for Explicit Mapping. These are in priority order. -// g_ChannelRoutings[channel][routing][patch] -// These are currently all down-mix routings -#define MAX_CHANNELS sizeof(g_LabelMap)/sizeof(AudioChannelLabel) -#define NO_ROUTINGS {{{kAudioChannelLabel_Unknown, 0.0f}}} -ChannelPatch g_ChannelRoutings[MAX_AUDIO_CHANNEL_LABEL+1][MAX_CHANNELS][MAX_CHANNELS] = -{ - NO_ROUTINGS, // kAudioChannelLabel_Unknown (0) - // kAudioChannelLabel_Left (1) - { - {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_Right (2) - { - {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_Center (3) - { - {{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_LFEScreen (4) - { - {{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_LeftSurround (5) - { - {{kAudioChannelLabel_LeftSurroundDirect, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_RightSurround (6) - { - {{kAudioChannelLabel_RightSurroundDirect, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_LeftCenter (7) - { - {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_RightCenter (8) - { - {{kAudioChannelLabel_Center, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_CenterSurround (9) - { - {{kAudioChannelLabel_LeftSurround, 0.707f},{kAudioChannelLabel_RightSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_LeftSurroundDirect, 0.707f},{kAudioChannelLabel_RightSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Left, 0.707f},{kAudioChannelLabel_Right, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_LeftSurroundDirect (10) - { - {{kAudioChannelLabel_LeftSurround, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_RightSurroundDirect (11) - { - {{kAudioChannelLabel_RightSurround, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - NO_ROUTINGS, //kAudioChannelLabel_TopCenterSurround (12) - NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightLeft (13) - NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightCenter (14) - NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightRight (15) - NO_ROUTINGS, //kAudioChannelLabel_TopBackLeft (16) - NO_ROUTINGS, //kAudioChannelLabel_TopBackCenter (17) - NO_ROUTINGS, //kAudioChannelLabel_VerticalHeightRight (18) - NO_ROUTINGS, // INVALID LABEL (19) - NO_ROUTINGS, // INVALID LABEL (20) - NO_ROUTINGS, // INVALID LABEL (21) - NO_ROUTINGS, // INVALID LABEL (22) - NO_ROUTINGS, // INVALID LABEL (23) - NO_ROUTINGS, // INVALID LABEL (24) - NO_ROUTINGS, // INVALID LABEL (25) - NO_ROUTINGS, // INVALID LABEL (26) - NO_ROUTINGS, // INVALID LABEL (27) - NO_ROUTINGS, // INVALID LABEL (28) - NO_ROUTINGS, // INVALID LABEL (29) - NO_ROUTINGS, // INVALID LABEL (30) - NO_ROUTINGS, // INVALID LABEL (31) - NO_ROUTINGS, // INVALID LABEL (32) - // kAudioChannelLabel_RearSurroundLeft (33) - { - {{kAudioChannelLabel_LeftSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_LeftSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Left, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - // kAudioChannelLabel_RearSurroundRight (34) - { - {{kAudioChannelLabel_RightSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_RightSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurround, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_CenterSurroundDirect, 0.707f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Right, 1.0f},{kAudioChannelLabel_Unknown, 0.0f}}, - {{kAudioChannelLabel_Unknown, 0.0f}} - }, - NO_ROUTINGS, // kAudioChannelLabel_LeftWide (35) - NO_ROUTINGS, // kAudioChannelLabel_RightWide (36) - NO_ROUTINGS, // kAudioChannelLabel_LFE2 (37) - NO_ROUTINGS, // kAudioChannelLabel_LeftTotal (38) - NO_ROUTINGS, // kAudioChannelLabel_RightTotal (39) - NO_ROUTINGS, // kAudioChannelLabel_HearingImpaired (40) - NO_ROUTINGS, // kAudioChannelLabel_Narration (41) - NO_ROUTINGS, // kAudioChannelLabel_Mono (42) - NO_ROUTINGS, // kAudioChannelLabel_DialogCentricMix (43) - NO_ROUTINGS // kAudioChannelLabel_CenterSurroundDirect (44) -}; - -CCoreAudioMixMap::CCoreAudioMixMap() : - m_isValid(false) -{ - m_pMap = (Float32*)calloc(sizeof(Float32), 2); -} - -CCoreAudioMixMap::CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit/*=false*/) : - m_isValid(false) -{ - Rebuild(inLayout, outLayout, forceExplicit); -} - -CCoreAudioMixMap::~CCoreAudioMixMap() -{ - if (m_pMap) - { - free(m_pMap); - } -} - -void CCoreAudioMixMap::Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit/*=false*/) -{ - // map[in][out] = mix-level of input_channel[in] into output_channel[out] - - if (m_pMap) - { - free(m_pMap); - m_pMap = NULL; - } - - m_inChannels = CCoreAudioChannelLayout::GetChannelCountForLayout(inLayout); - m_outChannels = CCoreAudioChannelLayout::GetChannelCountForLayout(outLayout); - - // If the caller allows it, try to find a 'well-known' matrix - if (!forceExplicit) - { - const AudioChannelLayout* layouts[] = {&inLayout, &outLayout}; - UInt32 propSize = 0; - OSStatus ret = AudioFormatGetPropertyInfo(kAudioFormatProperty_MatrixMixMap, sizeof(layouts), layouts, &propSize); - m_pMap = (Float32*)calloc(1,propSize); - ret = AudioFormatGetProperty(kAudioFormatProperty_MatrixMixMap, sizeof(layouts), layouts, &propSize, m_pMap); - if (!ret) - { - m_isValid = true; - CLog::Log(LOGDEBUG, "CCoreAudioMixMap::Rebuild: Using pre-defined mixing matrix."); - return; // Nothing else to do...a map already exists - } - - // No predefined mixing matrix was available. Going to have to build it manually - CLog::Log(LOGDEBUG, "CCoreAudioMixMap::Rebuild: Unable to locate pre-defined mixing matrix. Trying to build one explicitly..."); - } - else - CLog::Log(LOGINFO, "CCoreAudioMixMap::Rebuild: Building explicit mixing matrix [forceExplicit=true]"); - - // Try to build a mixing matrix from scratch - m_isValid = BuildExplicit(inLayout, outLayout); -} - -bool CCoreAudioMixMap::BuildExplicit(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout) -{ - // Initialize map - // map[in][out] = mix-level of input_channel[in] into output_channel[out] - m_pMap = (Float32*)calloc(sizeof(Float32), inLayout.mNumberChannelDescriptions * outLayout.mNumberChannelDescriptions); - int mappedChannels = 0; - - // Initialize array of output channel locations - int outPos[MAX_AUDIO_CHANNEL_LABEL + 1]; - for (UInt32 i = 0; i < (MAX_AUDIO_CHANNEL_LABEL + 1); i++) - outPos[i] = -1; - - // Map output channel order to output layout - for (UInt32 channel = 0; channel < outLayout.mNumberChannelDescriptions; channel++) - outPos[outLayout.mChannelDescriptions[channel].mChannelLabel] = channel; - - CLog::Log(LOGDEBUG, "CCoreAudioMixMap::BuildExplicit: Building mixing matrix [%d input channels, %d output channels]", inLayout.mNumberChannelDescriptions, outLayout.mNumberChannelDescriptions); - - // For each input channel, decide how to route/mix it - for (UInt32 channel = 0; channel < inLayout.mNumberChannelDescriptions; channel++) - { - AudioChannelDescription* pDesc = &inLayout.mChannelDescriptions[channel]; - - if (pDesc->mChannelLabel > MAX_AUDIO_CHANNEL_LABEL) - { - CLog::Log(LOGINFO, "CCoreAudioMixMap::BuildExplicit:\tUnrecognized input channel encountered (label=%d) - skipping.", pDesc->mChannelLabel); - continue; - } - - // Does the channel exist in the output? - int outIndex = outPos[pDesc->mChannelLabel]; - if (outIndex > -1) // If so, just pass it through - { - // map[in][out] = map[in * outCount + out] - CLog::Log(LOGDEBUG, "CCoreAudioMixMap::BuildExplicit:\tin[%d] -> out[%d] @ %0.02f", channel, outIndex, 1.0f); - m_pMap[channel * outLayout.mNumberChannelDescriptions + outIndex] = 1.0f; - mappedChannels++; - } - else // The input channel does not exist in the output layout. Decide where to route it... - { - // Loop through the pre-defined routings strategies for this channel. Use the first compatible one we find - for (UInt32 r = 0; r < MAX_CHANNELS; r++) - { - // If the first patch's label is kAudioChannelLabel_Unknown, this is the routing list terminator - if (g_ChannelRoutings[pDesc->mChannelLabel][r][0].label == kAudioChannelLabel_Unknown) - break; // No dice... - - // Check each patch in this routing to see if it is possible. If it is not, give up on this routing - bool validRouting = false; - for (UInt32 p = 0; ((p < MAX_CHANNELS) && !validRouting); p++) - { - ChannelPatch* patch = &g_ChannelRoutings[pDesc->mChannelLabel][r][p]; - if (patch->label == kAudioChannelLabel_Unknown) // End of this routing - validRouting = true; // Success...this routing should work. - else if (outPos[patch->label] == -1) - break; // The specified output channel is not available. Invalidate the whole routing - } - - // If this is a valid routing (all output channels are available), apply it... - if (validRouting) - { - for (UInt32 p = 0; p < MAX_CHANNELS; p++) - { - ChannelPatch* patch = &g_ChannelRoutings[pDesc->mChannelLabel][r][p]; - if (patch->label == kAudioChannelLabel_Unknown) // List terminator - break; - - int outIndex = outPos[patch->label]; - CLog::Log(LOGDEBUG, "CCoreAudioMixMap::BuildExplicit:\tin[%d] -> out[%d] @ %0.02f", channel, outIndex, patch->coeff); - m_pMap[channel * outLayout.mNumberChannelDescriptions + outIndex] = patch->coeff; - mappedChannels++; - } - break; - } - } - } - } - if (!mappedChannels) - { - CLog::Log(LOGINFO, "CCoreAudioMixMap::BuildExplicit: No valid patches found."); - return false; - } - - CLog::Log(LOGINFO, "CCoreAudioMixMap::BuildExplicit: Completed explicit channel map."); - return true; -} - -//*********************************************************************************************** -// Contruction/Destruction -//*********************************************************************************************** -CCoreAudioRenderer::CCoreAudioRenderer() : - m_Pause(false), - m_ChunkLen(0), - m_MaxCacheLen(0), - m_AvgBytesPerSec(0), - m_CurrentVolume(0), - m_Initialized(false), - m_Passthrough(false), - m_EnableVolumeControl(true), - m_OutputBufferIndex(0), - m_pCache(NULL), - m_DoRunout(0) -{ - m_init_state.reinit = false; - m_init_state.channelMap = NULL; - - SInt32 major, minor; - Gestalt(gestaltSystemVersionMajor, &major); - Gestalt(gestaltSystemVersionMinor, &minor); - - // By default, kAudioHardwarePropertyRunLoop points at the process's main thread on SnowLeopard, - // If your process lacks such a run loop, you can set kAudioHardwarePropertyRunLoop to NULL which - // tells the HAL to run it's own thread for notifications (which was the default prior to SnowLeopard). - // So tell the HAL to use its own thread for similar behavior under all supported versions of OSX. - if (major == 10 && minor >=6) - { - CFRunLoopRef theRunLoop = NULL; - AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; - OSStatus theError = AudioObjectSetPropertyData(kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); - if (theError != noErr) - { - CLog::Log(LOGERROR, "CoreAudioRenderer::constructor: kAudioHardwarePropertyRunLoop error."); - } - } -#ifdef VERBOSE_DEBUG - AudioHardwareAddPropertyListener(kAudioHardwarePropertyDevices, HardwareListenerProc, this); - AudioHardwareAddPropertyListener(kAudioHardwarePropertyIsInitingOrExiting, HardwareListenerProc, this); - AudioHardwareAddPropertyListener(kAudioHardwarePropertyDefaultOutputDevice, HardwareListenerProc, this); -#endif - g_Windowing.Register(this); -} - -CCoreAudioRenderer::~CCoreAudioRenderer() -{ -#ifdef VERBOSE_DEBUG - AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDevices, HardwareListenerProc); - AudioHardwareRemovePropertyListener(kAudioHardwarePropertyIsInitingOrExiting, HardwareListenerProc); - AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDefaultOutputDevice, HardwareListenerProc); -#endif - g_Windowing.Unregister(this); - Deinitialize(); - delete m_init_state.channelMap; -} - -//*********************************************************************************************** -// Initialization -//*********************************************************************************************** - -// Macro to use for sanity checks in each method. 'x' is the return value if not initialized -#define VERIFY_INIT(x) \ -if (!m_Initialized) \ -return x - -bool CCoreAudioRenderer::Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic /*Useless Legacy Parameter*/, EEncoded bPassthrough) -{ - CSingleLock lock(m_init_csection); - - // Have to clean house before we start again. - // TODO: Should we return failure instead? - if (m_Initialized) - Deinitialize(); - - m_init_state.device = device; - m_init_state.iChannels = iChannels; - // save the old and delete after clone incase we are reinit'ing. - enum PCMChannels *old_channelMap = m_init_state.channelMap; - m_init_state.channelMap = NULL; - if (channelMap) - { - m_init_state.channelMap = new PCMChannels[m_init_state.iChannels]; - for (int i = 0; i < iChannels; i++) - m_init_state.channelMap[i] = channelMap[i]; - } - delete [] old_channelMap; - m_init_state.uiSamplesPerSec = uiSamplesPerSec; - m_init_state.uiBitsPerSample = uiBitsPerSample; - m_init_state.bResample = bResample; - m_init_state.bIsMusic = bIsMusic; - m_init_state.bPassthrough = bPassthrough; - m_init_state.pCallback = pCallback; - - // Reset all the devices to a default 'non-hog' and mixable format. - // If we don't do this we may be unable to find the Default Output device. - // (e.g. if we crashed last time leaving it stuck in AC3/DTS/SPDIF mode) - Cocoa_ResetAudioDevices(); - - if(m_init_state.bPassthrough) - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE_DIGITAL); - else - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE); - - // TODO: If debugging, output information about all devices/streams - - // Attempt to find the configured output device - AudioDeviceID outputDevice = CCoreAudioHardware::FindAudioDevice(g_guiSettings.GetString("audiooutput.audiodevice")); - // Fall back to the default device if no match is found - if (!outputDevice) - { - CLog::Log(LOGWARNING, "CoreAudioRenderer::Initialize: " - "Unable to locate configured device, falling-back to the system default."); - outputDevice = CCoreAudioHardware::GetDefaultOutputDevice(); - // Not a lot to be done with no device. - // TODO: Should we just grab the first existing device? - if (!outputDevice) - return false; - } - -#ifdef VERBOSE_DEBUG - AudioDeviceAddPropertyListener(outputDevice, 0, false, kAudioDevicePropertyDeviceIsAlive, DeviceListenerProc, this); - AudioDeviceAddPropertyListener(outputDevice, 0, false, kAudioDevicePropertyDeviceIsRunning, DeviceListenerProc, this); - AudioDeviceAddPropertyListener(outputDevice, 0, false, kAudioDevicePropertyStreamConfiguration, DeviceListenerProc, this); -#endif - - // TODO: Determine if the device is in-use/locked by another process. - - // Attach our output object to the device - m_AudioDevice.Open(outputDevice); - - // If this is a passthrough (AC3/DTS) stream, attempt to handle it natively - if (m_init_state.bPassthrough) - { - m_Passthrough = InitializeEncoded(outputDevice, m_init_state.uiSamplesPerSec); - // TODO: wait for audio device startup - Sleep(200); - } - - // If this is a PCM stream, or we failed to handle a passthrough stream natively, - // prepare the standard interleaved PCM interface - if (!m_Passthrough) - { - // Create the Output AudioUnit Component - if (!m_AUOutput.Open(kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple)) - return false; - - // Hook the Ouput AudioUnit to the selected device - if (!m_AUOutput.SetCurrentDevice(outputDevice)) - return false; - - // If we are here and this is a passthrough stream, native handling failed. - // Try to handle it as IEC61937 data over straight PCM (DD-Wav) - bool configured = false; - if (m_init_state.bPassthrough) - { - CLog::Log(LOGDEBUG, "CoreAudioRenderer::Initialize: " - "No suitable AC3 output format found. Attempting DD-Wav."); - configured = InitializePCMEncoded(m_init_state.uiSamplesPerSec); - // TODO: wait for audio device startup - Sleep(250); - } - else - { - // Standard PCM data - configured = InitializePCM(m_init_state.iChannels, m_init_state.uiSamplesPerSec, m_init_state.uiBitsPerSample, m_init_state.channelMap); - // TODO: wait for audio device startup - Sleep(250); - } - - // No suitable output format was able to be configured - if (!configured) - return false; - - // Configure the maximum number of frames that the AudioUnit will ask to process at one time. - // If this is not called, there is no guarantee that the callback will ever be called. - // Size of the output buffer, in Frames - UInt32 bufferFrames = m_AUOutput.GetBufferFrameSize(); - if (!m_AUOutput.SetMaxFramesPerSlice(bufferFrames)) - return false; - - // This is the minimum amount of data that we will accept from a client - m_ChunkLen = bufferFrames * m_BytesPerFrame; - - // Setup the callback function that the AudioUnit will use to request data - ICoreAudioSource* pSource = this; - if (m_init_state.bIsMusic) - { - // A mixer is in-use - if (m_MixerUnit.IsInitialized()) - pSource = &m_MixerUnit; - } - else - { - // A mixer+compressor are in-use - if (m_AUCompressor.IsInitialized()) - pSource = &m_AUCompressor; - } - if (!m_AUOutput.SetInputSource(pSource)) - return false; - - // Initialize the Output AudioUnit - if (!m_AUOutput.Initialize()) - return false; - - // Log some information about the stream - AudioStreamBasicDescription inputDesc_end, outputDesc_end; - CStdString formatString; - m_AUOutput.GetInputFormat(&inputDesc_end); - m_AUOutput.GetOutputFormat(&outputDesc_end); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::Initialize: Input Stream Format %s", - StreamDescriptionToString(inputDesc_end, formatString)); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::Initialize: Output Stream Format %s", - StreamDescriptionToString(outputDesc_end, formatString)); - } - - m_NumLatencyFrames = m_AudioDevice.GetNumLatencyFrames(); - // Set the max cache size to 1 second of data. TODO: Make this more intelligent - m_MaxCacheLen = m_AvgBytesPerSec; - // Suspend rendering. We will start once we have some data. - m_Pause = true; - // Initialize our incoming data cache - if (!m_pCache) - m_pCache = new CSliceQueue(m_ChunkLen); -#ifdef _DEBUG - // Set up the performance monitor - m_PerfMon.Init(m_AvgBytesPerSec, 1000, CCoreAudioPerformance::FlagDefault); - // Disable underrun detection for the first 2 seconds (after start and after resume) - m_PerfMon.SetPreroll(2.0f); -#endif - m_init_state.reinit = false; - m_Initialized = true; - m_DoRunout = 0; - - SetCurrentVolume(g_settings.m_nVolumeLevel); - - CLog::Log(LOGDEBUG, "CoreAudioRenderer::Initialize: " - "Renderer Configuration - Chunk Len: %u, Max Cache: %lu (%0.0fms).", - m_ChunkLen, m_MaxCacheLen, 1000.0 *(float)m_MaxCacheLen/(float)m_AvgBytesPerSec); - CLog::Log(LOGINFO, "CoreAudioRenderer::Initialize: Successfully configured audio output."); - - return true; -} - -bool CCoreAudioRenderer::Deinitialize() -{ - VERIFY_INIT(true); // Not really a failure if we weren't initialized - -#ifdef VERBOSE_DEBUG - AudioDeviceRemovePropertyListener(m_AudioDevice.GetId(), 0, false, kAudioDevicePropertyDeviceIsAlive, DeviceListenerProc); - AudioDeviceRemovePropertyListener(m_AudioDevice.GetId(), 0, false, kAudioDevicePropertyDeviceIsRunning, DeviceListenerProc); - AudioDeviceRemovePropertyListener(m_AudioDevice.GetId(), 0, false, kAudioDevicePropertyStreamConfiguration, DeviceListenerProc); -#endif - - // Stop rendering - Stop(); - // Reset our state but do not diddle internal vars if we are re-init'ing - if (!m_init_state.reinit) - { - m_ChunkLen = 0; - m_MaxCacheLen = 0; - m_AvgBytesPerSec = 0; - } - if (m_Passthrough) - m_AudioDevice.RemoveIOProc(); - m_AUCompressor.Close(); - m_MixerUnit.Close(); - m_AUConverter.Close(); - m_AUOutput.Close(); - m_OutputStream.Close(); - Sleep(10); - m_AudioDevice.Close(); - if (!m_init_state.reinit) - { - // do not blow the cache if we are just re-init'ing - delete m_pCache; - m_pCache = NULL; - } - m_Initialized = false; - m_DoRunout = 0; - m_EnableVolumeControl = true; - - // do not diddle with active device if we are re-init'ing - if (!m_init_state.reinit) - g_audioContext.SetActiveDevice(CAudioContext::DEFAULT_DEVICE); - - CLog::Log(LOGINFO, "CoreAudioRenderer::Deinitialize: Renderer has been shut down."); - - return true; -} - -bool CCoreAudioRenderer::Reinitialize() -{ - CSingleLock lock(m_init_csection); - - m_init_state.reinit = true; - return Initialize(m_init_state.pCallback, - m_init_state.device, - m_init_state.iChannels, - m_init_state.channelMap, - m_init_state.uiSamplesPerSec, - m_init_state.uiBitsPerSample, - m_init_state.bResample, - m_init_state.bIsMusic, - m_init_state.bPassthrough); -} -//*********************************************************************************************** -// Transport control methods -//*********************************************************************************************** -bool CCoreAudioRenderer::Pause() -{ - VERIFY_INIT(false); - - if (!m_Pause) - { - //CLog::Log(LOGDEBUG, "CoreAudioRenderer::Pause: Pausing Playback."); - if (m_Passthrough) - m_AudioDevice.Stop(); - else - m_AUOutput.Stop(); - m_Pause = true; - } -#ifdef _DEBUG - m_PerfMon.EnableWatchdog(false); // Stop monitoring, we're paused -#endif - return true; -} - -bool CCoreAudioRenderer::Resume() -{ - VERIFY_INIT(false); - - if (m_Pause) - { - //CLog::Log(LOGDEBUG, "CoreAudioRenderer::Resume: Resuming Playback."); - if (m_Passthrough) - m_AudioDevice.Start(); - else - m_AUOutput.Start(); - m_Pause = false; - } -#ifdef _DEBUG - m_PerfMon.EnableWatchdog(true); // Resume monitoring -#endif - return true; -} - -bool CCoreAudioRenderer::Stop() -{ - VERIFY_INIT(false); - - if (m_Passthrough) - m_AudioDevice.Stop(); - else - m_AUOutput.Stop(); - - m_Pause = true; -#ifdef _DEBUG - m_PerfMon.EnableWatchdog(false); -#endif - m_pCache->Clear(); - - return true; -} - -//*********************************************************************************************** -// Volume control methods -//*********************************************************************************************** -LONG CCoreAudioRenderer::GetCurrentVolume() const -{ - return m_CurrentVolume; -} - -void CCoreAudioRenderer::Mute(bool bMute) -{ - if (bMute) - SetCurrentVolume(0); - else - SetCurrentVolume(m_CurrentVolume); -} - -bool CCoreAudioRenderer::SetCurrentVolume(LONG nVolume) -{ - VERIFY_INIT(false); - - if (m_EnableVolumeControl) // Don't change actual volume for encoded streams - { - // Convert milliBels to percent - Float32 volPct = pow(10.0f, (float)nVolume/2000.0f); - - // Try to set the volume. If it fails there is not a lot to be done. - if (!m_AUOutput.SetCurrentVolume(volPct)) - return false; - } - m_CurrentVolume = nVolume; // Store the volume setpoint. We need this to check for 'mute' - return true; -} - -void CCoreAudioRenderer::SetDynamicRangeCompression(long drc) -{ - if (m_AUCompressor.IsInitialized()) - m_AUCompressor.SetMasterGain(((float)drc)/100.0f); -} - -//*********************************************************************************************** -// Data management methods -//*********************************************************************************************** -unsigned int CCoreAudioRenderer::GetSpace() -{ - VERIFY_INIT(0); - return m_MaxCacheLen - m_pCache->GetTotalBytes(); // This is just an estimate, since the driver is asynchonously pulling data. -} - -unsigned int CCoreAudioRenderer::AddPackets(const void* data, DWORD len) -{ - if (!m_pCache) - return 0; - - // Require at least one 'chunk'. This allows us at least some measure of control over efficiency - if (len < m_ChunkLen || m_pCache->GetTotalBytes() >= m_MaxCacheLen) - return 0; - - unsigned int cacheSpace = GetSpace(); - if (len > cacheSpace) - return 0; // Wait until we can accept all of it - - size_t bytesUsed = m_pCache->AddData((void*)data, len); - -#ifdef _DEBUG - // Update tracking variable - m_PerfMon.ReportData(bytesUsed, 0); -#endif - - //We have some data. Attempt to resume playback only if not trying to reinit. - if (!m_init_state.reinit) - Resume(); - - // Number of bytes added to cache; - return bytesUsed; -} - -float CCoreAudioRenderer::GetDelay() -{ - VERIFY_INIT(0); - // Calculate the duration of the data in the cache - float delay = (float)m_pCache->GetTotalBytes()/(float)m_AvgBytesPerSec; - // TODO: Obtain hardware/os latency for better accuracy - delay += (float)m_NumLatencyFrames/(float)m_AvgBytesPerSec; - - return delay; -} - -float CCoreAudioRenderer::GetCacheTime() -{ - return GetDelay(); -} - -float CCoreAudioRenderer::GetCacheTotal() -{ - return (float)m_MaxCacheLen / m_AvgBytesPerSec; -} - -unsigned int CCoreAudioRenderer::GetChunkLen() -{ - return m_ChunkLen; -} - -void CCoreAudioRenderer::WaitCompletion() -{ - VERIFY_INIT(); - - // The cache is already empty. There is nothing to wait for. - if (m_pCache->GetTotalBytes() == 0) - return; - - // Signal that we are waiting - AtomicIncrement(&m_DoRunout); - // Signal that a buffer underrun is OK - m_DoRunout = 1; - // TODO: Should we pad the wait time to allow for preemption? - // This is how much time 'should' be in the cache (plus 10ms for preemption hedge) - UInt32 delay = (UInt32)(GetDelay() * 1000.0f) + 10; - if (delay) - { - // Wait for the callback thread to process the whole cache, - // but only wait as long as we expect it to take. - m_RunoutEvent.WaitMSec(delay); - if (!m_RunoutEvent.WaitMSec(delay)) - { - CLog::Log(LOGERROR, "CCoreAudioRenderer::WaitCompletion: " - "Timed-out waiting for runout. Remaining data will be truncated."); - } - } - - Stop(); -} - -//*********************************************************************************************** -// Rendering Methods -//*********************************************************************************************** -OSStatus CCoreAudioRenderer::Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList) -{ - OSStatus ret = OnRender(actionFlags, pTimeStamp, busNumber, frameCount, pBufList); - return ret; -} - -OSStatus CCoreAudioRenderer::OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - if (!m_Initialized) - { - CLog::Log(LOGERROR, "CCoreAudioRenderer::OnRender: Callback to de/unitialized renderer."); - ioData->mBuffers[m_OutputBufferIndex].mDataByteSize = 0; - } - - // Process the request - // Data length requested, based on the input data format - UInt32 bytesRequested = m_BytesPerFrame * inNumberFrames; - UInt32 bytesRead = (UInt32)m_pCache->GetData(ioData->mBuffers[m_OutputBufferIndex].mData, bytesRequested); - if (bytesRead < bytesRequested) - { - // Stop further requests until we have more data. - // The AddPackets method will resume playback - Pause(); - // Tell anyone who cares that the cache is empty - m_RunoutEvent.Set(); - // We were waiting for a runout. This is not an error. - if (m_DoRunout) - { - //CLog::Log(LOGDEBUG, "CCoreAudioRenderer::OnRender: Runout complete"); - m_DoRunout = 0; - } - /* - else - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::OnRender: Buffer underrun."); - */ - } - // Hard mute for formats that do not allow standard volume control. Throw away any actual data to keep the stream moving. - if (!m_EnableVolumeControl && m_CurrentVolume <= VOLUME_MINIMUM) - memset(ioData->mBuffers[m_OutputBufferIndex].mData, 0x00, bytesRead); - ioData->mBuffers[m_OutputBufferIndex].mDataByteSize = bytesRead; - -#ifdef _DEBUG - // Calculate stats and perform a sanity check - m_PerfMon.ReportData(0, bytesRead); // TODO: Should we check the result? -#endif - return noErr; -} - -// Static Callback from AudioDevice -OSStatus CCoreAudioRenderer::DirectRenderCallback(AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData) -{ - CCoreAudioRenderer* pThis = (CCoreAudioRenderer*)inClientData; - return pThis->OnRender(NULL, inInputTime, 0, outOutputData->mBuffers[0].mDataByteSize / pThis->m_BytesPerFrame, outOutputData); -} - -//*********************************************************************************************** -// Audio Device Initialization Methods -//*********************************************************************************************** -bool CCoreAudioRenderer::InitializePCM(UInt32 channels, UInt32 samplesPerSecond, UInt32 bitsPerSample, enum PCMChannels *channelMap, bool allowMixing /*= true*/) -{ - // Set the input stream format for the first AudioUnit (this is what is being sent to us) - AudioStreamBasicDescription inputFormat; - AudioStreamBasicDescription outputFormat; - inputFormat.mFormatID = kAudioFormatLinearPCM; // Data encoding format - inputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian - | kLinearPCMFormatFlagIsPacked // Samples occupy all bits (not left or right aligned) - | kAudioFormatFlagIsSignedInteger; - inputFormat.mChannelsPerFrame = channels; // Number of interleaved audiochannels - inputFormat.mSampleRate = (Float64)samplesPerSecond; // the sample rate of the audio stream - inputFormat.mBitsPerChannel = bitsPerSample; // Number of bits per sample, per channel - inputFormat.mBytesPerFrame = (bitsPerSample>>3) * channels; // Size of a frame == 1 sample per channel - inputFormat.mFramesPerPacket = 1; // The smallest amount of indivisible data. Always 1 for uncompressed audio - inputFormat.mBytesPerPacket = inputFormat.mBytesPerFrame * inputFormat.mFramesPerPacket; - inputFormat.mReserved = 0; - - // Configure up/down mixing if necessary, if caller allows it (and provides enough information to complete it) - if (allowMixing && channelMap) - { - bool hasLFE = false; - // Convert XBMC input channel layout format to CoreAudio layout format - AudioChannelLayout* pInLayout = (AudioChannelLayout*)malloc(sizeof(AudioChannelLayout) + sizeof(AudioChannelDescription) * channels); - pInLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; - pInLayout->mChannelBitmap = 0; - pInLayout->mNumberChannelDescriptions = channels; - for (unsigned int chan=0; chan < channels; chan++) - { - AudioChannelDescription* pDesc = &pInLayout->mChannelDescriptions[chan]; - pDesc->mChannelLabel = g_LabelMap[(unsigned int)channelMap[chan]]; // Convert from XBMC channel tag to CoreAudio channel tag - pDesc->mChannelFlags = kAudioChannelFlags_AllOff; - pDesc->mCoordinates[0] = 0.0f; - pDesc->mCoordinates[1] = 0.0f; - pDesc->mCoordinates[2] = 0.0f; - if (pDesc->mChannelLabel == kAudioChannelLabel_LFEScreen) - hasLFE = true; - } - - // HACK: Fix broken channel layouts coming from some aac sources that include rear channels but no side channels. - // 5.1 streams should include front and side channels. Rear channels are added by 6.1 and 7.1, so any 5.1 - // source that claims to have rear channels is wrong. - if (inputFormat.mChannelsPerFrame == 6 && hasLFE) // Check for 5.1 configuration (as best we can without getting too silly) - { - for (unsigned int chan=0; chan < inputFormat.mChannelsPerFrame; chan++) - { - AudioChannelDescription* pDesc = &pInLayout->mChannelDescriptions[chan]; - if (pDesc->mChannelLabel == kAudioChannelLabel_LeftSurround || pDesc->mChannelLabel == kAudioChannelLabel_LeftSurround) - break; // Required condition cannot be true - - if (pDesc->mChannelLabel == kAudioChannelLabel_LeftSurroundDirect) - { - pDesc->mChannelLabel = kAudioChannelLabel_LeftSurround; // Change [Back Left] to [Side Left] - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: Detected faulty input channel map...fixing(Back Left-->Side Left)"); - } - if (pDesc->mChannelLabel == kAudioChannelLabel_RightSurroundDirect) - { - pDesc->mChannelLabel = kAudioChannelLabel_RightSurround; // Change [Back Left] to [Side Left] - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: Detected faulty input channel map...fixing(Back Right-->Side Right)"); - } - } - } - - CCoreAudioChannelLayout sourceLayout(*pInLayout); - free(pInLayout); - pInLayout = NULL; - - CStdString strInLayout; - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: Source Stream Layout: %s", CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)sourceLayout, strInLayout)); - - // Get User-Configured (XBMC) Speaker Configuration - AudioChannelLayout guiLayout; - if (g_sysinfo.IsAppleTV()) - { - // Force ATV1 to a 2.0 layout (that is all it knows), since it does not provide a usable channel layout - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: AppleTV detected - Forcing channel layout to 2.0 (max available PCM channels)"); - guiLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; - } - else - guiLayout.mChannelLayoutTag = g_LayoutMap[(PCMLayout)g_guiSettings.GetInt("audiooutput.channellayout")]; - - CCoreAudioChannelLayout userLayout(guiLayout); - CStdString strUserLayout; - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: User-Configured Speaker Layout: %s", CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)userLayout, strUserLayout)); - - // Get OS-Configured (Audio MIDI Setup) Speaker Configuration (Channel Layout) - CCoreAudioChannelLayout deviceLayout; - if (!m_AudioDevice.GetPreferredChannelLayout(deviceLayout)) - return false; - - // Detect devices with no Speaker Configuration - bool undefinedLayout = true; - for (UInt32 c = 0; c < deviceLayout.GetChannelCount(); c++) - { - // If this is a known channel, then we can't have an undefined layout - if (deviceLayout.GetChannelLabel(c) != kAudioChannelLabel_Unknown) - { - undefinedLayout = false; - break; - } - } - if (undefinedLayout) - { - AudioChannelLayoutTag newLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap; - if (g_sysinfo.IsAppleTV()) // AppleTV is only Stereo - newLayoutTag = kAudioChannelLayoutTag_Stereo; - else // AppleTV users cannot do this... - { - CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: The selected device (%s) does not have a speaker layout configured. Using the default layout.", m_AudioDevice.GetName()); - CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: \tPlease go to Applications -> Utilities -> Audio MIDI Setup, and select 'Configure Speakers...'"); - - // Pick a default layout based on the number of channels - newLayoutTag = GetDefaultLayout(deviceLayout.GetChannelCount()); - if (newLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) // Undefined, give up... - { - CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: Unable to find a suitable default layout for this device."); - return false; - } - } - if (!deviceLayout.SetLayout(newLayoutTag)) - { - CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: Unable to set channel layout from tag."); - return false; - } - } - - CStdString strOutLayout; - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: Output Device Layout: %s", CCoreAudioChannelLayout::ChannelLayoutToString(*(AudioChannelLayout*)deviceLayout, strOutLayout)); - - // TODO: - // Reconcile the OS and GUI layout configurations. Clamp to the minimum number of speakers - // For each OS-defined output, see if it exists in the GUI configuration - // If it does, add it to the 'union' layout (bitmap?) - // User may have configured 5.1 in GUI, but only 2.0 in OS - // Resulting layout would be {FL, FR} - // User may have configured 2.0 in GUI, and 5.1 in OS - // Resulting layout would be {FL, FR} - - // Correct any configuration incompatibilities - // if (CCoreAudioChannelLayout::GetChannelCountForLayout(guiLayout) < CCoreAudioChannelLayout::GetChannelCountForLayout(deviceLayout)) - // deviceLayout.CopyLayout(guiLayout); - - // TODO: Skip matrix mixer if input/output are compatible -> Add a IsPurePassthrough() method to the CCoreAudioMixMap class - - AudioChannelLayout* layoutCandidates[] = {(AudioChannelLayout*)deviceLayout, (AudioChannelLayout*)userLayout, NULL}; - - // Try to construct a mapping matrix for the mixer. Work through the layout candidates and see if any will work - CCoreAudioMixMap mixMap; - for(AudioChannelLayout** pLayout = layoutCandidates; *pLayout != NULL; pLayout++) - { - mixMap.Rebuild(*sourceLayout, **pLayout); - if (mixMap.IsValid()) - break; - } - - if (mixMap.IsValid()) - { - if (!m_AUConverter.Open(kAudioUnitType_FormatConverter, kAudioUnitSubType_AUConverter, kAudioUnitManufacturer_Apple) || - !m_AUConverter.SetInputFormat(&inputFormat)) - return false; - - // Audio units use noninterleaved 32-bit floating point linear PCM data for input and output, - // ...except in the case of an audio unit that is a data format converter, which converts to or from this format. - AudioStreamBasicDescription fmt; - fmt.mFormatID = kAudioFormatLinearPCM; - fmt.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved; - fmt.mBitsPerChannel = sizeof(Float32)<<3; - fmt.mSampleRate = (Float64)samplesPerSecond; - fmt.mFramesPerPacket = 1; - fmt.mChannelsPerFrame = inputFormat.mChannelsPerFrame; - fmt.mBytesPerFrame = sizeof(Float32); - fmt.mBytesPerPacket = sizeof(Float32); - - // Set-up the format converter - if (!m_AUConverter.SetOutputFormat(&fmt) || - !m_AUConverter.SetInputSource(this) || // Converter's data comes from the renderer - !m_AUConverter.Initialize()) - return false; - - // Set-up the mixer input - if (!m_MixerUnit.Open() || // Create the MatrixMixer AudioUnit Component to handle up/down mix) - !m_MixerUnit.SetInputBusCount(1) || // Configure the mixer - !m_MixerUnit.SetOutputBusCount(1) || - !m_MixerUnit.SetInputFormat(&fmt)) // Same input format as the outpur from the converter - return false; - - // Update format structure to reflect the desired format from the mixer - fmt.mChannelsPerFrame = mixMap.GetOutputChannels(); // The output format of the mixer is identical to the input format, except for the channel count - - // Set-up the mixer output - if (!m_MixerUnit.SetOutputFormat(&fmt) || - !m_MixerUnit.SetInputSource(&m_AUConverter) || // The mixer gets its data from the converter - !m_MixerUnit.Initialize()) - return false; - - // Configure the mixing matrix - Float32* val = (Float32*)mixMap; - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: Loading matrix mixer configuration"); - for (UInt32 i = 0; i < inputFormat.mChannelsPerFrame; ++i) - { - for (UInt32 j = 0; j < fmt.mChannelsPerFrame; ++j) - { - AudioUnitSetParameter(m_MixerUnit.GetComponent(), - kMatrixMixerParam_Volume, kAudioUnitScope_Global, (i<<16) | j, *val++, 0); - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: \t[%d][%d][%0.1f]", - (int)i, (int)j, *(val-1)); - } - } - - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::InitializePCM: " - "Mixer Output Format: %d channels, %0.1f kHz, %d bits, %d bytes per frame", - (int)fmt.mChannelsPerFrame, fmt.mSampleRate / 1000.0f, (int)fmt.mBitsPerChannel, (int)fmt.mBytesPerFrame); - - // only enable the compressor if not playing music - if (!m_init_state.bIsMusic) - { - // Set-up the compander - if (!m_AUCompressor.Open() || - !m_AUCompressor.SetOutputFormat(&fmt) || - !m_AUCompressor.SetInputFormat(&fmt) || - !m_AUCompressor.SetInputSource(&m_MixerUnit) || // The compressor gets its data from the mixer - !m_AUCompressor.Initialize()) - return false; - - // Configure compander parameters - m_AUCompressor.SetAttackTime(g_advancedSettings.m_limiterHold); - m_AUCompressor.SetReleaseTime(g_advancedSettings.m_limiterRelease); - } - - // Copy format for the Output AU - outputFormat = fmt; - } - else - { - CLog::Log(LOGERROR, "CCoreAudioRenderer::InitializePCM: No matrix mixer configuration available - unmapped channels will be dropped"); - outputFormat = inputFormat; // We don't know how to map this...let CoreAudio handle it - } - } - else - { - if (allowMixing && !channelMap) - CLog::Log(LOGINFO, "CCoreAudioRenderer::InitializePCM: No channel map provided - extra channels will be dropped"); - outputFormat = inputFormat; - } - - if (!m_AUOutput.SetInputFormat(&outputFormat)) - return false; - - m_BytesPerFrame = inputFormat.mBytesPerFrame; - m_AvgBytesPerSec = inputFormat.mSampleRate * inputFormat.mBytesPerFrame; // 1 sample per channel per frame - m_EnableVolumeControl = true; - - return true; -} - -bool CCoreAudioRenderer::InitializePCMEncoded(UInt32 sampleRate) -{ - m_AudioDevice.SetHogStatus(true); // Prevent any other application from using this device. - m_AudioDevice.SetMixingSupport(false); // Try to disable mixing support. Effectiveness depends on the device. - - // Set the Sample Rate as defined by the spec. - m_AudioDevice.SetNominalSampleRate((float)sampleRate); - - if (!InitializePCM(2, sampleRate, 16, NULL, false)) - return false; - - m_EnableVolumeControl = false; // Prevent attempts to change the output volume. It is not possible with encoded audio - return true; -} - -bool CCoreAudioRenderer::InitializeEncoded(AudioDeviceID outputDevice, UInt32 sampleRate) -{ - //return false; // un-comment to force PCM Spoofing (DD-Wav). For testing use only. - - CStdString formatString; - AudioStreamBasicDescription outputFormat = {0}; - AudioStreamID outputStream = 0; - - // Fetch a list of the streams defined by the output device - AudioStreamIdList streams; - UInt32 streamIndex = 0; - m_AudioDevice.GetStreams(&streams); - - while (!streams.empty()) - { - // Get the next stream - CCoreAudioStream stream; - stream.Open(streams.front()); - streams.pop_front(); // We copied it, now we are done with it - - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: " - "Found %s stream - id: 0x%04X, Terminal Type: 0x%04lX", - stream.GetDirection() ? "Input" : "Output", - (int)stream.GetId(), - stream.GetTerminalType()); - - // Probe physical formats - StreamFormatList physicalFormats; - stream.GetAvailablePhysicalFormats(&physicalFormats); - while (!physicalFormats.empty()) - { - AudioStreamRangedDescription& desc = physicalFormats.front(); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: Considering Physical Format: %s", StreamDescriptionToString(desc.mFormat, formatString)); - if (desc.mFormat.mFormatID == kAudioFormat60958AC3 && desc.mFormat.mSampleRate == sampleRate) - { - outputFormat = desc.mFormat; // Select this format - m_OutputBufferIndex = streamIndex; // TODO: Is this technically correct? Will each stream have it's own IOProc buffer? - outputStream = stream.GetId(); - break; - } - physicalFormats.pop_front(); - } - - // TODO: How do we determine if this is the right stream (not just the right format) to use? - if (outputFormat.mFormatID) - break; // We found a suitable format. No need to continue. - streamIndex++; - } - - if (!outputFormat.mFormatID) // No match found - { - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: Unable to identify suitable output format."); - return false; - } - - m_ChunkLen = outputFormat.mBytesPerPacket; // 1 Chunk == 1 Packet - m_AvgBytesPerSec = outputFormat.mChannelsPerFrame * (outputFormat.mBitsPerChannel>>3) * outputFormat.mSampleRate; // mBytesPerFrame is 0 for a cac3 stream - m_BytesPerFrame = outputFormat.mChannelsPerFrame * (outputFormat.mBitsPerChannel>>3); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: Selected stream[%lu] - id: 0x%04lX, Physical Format: %s (%lu Bytes/sec.)", streamIndex, outputStream, StreamDescriptionToString(outputFormat, formatString), m_AvgBytesPerSec); - - // TODO: Auto hogging sets this for us. Figure out how/when to turn it off or use it - // It appears that leaving this set will aslo restore the previous stream format when the - // Application exits. If auto hogging is set and we try to set hog mode, we will deadlock - // From the SDK docs: "If the AudioDevice is in a non-mixable mode, the HAL will automatically take hog mode on behalf of the first process to start an IOProc." - - // Lock down the device. This MUST be done PRIOR to switching to a non-mixable format, if it is done at all - // If it is attempted after the format change, there is a high likelihood of a deadlock - // We may need to do this sooner to enable mix-disable (i.e. before setting the stream format) - - CCoreAudioHardware::SetAutoHogMode(false); // Auto-Hog does not always un-hog the device when changing back to a mixable mode. Handle this on our own until it is fixed. - bool autoHog = CCoreAudioHardware::GetAutoHogMode(); - CLog::Log(LOGDEBUG, " CoreAudioRenderer::InitializeEncoded: Auto 'hog' mode is set to '%s'.", autoHog ? "On" : "Off"); - if (!autoHog) // Try to handle this ourselves - { - m_AudioDevice.SetHogStatus(true); // Hog the device if it is not set to be done automatically - m_AudioDevice.SetMixingSupport(false); // Try to disable mixing. If we cannot, it may not be a problem - } - m_NumLatencyFrames = m_AudioDevice.GetNumLatencyFrames(); - - // Configure the output stream object - m_OutputStream.Open(outputStream); // This is the one we will keep - AudioStreamBasicDescription virtualFormat; - m_OutputStream.GetVirtualFormat(&virtualFormat); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: Previous Virtual Format: %s (%lu Bytes/sec.)", StreamDescriptionToString(virtualFormat, formatString), m_AvgBytesPerSec); - AudioStreamBasicDescription previousPhysicalFormat; - m_OutputStream.GetPhysicalFormat(&previousPhysicalFormat); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: Previous Physical Format: %s (%lu Bytes/sec.)", StreamDescriptionToString(previousPhysicalFormat, formatString), m_AvgBytesPerSec); - m_OutputStream.SetPhysicalFormat(&outputFormat); // Set the active format (the old one will be reverted when we close) - m_NumLatencyFrames += m_OutputStream.GetNumLatencyFrames(); - m_OutputStream.GetVirtualFormat(&virtualFormat); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: New Virtual Format: %s (%lu Bytes/sec.)", StreamDescriptionToString(virtualFormat, formatString), m_AvgBytesPerSec); - CLog::Log(LOGDEBUG, "CoreAudioRenderer::InitializeEncoded: New Physical Format: %s (%lu Bytes/sec.)", StreamDescriptionToString(outputFormat, formatString), m_AvgBytesPerSec); - - // Register for data request callbacks from the driver - m_AudioDevice.AddIOProc(DirectRenderCallback, this); - - m_EnableVolumeControl = false; // Prevent attempts to change the output volume. It is not possible with encoded audio - return true; -} - -OSStatus CCoreAudioRenderer::HardwareListenerProc(AudioHardwarePropertyID property, void *clientref) -{ - //CCoreAudioRenderer *m = (CCoreAudioRenderer*)clientref; - switch(property) - { - case kAudioHardwarePropertyDevices: - // An audio device has been added/removed to the system - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::HardwareListenerProc:kAudioHardwarePropertyDevices"); - break; - case kAudioHardwarePropertyIsInitingOrExiting: - // HAL is either initializing or exiting the process. - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::HardwareListenerProc:kAudioHardwarePropertyIsInitingOrExiting"); - break; - case kAudioHardwarePropertyDefaultOutputDevice: - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::HardwareListenerProc:kAudioHardwarePropertyDefaultOutputDevice"); - break; - default: - break; - } - - return noErr; -} - -OSStatus CCoreAudioRenderer::DeviceListenerProc(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *clientref) -{ - //CCoreAudioRenderer *m = (CCoreAudioRenderer*)clientref; - switch(inPropertyID) - { - case kAudioDevicePropertyDeviceIsAlive: - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::DeviceListenerProc:kAudioDevicePropertyDeviceIsAlive"); - break; - case kAudioDevicePropertyDeviceIsRunning: - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::DeviceListenerProc:kAudioDevicePropertyDeviceIsRunning, " - "inDevice(0x%x), inChannel(%d), inDevice(%d)", inDevice, inChannel, isInput); - break; - case kAudioDevicePropertyStreamConfiguration: - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::DeviceListenerProc:kAudioDevicePropertyStreamConfiguration, " - "inDevice(0x%x), inChannel(%d), inDevice(%d)", inDevice, inChannel, isInput); - break; - default: - break; - } - return noErr; -} - -void CCoreAudioRenderer::OnLostDevice() -{ - if (g_guiSettings.GetBool("videoplayer.adjustrefreshrate")) - { - CStdString deviceName; - m_AudioDevice.GetName(deviceName); - if (deviceName.Equals("HDMI")) - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::OnLostDevice"); - } -} - -void CCoreAudioRenderer::OnResetDevice() -{ - if (g_guiSettings.GetBool("videoplayer.adjustrefreshrate")) - { - CStdString deviceName; - m_AudioDevice.GetName(deviceName); - if (deviceName.Equals("HDMI")) - { - Reinitialize(); - CLog::Log(LOGDEBUG, "CCoreAudioRenderer::OnResetDevice"); - } - } -} - -AudioChannelLayoutTag CCoreAudioRenderer::GetDefaultLayout(UInt32 channelCount) -{ - switch(channelCount) - { - case 1: - return kAudioChannelLayoutTag_Mono; // 1.0 - case 2: - return kAudioChannelLayoutTag_Stereo; // 2.0 - case 3: - return kAudioChannelLayoutTag_DVD_4; // 2.1 - case 4: - return kAudioChannelLayoutTag_DVD_10; // 3.1 - case 5: - return kAudioChannelLayoutTag_DVD_6; // 4.1 - case 6: - return kAudioChannelLayoutTag_MPEG_5_1_A; // 5.1 - case 7: - return kAudioChannelLayoutTag_AudioUnit_7_0; // 7.0 - case 8: - return kAudioChannelLayoutTag_MPEG_7_1_A; // 7.1 - case 0: - default: - return kAudioChannelLayoutTag_UseChannelBitmap; // Basically 'Undefined' - } -} - -#endif -#endif - diff --git a/xbmc/cores/AudioRenderers/CoreAudioRenderer.h b/xbmc/cores/AudioRenderers/CoreAudioRenderer.h deleted file mode 100644 index 3b06a518fb..0000000000 --- a/xbmc/cores/AudioRenderers/CoreAudioRenderer.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2005-2011 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ -#ifndef __COREAUDIO_RENDERER_H__ -#define __COREAUDIO_RENDERER_H__ - -#if !defined(__arm__) -#include <osx/CoreAudio.h> -#include "IAudioRenderer.h" -#include "threads/Event.h" -#include "threads/LockFree.h" -#include "guilib/DispResource.h" - -struct audio_slice -{ - struct _tag_header{ - uint64_t timestamp; // Currently not used - size_t data_len; - } header; - unsigned int data[1]; - unsigned char* get_data() {return (unsigned char*)&data;} -}; - -class CAtomicAllocator -{ -public: - CAtomicAllocator(size_t blockSize); - ~CAtomicAllocator(); - void* Alloc(); - void Free(void* p); - size_t GetBlockSize(); -private: - lf_heap m_Heap ; - size_t m_BlockSize; -}; - -class CSliceQueue -{ -public: - CSliceQueue(size_t sliceSize); - virtual ~CSliceQueue(); - size_t AddData(void* pBuf, size_t bufLen); - size_t GetData(void* pBuf, size_t bufLen); - size_t GetTotalBytes(); - void Clear(); -protected: - void Push(audio_slice* pSlice); - audio_slice* Pop(); // Does not respect remainder, so it must be private - CAtomicAllocator* m_pAllocator; - lf_queue m_Queue; - size_t m_TotalBytes; - audio_slice* m_pPartialSlice; - size_t m_RemainderSize; -}; - -class CCoreAudioPerformance -{ -public: - CCoreAudioPerformance(); - ~CCoreAudioPerformance(); - void Init(UInt32 expectedBytesPerSec, UInt32 watchdogInterval = 1000, UInt32 flags = 0); - void ReportData(UInt32 bytesIn, UInt32 bytesOut); - void EnableWatchdog(bool enable); - void SetPreroll(UInt32 bytes); // Fixed bytes - void SetPreroll(float seconds); // Calculated for time (seconds) - void Reset(); - enum - { - FlagDefault = 0 - }; -protected: - UInt64 m_TotalBytesIn; - UInt64 m_TotalBytesOut; - UInt32 m_ExpectedBytesPerSec; - UInt32 m_ActualBytesPerSec; - UInt32 m_Flags; - bool m_WatchdogEnable; - UInt32 m_WatchdogInterval; - UInt32 m_LastWatchdogCheck; - UInt32 m_LastWatchdogBytesIn; - UInt32 m_LastWatchdogBytesOut; - float m_WatchdogBitrateSensitivity; - UInt32 m_WatchdogPreroll; -}; - -class CCoreAudioMixMap -{ -public: - CCoreAudioMixMap(); - CCoreAudioMixMap(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit=false); - virtual ~CCoreAudioMixMap(); - operator Float32*() const {return m_pMap;} - const Float32* GetBuffer() {return m_pMap;} - UInt32 GetInputChannels() {return m_inChannels;} - UInt32 GetOutputChannels() {return m_outChannels;} - bool IsValid() {return m_isValid;} - void Rebuild(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout, bool forceExplicit=false); -private: - bool BuildExplicit(AudioChannelLayout& inLayout, AudioChannelLayout& outLayout); - Float32* m_pMap; - UInt32 m_inChannels; - UInt32 m_outChannels; - bool m_isValid; -}; - -class CCoreAudioRenderer : public IAudioRenderer, public ICoreAudioSource, public IDispResource -{ -public: - CCoreAudioRenderer(); - virtual ~CCoreAudioRenderer(); - virtual unsigned int GetChunkLen(); - virtual float GetDelay(); - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = IAudioRenderer::ENCODED_NONE); - virtual bool Deinitialize(); - bool Reinitialize(); - virtual unsigned int AddPackets(const void* data, unsigned int len); - virtual unsigned int GetSpace(); - virtual float GetCacheTime(); - virtual float GetCacheTotal(); - virtual bool Pause(); - virtual bool Stop(); - virtual bool Resume(); - - virtual long GetCurrentVolume() const; - virtual void Mute(bool bMute); - virtual bool SetCurrentVolume(long nVolume); - virtual void WaitCompletion(); - - virtual void SetDynamicRangeCompression(long drc); - - // Unimplemented IAudioRenderer methods - virtual int SetPlaySpeed(int iSpeed) {return 0;}; - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) {}; - virtual void UnRegisterAudioCallback() {}; - virtual void RegisterAudioCallback(IAudioCallback* pCallback) {}; - - static void EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough) {}; - - // AudioUnit Rendering Connection Point (called by down-stream sinks) - virtual OSStatus Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList); - - virtual void OnLostDevice(); - virtual void OnResetDevice(); -private: - OSStatus OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - static OSStatus DirectRenderCallback(AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData); - bool InitializeEncoded(AudioDeviceID outputDevice, UInt32 sampleRate); - bool InitializePCM(UInt32 channels, UInt32 samplesPerSecond, UInt32 bitsPerSample, enum PCMChannels *channelMap, bool allowMixing = true); - bool InitializePCMEncoded(UInt32 sampleRate); - - AudioChannelLayoutTag GetDefaultLayout(UInt32 channelCount); - static OSStatus HardwareListenerProc(AudioHardwarePropertyID property, void *clientref); - static OSStatus DeviceListenerProc(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *clientref); - - bool m_Pause; - bool m_Initialized; // Prevent multiple init/deinit - - long m_CurrentVolume; // Courtesy of the jerk that made GetCurrentVolume a const... - unsigned int m_ChunkLen; // Minimum amount of data accepted by AddPackets - // char* m_RemapBuffer; // Temporary buffer for channel remapping - CSliceQueue* m_pCache; - size_t m_MaxCacheLen; // Maximum number of bytes to be cached by the renderer. - - CAUOutputDevice m_AUOutput; - CAUMatrixMixer m_MixerUnit; - CCoreAudioDevice m_AudioDevice; - CCoreAudioStream m_OutputStream; - UInt32 m_OutputBufferIndex; - - CAUGenericSource m_AUConverter; - CAUDynamicsProcessor m_AUCompressor; - - bool m_Passthrough; - bool m_EnableVolumeControl; - - // Stream format - size_t m_AvgBytesPerSec; - size_t m_BytesPerFrame; // Input frame size - UInt32 m_NumLatencyFrames; - -#ifdef _DEBUG - // Performace Monitoring - CCoreAudioPerformance m_PerfMon; -#endif - // Thread synchronization - CEvent m_RunoutEvent; - long m_DoRunout; - // saved Initialize vars - struct init_state - { - bool reinit; - CStdString device; - int iChannels; - enum PCMChannels *channelMap; - unsigned int uiSamplesPerSec; - unsigned int uiBitsPerSample; - bool bResample; - bool bIsMusic; - EEncoded bPassthrough; - IAudioCallback *pCallback; - }; - CCriticalSection m_init_csection; - init_state m_init_state; - -}; - -#endif -#endif diff --git a/xbmc/cores/AudioRenderers/IAudioRenderer.h b/xbmc/cores/AudioRenderers/IAudioRenderer.h deleted file mode 100644 index e1342fd336..0000000000 --- a/xbmc/cores/AudioRenderers/IAudioRenderer.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -* XBMC Media Center -* Copyright (c) 2002 d7o3g4q and RUNTiME -* Portions Copyright (c) by the authors of ffmpeg and xvid -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -// AsyncAudioRenderer.h: interface for the CAsyncDirectSound class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_IAUDIORENDERER_H__B590A94D_D15E_43A6_A41D_527BD441B5F5__INCLUDED_) -#define AFX_IAUDIORENDERER_H__B590A94D_D15E_43A6_A41D_527BD441B5F5__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "utils/StdString.h" -#include "cores/IAudioCallback.h" -#include "utils/PCMRemap.h" -extern void RegisterAudioCallback(IAudioCallback* pCallback); -extern void UnRegisterAudioCallback(); - -typedef std::pair<CStdString, CStdString> AudioSink; -typedef std::vector<AudioSink> AudioSinkList; - -class IAudioRenderer -{ -public: - enum EEncoded { - ENCODED_NONE = 0, - ENCODED_IEC61937_AC3, - ENCODED_IEC61937_EAC3, - ENCODED_IEC61937_DTS, - ENCODED_IEC61937_MPEG, - ENCODED_IEC61937_UNKNOWN, - }; - - IAudioRenderer() {}; - virtual ~IAudioRenderer() {}; - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = ENCODED_NONE) = 0; - virtual void UnRegisterAudioCallback() = 0; - virtual void RegisterAudioCallback(IAudioCallback* pCallback) = 0; - virtual float GetDelay() = 0; - virtual float GetCacheTime() = 0; - virtual float GetCacheTotal() { return 1.0f; } - - virtual unsigned int AddPackets(const void* data, unsigned int len) = 0; - virtual bool IsResampling() { return false;}; - virtual unsigned int GetSpace() = 0; - virtual bool Deinitialize() = 0; - virtual bool Pause() = 0; - virtual bool Stop() = 0; - virtual bool Resume() = 0; - virtual unsigned int GetChunkLen() = 0; - - virtual long GetCurrentVolume() const = 0; - virtual void Mute(bool bMute) = 0; - virtual bool SetCurrentVolume(long nVolume) = 0; - virtual void SetDynamicRangeCompression(long drc) {}; - virtual float GetCurrentAttenuation() { return m_remap.GetCurrentAttenuation(); } - virtual int SetPlaySpeed(int iSpeed) = 0; - virtual void WaitCompletion() = 0; - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) = 0; - -protected: - CPCMRemap m_remap; - -private: -}; - -#endif // !defined(AFX_IAUDIORENDERER_H__B590A94D_D15E_43A6_A41D_527BD441B5F5__INCLUDED_) diff --git a/xbmc/cores/AudioRenderers/IOSAudioRenderer.cpp b/xbmc/cores/AudioRenderers/IOSAudioRenderer.cpp deleted file mode 100644 index cb72e67c5e..0000000000 --- a/xbmc/cores/AudioRenderers/IOSAudioRenderer.cpp +++ /dev/null @@ -1,426 +0,0 @@ -#ifdef __APPLE__ -/* - * Copyright (C) 2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "IOSAudioRenderer.h" -#include "IOSAudioRingBuffer.h" -#include "AudioContext.h" -#include "GUISettings.h" -#include "Settings.h" -#include "utils/log.h" - -//*********************************************************************************************** -// Contruction/Destruction -//*********************************************************************************************** -CIOSAudioRenderer::CIOSAudioRenderer() : - m_Pause(false), - m_Initialized(false), - m_CurrentVolume(0), - m_OutputBufferIndex(0), - m_BytesPerSec(0), - m_NumChunks(0), - m_PacketSize(0), - m_Passthrough(false), - m_SamplesPerSec(0), - m_DoRunout(0) -{ - m_Buffer = new IOSAudioRingBuffer(); -} - -CIOSAudioRenderer::~CIOSAudioRenderer() -{ - Deinitialize(); - delete m_Buffer; -} - -//*********************************************************************************************** -// Initialization -//*********************************************************************************************** - -bool CIOSAudioRenderer::Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic /*Useless Legacy Parameter*/, EEncoded bPassthrough) -{ - // Limit to 2.0. It is only used for anloge audio. - static enum PCMChannels IOSChannelMap[2] = - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT}; - - m_Passthrough = bPassthrough; - - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE); - - bool bAudioOnAllSpeakers(false); - g_audioContext.SetupSpeakerConfig(iChannels, bAudioOnAllSpeakers, bIsMusic); - - if(bPassthrough) - { - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE_DIGITAL); - } else { - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE); - } - - m_DataChannels = iChannels; - m_remap.Reset(); - - if (!m_Passthrough && channelMap) - { - enum PCMChannels *outLayout; - - /* set the input format, and get the channel layout so we know what we need to open */ - outLayout = m_remap.SetInputFormat (iChannels, channelMap, uiBitsPerSample / 8, uiSamplesPerSec); - unsigned int outChannels = 0; - unsigned int ch = 0, map; - while(outLayout[ch] != PCM_INVALID) - { - for(map = 0; map < 8; ++map) - { - if (outLayout[ch] == IOSChannelMap[map]) - { - if (map > outChannels) - outChannels = map; - break; - } - } - ++ch; - } - - m_remap.SetOutputFormat(++outChannels, IOSChannelMap); - if (m_remap.CanRemap()) - { - iChannels = outChannels; - if (m_DataChannels != (unsigned int)iChannels) - CLog::Log(LOGDEBUG, "CIOSAudioRenderer::InitializePCM: Requested channels changed from %i to %i", m_DataChannels, iChannels); - } - - } - - m_Channels = iChannels; - - // Set the input stream format for the AudioUnit - // We use the default DefaultOuput AudioUnit, so we only can set the input stream format. - // The autput format is automaticaly set to the input format. - AudioStreamBasicDescription audioFormat; - audioFormat.mFormatID = kAudioFormatLinearPCM; // Data encoding format - - audioFormat.mFormatFlags = kAudioFormatFlagsCanonical; - audioFormat.mChannelsPerFrame = iChannels; // Number of interleaved audiochannels - audioFormat.mSampleRate = (Float64)uiSamplesPerSec; // the sample rate of the audio stream - audioFormat.mBitsPerChannel = uiBitsPerSample; // Number of bits per sample, per channel - audioFormat.mBytesPerFrame = (uiBitsPerSample>>3) * iChannels; // Size of a frame == 1 sample per channel - audioFormat.mFramesPerPacket = 1; // The smallest amount of indivisible data. Always 1 for uncompressed audio - audioFormat.mBytesPerPacket = audioFormat.mBytesPerFrame * audioFormat.mFramesPerPacket; - audioFormat.mReserved = 0; - - // Attach our output object to the device - if(!m_AudioDevice.Init(/*m_Passthrough*/ true, &audioFormat, RenderCallback, this)) - { - CLog::Log(LOGDEBUG, "CIOSAudioRenderer::Init failed"); - return false; - } - - m_PacketSize = iChannels * (uiBitsPerSample / 8) * 512; - - m_BufferFrames = m_AudioDevice.FramesPerSlice(m_PacketSize); - if(!m_BufferFrames) - { - CLog::Log(LOGDEBUG, "CIOSAudioRenderer::FramesPerSlice bufferFrames == 0\n"); - //return false; - } - - m_BytesPerFrame = audioFormat.mBytesPerFrame; - m_BitsPerChannel = audioFormat.mBitsPerChannel; - m_BytesPerSec = uiSamplesPerSec * (uiBitsPerSample / 8) * iChannels; - m_SamplesPerSec = uiSamplesPerSec; - m_BufferLen = m_PacketSize * 96; - if(m_BufferLen < m_PacketSize || m_BufferLen == 0) - m_BufferLen = m_PacketSize; - - bool success = m_Buffer->Create(m_BufferLen); - if(!success || !m_BufferLen) - { - CLog::Log(LOGDEBUG, "CIOSAudioRenderer::Initialize: Error allocation audio buffer size %d.", m_BufferLen); - return false; - } - - m_EnableVolumeControl = true; - - /* - if (!m_AudioDevice.SetSessionListener(kAudioSessionProperty_AudioRouteChange, PropertyChangeCallback, this)) - return false; - */ - - // Start the audio device - if (!m_AudioDevice.Open()) - return false; - - // Suspend rendering. We will start once we have some data. - m_Pause = true; - m_Initialized = true; - - CLog::Log(LOGDEBUG, "CIOSAudioRenderer::Initialize: Renderer Configuration - Chunk Len: %u, Max Cache: %u (%0.0fms).", m_PacketSize, m_BufferLen, 1000.0 *(float)m_BufferLen/(float)m_BytesPerSec); - CLog::Log(LOGINFO, "CIOSAudioRenderer::Initialize: Successfully configured audio output."); - - m_DoRunout = 0; - - m_drc = 0; - - return true; -} - -bool CIOSAudioRenderer::Deinitialize() -{ - - if(m_Initialized) - WaitCompletion(); - - // Stop rendering - Stop(); - - Sleep(10); - m_AudioDevice.Close(); - m_Initialized = false; - m_BytesPerSec = 0; - m_BufferLen = 0; - m_NumChunks = 0; - m_PacketSize = 0; - m_SamplesPerSec = 0; - m_DoRunout = 0; - - CLog::Log(LOGINFO, "CIOSAudioRenderer::Deinitialize: Renderer has been shut down."); - - return true; -} - -void CIOSAudioRenderer::Flush() -{ - Pause(); - - // IOSAudioRingBuffer::Reset is not threadsafe but we have - // paused here so renderer is not reading from m_Buffer and - // we can reset with confidence. - m_Buffer->Reset(); -} - -//*********************************************************************************************** -// Transport control methods -//*********************************************************************************************** -bool CIOSAudioRenderer::Pause() -{ - if (!m_Pause) - { - m_AudioDevice.Stop(); - m_Pause = true; - } - return true; -} - -bool CIOSAudioRenderer::Resume() -{ - if (m_Pause) - { - m_AudioDevice.Start(); - m_Pause = false; - } - return true; -} - -bool CIOSAudioRenderer::Stop() -{ - m_AudioDevice.Stop(); - - m_Pause = true; - - Flush(); - return true; -} - -//*********************************************************************************************** -// Volume control methods -//*********************************************************************************************** -LONG CIOSAudioRenderer::GetCurrentVolume() const -{ - return m_CurrentVolume; -} - -void CIOSAudioRenderer::Mute(bool bMute) -{ -} - -bool CIOSAudioRenderer::SetCurrentVolume(LONG nVolume) -{ - return true; -} - -//*********************************************************************************************** -// Data management methods -//*********************************************************************************************** -unsigned int CIOSAudioRenderer::GetSpace() -{ - int free = m_Buffer->GetWriteSize(); - return (free / m_Channels) * m_DataChannels; -} - -unsigned int CIOSAudioRenderer::AddPackets(const void* data, DWORD len) -{ - int status; - - // call channel remapping routine if available and required - if (m_remap.CanRemap() && !m_Passthrough) - { - int length, frames; - - // we might be up or down converting, so convert to number of bytes - // that we will get out of remapping the channels and see if that fits. - length = (len / m_DataChannels) * m_Channels; - if (length > GetSpace()) - return 0; - - // check buffer fit, we can only accept unit frames, so if less than - // a complete frame, we punt. - frames = length / m_Channels / (m_BitsPerChannel >> 3); - if (frames == 0) - { - CLog::Log(LOGINFO, "IOSAudioRenderer::AddPackets() - Need complete frame."); - return 0; - } - - uint8_t outData[length]; - // remap the audio channels using the frame count - m_remap.Remap((void*)data, outData, frames, m_drc); - - status = m_Buffer->Write(outData, length); - // return the number of input bytes we accepted - len = (length / m_Channels) * m_DataChannels; - } - else - { - // simple case, not remaping or passthough, only have to check - // that we have free space in our buffer. - status = m_Buffer->Write((unsigned char *)data, len); - } - - Resume(); - //only return the length if buffer accepted the data - return status == 0 ? len : 0; -} - -float CIOSAudioRenderer::GetDelay() -{ - return (float)m_Buffer->GetReadSize() / (float)m_BytesPerSec; -} - -float CIOSAudioRenderer::GetCacheTime() -{ - unsigned int nBufferLenFull = (m_BufferLen / m_Channels) * m_DataChannels; - return (float)(nBufferLenFull - GetSpace()) / (float)m_BytesPerSec; -} - -float CIOSAudioRenderer::GetCacheTotal() -{ - return (float)m_BufferLen / (float)m_BytesPerSec; -} - -unsigned int CIOSAudioRenderer::GetChunkLen() -{ - return (m_PacketSize / m_Channels) * m_DataChannels; -} - -void CIOSAudioRenderer::WaitCompletion() -{ - // we don't lock here as we are just checking for zero or non-zero. - - // The cache is already empty. There is nothing to wait for. - if (m_Buffer->GetReadSize() == 0) - return; - - m_DoRunout = 1; - - UInt32 delay = (UInt32)(GetDelay() * 1000.0f) + 10; - if (!delay) - { - bool ret = m_RunoutEvent.WaitMSec(delay); - if (!ret && m_Buffer->GetReadSize() ) - { - //See if there is still some data left in the cache that didn't get played - CLog::Log(LOGERROR, "CIOSAudioRenderer::WaitCompletion: Timed-out waiting for runout. Remaining data will be truncated."); - } - } - - Stop(); -} - -//*********************************************************************************************** -// Rendering Methods -//*********************************************************************************************** -OSStatus CIOSAudioRenderer::OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - if (!m_Initialized) - { - CLog::Log(LOGERROR, "CIOSAudioRenderer::OnRender: Callback to de/unitialized renderer."); - ioData->mBuffers[m_OutputBufferIndex].mDataByteSize = 0; - return noErr; - } - - if(m_Pause) - { - ioData->mBuffers[m_OutputBufferIndex].mDataByteSize = 0; - return noErr; - } - - UInt32 bytesRead = m_Buffer->GetReadSize(); - UInt32 bytesRequested = inNumberFrames * m_BytesPerFrame; - - if (bytesRead < bytesRequested) - { - m_RunoutEvent.Set(); // Tell anyone who cares that the cache is empty - if (m_DoRunout) // We were waiting for a runout. This is not an error. - { - m_DoRunout = 0; - } - ioData->mBuffers[m_OutputBufferIndex].mDataByteSize = 0; - return noErr; - } - - m_Buffer->Read((unsigned char *)ioData->mBuffers[m_OutputBufferIndex].mData, bytesRequested); - - if (!m_EnableVolumeControl && m_CurrentVolume <= VOLUME_MINIMUM) - ioData->mBuffers[m_OutputBufferIndex].mDataByteSize = 0; - else - ioData->mBuffers[m_OutputBufferIndex].mDataByteSize = bytesRequested; - - return noErr; -} - -OSStatus CIOSAudioRenderer::RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - return ((CIOSAudioRenderer*)inRefCon)->OnRender(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); -} - -// Static Callback from AudioUnit -void CIOSAudioRenderer::PropertyChanged(AudioSessionPropertyID inID, UInt32 inDataSize, const void* inPropertyValue) -{ - CLog::Log(LOGERROR, "CIOSAudioRenderer::PropertyChanged: inID %d.", (int)inID); -} - -void CIOSAudioRenderer::PropertyChangeCallback(void* inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void* inPropertyValue) -{ - ((CIOSAudioRenderer*)inClientData)->PropertyChanged(inID, inDataSize, inPropertyValue); -} - -#endif diff --git a/xbmc/cores/AudioRenderers/IOSAudioRenderer.h b/xbmc/cores/AudioRenderers/IOSAudioRenderer.h deleted file mode 100644 index 5b4b0729f0..0000000000 --- a/xbmc/cores/AudioRenderers/IOSAudioRenderer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef __IOSAUDIO_RENDERER_H__ -#define __IOSAUDIO_RENDERER_H__ - -#include "IOSCoreAudio.h" -#include "PlatformDefs.h" -#include "IAudioRenderer.h" -#include "threads/Event.h" - -class IOSAudioRingBuffer; -class CIOSAudioRenderer : public IAudioRenderer - { - public: - CIOSAudioRenderer(); - virtual ~CIOSAudioRenderer(); - virtual unsigned int GetChunkLen(); - virtual float GetDelay(); - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = IAudioRenderer::ENCODED_NONE); - virtual bool Deinitialize(); - virtual void Flush(); - virtual unsigned int AddPackets(const void* data, unsigned int len); - virtual unsigned int GetSpace(); - virtual float GetCacheTime(); - virtual float GetCacheTotal(); - virtual bool Pause(); - virtual bool Stop(); - virtual bool Resume(); - - virtual long GetCurrentVolume() const; - virtual void Mute(bool bMute); - virtual bool SetCurrentVolume(long nVolume); - virtual void SetDynamicRangeCompression(long drc) { m_drc = drc; } - virtual void WaitCompletion(); - - // Unimplemented IAudioRenderer methods - virtual int SetPlaySpeed(int iSpeed) {return 0;}; - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) {}; - virtual void UnRegisterAudioCallback() {}; - virtual void RegisterAudioCallback(IAudioCallback* pCallback) {}; - - static void EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough) {}; - private: - OSStatus OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - static OSStatus RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - static void PropertyChanged(AudioSessionPropertyID inID, UInt32 inDataSize, const void* inPropertyValue); - static void PropertyChangeCallback(void* inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void* inPropertyValue); - bool InitializePCM(UInt32 channels, UInt32 samplesPerSecond, UInt32 bitsPerSample, enum PCMChannels *channelMap); - - bool m_Pause; - bool m_Initialized; // Prevent multiple init/deinit - - long m_CurrentVolume; // Courtesy of the jerk that made GetCurrentVolume a const... - bool m_EnableVolumeControl; - - CIOSCoreAudioDevice m_AudioDevice; - UInt32 m_OutputBufferIndex; - - // Stream format - int m_BitsPerChannel; - int m_ChannelsPerFrame; - - IOSAudioRingBuffer *m_Buffer; - unsigned int m_BytesPerSec; - unsigned int m_BufferLen; ///< must always be num_chunks * chunk_size - unsigned int m_NumChunks; - unsigned int m_PacketSize; - unsigned int m_BytesPerFrame; - unsigned int m_BufferFrames; - unsigned int m_SamplesPerSec; - - CEvent m_RunoutEvent; - long m_DoRunout; - unsigned int m_DataChannels; - unsigned int m_Channels; - bool m_Passthrough; - - long m_drc; - - }; - -#endif diff --git a/xbmc/cores/AudioRenderers/IOSAudioRingBuffer.h b/xbmc/cores/AudioRenderers/IOSAudioRingBuffer.h deleted file mode 100644 index 7e3160cb42..0000000000 --- a/xbmc/cores/AudioRenderers/IOSAudioRingBuffer.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (C) 2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef IOSAUDIORINGBUFFER_H_ -#define IOSAUDIORINGBUFFER_H_ - -#define RING_BUFFER_OK 0; -#define RING_BUFFER_EMPTY 1; -#define RING_BUFFER_FULL 2; -#define RING_BUFFER_NOTAVAILABLE 3; - -//#define RING_BUFFER_DEBUG - -#include "utils/log.h" //CLog -#include <string.h> //memset, memcpy - -/** - * This buffer can be used by one read and one write thread at any one time - * without the risk of data corruption. - * If you intend to call the Reset() method, please use Locks. - * All other operations are thread-safe. - */ -class IOSAudioRingBuffer { - -public: - IOSAudioRingBuffer() : - m_iReadPos(0), - m_iWritePos(0), - m_iRead(0), - m_iWritten(0), - m_iSize(0), - m_Buffer(NULL) - { - } - - IOSAudioRingBuffer(unsigned int size) : - m_iReadPos(0), - m_iWritePos(0), - m_iRead(0), - m_iWritten(0), - m_iSize(0), - m_Buffer(NULL) - { - Create(size); - } - - ~IOSAudioRingBuffer() - { -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer::~IOSAudioRingBuffer: Deleting buffer."); -#endif - delete[] m_Buffer; - } - - /** - * Allocates space for buffer, and sets it's contents to 0. - * - * @return true on success, false otherwise - */ - bool Create(int size) - { - m_Buffer = new unsigned char[ size ]; - if ( m_Buffer ) - { - m_iSize = size; - memset(m_Buffer, 0, m_iSize); - return true; - } - return false; - } - - /** - * Fills the buffer with zeros and resets the pointers. - * This method is not thread-safe, so before using this method - * please acquire a Lock() - */ - void Reset() { -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer::Reset: Buffer reset."); -#endif - m_iWritten = 0; - m_iRead = 0; - m_iReadPos = 0; - m_iWritePos = 0; - } - - /** - * Writes data to buffer. - * Attempt to write more bytes than available results in RING_BUFFER_FULL. - * - * @return RING_BUFFER_OK on success, otherwise an error code - */ - int Write(unsigned char *src, unsigned int size) - { - unsigned int space = GetWriteSize(); - - //do we have enough space for all the data? - if (size > space) { -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer: Not enough space, ignoring data. Requested: %u Available: %u",size, space); -#endif - return RING_BUFFER_FULL; - } - - //no wrapping? - if ( m_iSize > size + m_iWritePos ) - { -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer: Written to: %u size: %u space before: %u\n", m_iWritePos, size, space); -#endif - memcpy(&(m_Buffer[m_iWritePos]), src, size); - m_iWritePos+=size; - } - //need to wrap - else - { - unsigned int first = m_iSize - m_iWritePos; - unsigned int second = size - first; -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer: Written to (split) first: %u second: %u size: %u space before: %u\n", first, second, size, space); -#endif - memcpy(&(m_Buffer[m_iWritePos]), src, first); - memcpy(&(m_Buffer[0]), &src[first], second); - m_iWritePos = second; - } - - //we can increase the write count now - m_iWritten+=size; - return RING_BUFFER_OK; - } - - /** - * Reads data from buffer. - * Attempt to read more bytes than available results in RING_BUFFER_NOTAVAILABLE. - * Reading from empty buffer returns RING_BUFFER_EMPTY - * - * @return RING_BUFFER_OK on success, otherwise an error code - */ - int Read(unsigned char *dest, unsigned int size) - { - unsigned int space = GetReadSize(); - - //want to read more than we have written? - if( space <= 0 ) - { -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer: Can't read from empty buffer."); -#endif - return RING_BUFFER_EMPTY; - } - - //want to read more than we have available - if( size > space ) - { -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer: Can't read %u bytes when we only have %u.", size, space); -#endif - return RING_BUFFER_NOTAVAILABLE; - } - - //no wrapping? - if ( size + m_iReadPos < m_iSize ) - { -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer: Reading from: %u size: %u space before: %u\n", m_iWritePos, size, space); -#endif - memcpy(dest, &(m_Buffer[m_iReadPos]), size); - m_iReadPos+=size; - } - //need to wrap - else - { - unsigned int first = m_iSize - m_iReadPos; - unsigned int second = size - first; -#ifdef RING_BUFFER_DEBUG - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer: Reading from (split) first: %u second: %u size: %u space before: %u\n", first, second, size, space); -#endif - memcpy(dest, &(m_Buffer[m_iReadPos]), first); - memcpy(&dest[first], &(m_Buffer[0]), second); - m_iReadPos = second; - } - //we can increase the read count now - m_iRead+=size; - - return RING_BUFFER_OK; - } - - /** - * Dumps the buffer. - */ - void Dump() - { - unsigned char* bufferContents = new unsigned char[m_iSize + 1]; - for (unsigned int i=0; i<m_iSize; i++) { - if (i >= m_iReadPos && i<m_iWritePos) - bufferContents[i] = m_Buffer[i]; - else - bufferContents[i] = '_'; - } - bufferContents[m_iSize] = '\0'; - CLog::Log(LOGDEBUG, "IOSAudioRingBuffer::Dump()\n%s",bufferContents); - delete[] bufferContents; - } - - /** - * Returns available space for writing to buffer. - * Attempt to write more bytes than available results in RING_BUFFER_FULL. - */ - unsigned int GetWriteSize() - { - return m_iSize - ( m_iWritten - m_iRead ); - } - - /** - * Returns available space for reading from buffer. - * Attempt to read more bytes than available results in RING_BUFFER_EMPTY. - */ - unsigned int GetReadSize() - { - return m_iWritten - m_iRead; - } - - /** - * Returns the buffer size. - */ - unsigned int GetMaxSize() - { - return m_iSize; - } - -private: - unsigned int m_iReadPos; - unsigned int m_iWritePos; - unsigned int m_iRead; - unsigned int m_iWritten; - unsigned int m_iSize; - unsigned char *m_Buffer; -}; -#endif //#define IOSAUDIORINGBUFFER_H_ diff --git a/xbmc/cores/AudioRenderers/Makefile.in b/xbmc/cores/AudioRenderers/Makefile.in deleted file mode 100644 index 61adeb69f6..0000000000 --- a/xbmc/cores/AudioRenderers/Makefile.in +++ /dev/null @@ -1,28 +0,0 @@ -ARCH=@ARCH@ - -ifeq ($(findstring osx,$(ARCH)), osx) -SRCS = \ - NullDirectSound.cpp \ - AudioRendererFactory.cpp \ - CoreAudioRenderer.cpp \ - -else -SRCS = \ - NullDirectSound.cpp \ - AudioRendererFactory.cpp \ - -endif - -ifeq (@USE_ALSA@,1) -SRCS+= ALSADirectSound.cpp -endif - -ifeq (@USE_PULSE@,1) -SRCS+= PulseAudioDirectSound.cpp \ - -endif - -LIB=audiorenderers.a - -include @abs_top_srcdir@/Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/xbmc/cores/AudioRenderers/Makefile.include b/xbmc/cores/AudioRenderers/Makefile.include deleted file mode 100644 index e69de29bb2..0000000000 --- a/xbmc/cores/AudioRenderers/Makefile.include +++ /dev/null diff --git a/xbmc/cores/AudioRenderers/NullDirectSound.cpp b/xbmc/cores/AudioRenderers/NullDirectSound.cpp deleted file mode 100644 index 20e6125b6d..0000000000 --- a/xbmc/cores/AudioRenderers/NullDirectSound.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "threads/SystemClock.h" -#include "NullDirectSound.h" -#include "guilib/AudioContext.h" -#include "guilib/LocalizeStrings.h" -#include "utils/log.h" -#include "utils/TimeUtils.h" -#include "dialogs/GUIDialogKaiToast.h" - -#define BUFFER CHUNKLEN * 20 -#define CHUNKLEN 512 - - -void CNullDirectSound::DoWork() -{ - -} - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// -//*********************************************************************************************** -CNullDirectSound::CNullDirectSound() -{ -} -bool CNullDirectSound::Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, EEncoded encoded) -{ - CLog::Log(LOGERROR,"Creating a Null Audio Renderer, Check your audio settings as this should not happen"); - if (iChannels == 0) - iChannels = 2; - - bool bAudioOnAllSpeakers(false); - g_audioContext.SetupSpeakerConfig(iChannels, bAudioOnAllSpeakers, bIsMusic); - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE); - - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(34402), g_localizeStrings.Get(34403), TOAST_DISPLAY_TIME, false); - m_timePerPacket = 1.0f / (float)(iChannels*(uiBitsPerSample/8) * uiSamplesPerSec); - m_packetsSent = 0; - m_paused = 0; - m_lastUpdate = XbmcThreads::SystemClockMillis(); - return true; -} - -//*********************************************************************************************** -CNullDirectSound::~CNullDirectSound() -{ - Deinitialize(); -} - - -//*********************************************************************************************** -bool CNullDirectSound::Deinitialize() -{ - g_audioContext.SetActiveDevice(CAudioContext::DEFAULT_DEVICE); - return true; -} - -void CNullDirectSound::Flush() -{ - m_lastUpdate = XbmcThreads::SystemClockMillis(); - m_packetsSent = 0; - Pause(); -} - -//*********************************************************************************************** -bool CNullDirectSound::Pause() -{ - m_paused = true; - return true; -} - -//*********************************************************************************************** -bool CNullDirectSound::Resume() -{ - m_paused = false; - return true; -} - -//*********************************************************************************************** -bool CNullDirectSound::Stop() -{ - Flush(); - return true; -} - -//*********************************************************************************************** -long CNullDirectSound::GetCurrentVolume() const -{ - return m_nCurrentVolume; -} - -//*********************************************************************************************** -void CNullDirectSound::Mute(bool bMute) -{ -} - -//*********************************************************************************************** -bool CNullDirectSound::SetCurrentVolume(long nVolume) -{ - m_nCurrentVolume = nVolume; - return true; -} - - -//*********************************************************************************************** -unsigned int CNullDirectSound::GetSpace() -{ - Update(); - - if(BUFFER > m_packetsSent) - return (int)BUFFER - m_packetsSent; - else - return 0; -} - -//*********************************************************************************************** -unsigned int CNullDirectSound::AddPackets(const void* data, unsigned int len) -{ - if (m_paused || GetSpace() == 0) - return 0; - - int add = ( len / GetChunkLen() ) * GetChunkLen(); - m_packetsSent += add; - - return add; -} - -//*********************************************************************************************** -float CNullDirectSound::GetDelay() -{ - Update(); - - return m_timePerPacket * (float)m_packetsSent; -} - -float CNullDirectSound::GetCacheTime() -{ - return GetDelay(); -} - -//*********************************************************************************************** -unsigned int CNullDirectSound::GetChunkLen() -{ - return (int)CHUNKLEN; -} -//*********************************************************************************************** -int CNullDirectSound::SetPlaySpeed(int iSpeed) -{ - return 0; -} - -void CNullDirectSound::RegisterAudioCallback(IAudioCallback *pCallback) -{ -} - -void CNullDirectSound::UnRegisterAudioCallback() -{ -} - -void CNullDirectSound::WaitCompletion() -{ - while(m_packetsSent > 0) - Update(); -} - -void CNullDirectSound::SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) -{ - return ; -} - -void CNullDirectSound::Update() -{ - unsigned int currentTime = XbmcThreads::SystemClockMillis(); - // because of the if clause below it's possible that m_lastUpdate is larger - // than currentTime. We need to handle this. - long deltaTime = (currentTime - m_lastUpdate); // the diff shouldn't overflow - - if (m_paused) - { - m_lastUpdate += deltaTime; - return; - } - - double d = (double)deltaTime / 1000.0f; - - if (currentTime != m_lastUpdate) - { - double i = (d / (double)m_timePerPacket); - m_packetsSent -= (long)i; - if (m_packetsSent < 0) - m_packetsSent = 0; - m_lastUpdate = currentTime; - } -} diff --git a/xbmc/cores/AudioRenderers/NullDirectSound.h b/xbmc/cores/AudioRenderers/NullDirectSound.h deleted file mode 100644 index 7ba91f290e..0000000000 --- a/xbmc/cores/AudioRenderers/NullDirectSound.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef __NULL_DIRECT_SOUND_H__ -#define __NULL_DIRECT_SOUND_H__ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "IAudioRenderer.h" -#include "cores/IAudioCallback.h" - -extern void RegisterAudioCallback(IAudioCallback* pCallback); -extern void UnRegisterAudioCallback(); - -class CNullDirectSound : public IAudioRenderer -{ -public: - virtual void UnRegisterAudioCallback(); - virtual void RegisterAudioCallback(IAudioCallback* pCallback); - virtual unsigned int GetChunkLen(); - virtual float GetDelay(); - virtual float GetCacheTime(); - CNullDirectSound(); - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = IAudioRenderer::ENCODED_NONE); - virtual ~CNullDirectSound(); - - virtual unsigned int AddPackets(const void* data, unsigned int len); - virtual unsigned int GetSpace(); - virtual bool Deinitialize(); - virtual bool Pause(); - virtual bool Stop(); - virtual bool Resume(); - - virtual long GetCurrentVolume() const; - virtual void Mute(bool bMute); - virtual bool SetCurrentVolume(long nVolume); - virtual int SetPlaySpeed(int iSpeed); - virtual void WaitCompletion(); - virtual void DoWork(); - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers); - - virtual void Flush(); -private: - long m_nCurrentVolume; - - float m_timePerPacket; - int m_packetsSent; - bool m_paused; - unsigned int m_lastUpdate; - - void Update(); -}; - -#endif diff --git a/xbmc/cores/AudioRenderers/PulseAudioDirectSound.cpp b/xbmc/cores/AudioRenderers/PulseAudioDirectSound.cpp deleted file mode 100644 index 861270d91c..0000000000 --- a/xbmc/cores/AudioRenderers/PulseAudioDirectSound.cpp +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "system.h" -#ifdef HAS_PULSEAUDIO -#include "PulseAudioDirectSound.h" -#include "guilib/AudioContext.h" -#include "settings/AdvancedSettings.h" -#include "settings/Settings.h" -#include "utils/log.h" -#include "Util.h" -#include "guilib/LocalizeStrings.h" - -static const char *ContextStateToString(pa_context_state s) -{ - switch (s) - { - case PA_CONTEXT_UNCONNECTED: - return "unconnected"; - case PA_CONTEXT_CONNECTING: - return "connecting"; - case PA_CONTEXT_AUTHORIZING: - return "authorizing"; - case PA_CONTEXT_SETTING_NAME: - return "setting name"; - case PA_CONTEXT_READY: - return "ready"; - case PA_CONTEXT_FAILED: - return "failed"; - case PA_CONTEXT_TERMINATED: - return "terminated"; - default: - return "none"; - } -} - -static const char *StreamStateToString(pa_stream_state s) -{ - switch(s) - { - case PA_STREAM_UNCONNECTED: - return "unconnected"; - case PA_STREAM_CREATING: - return "creating"; - case PA_STREAM_READY: - return "ready"; - case PA_STREAM_FAILED: - return "failed"; - case PA_STREAM_TERMINATED: - return "terminated"; - default: - return "none"; - } -} - -/* Static callback functions */ - -static void ContextStateCallback(pa_context *c, void *userdata) -{ - pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata; - switch (pa_context_get_state(c)) - { - case PA_CONTEXT_READY: - case PA_CONTEXT_TERMINATED: - case PA_CONTEXT_UNCONNECTED: - case PA_CONTEXT_CONNECTING: - case PA_CONTEXT_AUTHORIZING: - case PA_CONTEXT_SETTING_NAME: - case PA_CONTEXT_FAILED: - pa_threaded_mainloop_signal(m, 0); - break; - } -} - -static void StreamStateCallback(pa_stream *s, void *userdata) -{ - pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata; - switch (pa_stream_get_state(s)) - { - case PA_STREAM_UNCONNECTED: - case PA_STREAM_CREATING: - case PA_STREAM_READY: - case PA_STREAM_FAILED: - case PA_STREAM_TERMINATED: - pa_threaded_mainloop_signal(m, 0); - break; - } -} - -static void StreamRequestCallback(pa_stream *s, size_t length, void *userdata) -{ - pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata; - pa_threaded_mainloop_signal(m, 0); -} - -static void StreamLatencyUpdateCallback(pa_stream *s, void *userdata) -{ - pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata; - pa_threaded_mainloop_signal(m, 0); -} - -struct SinkInfoStruct -{ - bool passthrough; - AudioSinkList *list; - pa_threaded_mainloop *mainloop; -}; - -static void SinkInfo(pa_context *c, const pa_sink_info *i, int eol, void *userdata) -{ - SinkInfoStruct *sinkStruct = (SinkInfoStruct *)userdata; - - if (i && i->name) - { - bool add = false; - if(sinkStruct->passthrough) - { -#if PA_CHECK_VERSION(1,0,0) - for(int idx = 0; idx < i->n_formats; ++idx) - { - if(!pa_format_info_is_pcm(i->formats[idx])) - { - add = true; - break; - } - } -#endif - } - else - add = true; - - if(add) - { - CStdString desc, sink; - if(sinkStruct->list->size() == 0) - sinkStruct->list->push_back(AudioSink(g_localizeStrings.Get(409) + " (PulseAudio)", "pulse:default@default")); - desc.Format("%s (PulseAudio)", i->description); - sink.Format("pulse:%s@default", i->name); - sinkStruct->list->push_back(AudioSink(desc, sink)); - CLog::Log(LOGDEBUG, "PulseAudio: Found %s with devicestring %s", desc.c_str(), sink.c_str()); - } - } - - pa_threaded_mainloop_signal(sinkStruct->mainloop, 0); -} - -/* PulseAudio class memberfunctions*/ - -CPulseAudioDirectSound::CPulseAudioDirectSound() -{ -} - -bool CPulseAudioDirectSound::Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels* channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, EEncoded encoded) -{ - m_remap.Reset(); - m_uiDataChannels = iChannels; - enum PCMChannels* outLayout = NULL; - - if (encoded == ENCODED_NONE && channelMap) - { - /* set the input format, and get the channel layout so we know what we need to open */ - outLayout = m_remap.SetInputFormat(iChannels, channelMap, uiBitsPerSample / 8, uiSamplesPerSec); - enum PCMChannels *channel; - iChannels = 0; - for(channel = outLayout; *channel != PCM_INVALID; ++channel) - ++iChannels; - - m_remap.SetOutputFormat(iChannels, outLayout); - if (m_uiDataChannels != (unsigned int)iChannels) - CLog::Log(LOGDEBUG, "CPulseAudioDirectSound::CPulseAudioDirectSound - Requested channels changed from %i to %i", m_uiDataChannels, iChannels); - } - - bool bAudioOnAllSpeakers(false); - g_audioContext.SetupSpeakerConfig(iChannels, bAudioOnAllSpeakers, bIsMusic); - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE); - - m_Context = NULL; - m_Stream = NULL; - m_MainLoop = NULL; - m_bPause = false; - m_bRecentlyFlushed = true; - m_bAutoResume = false; - m_bIsAllocated = false; - m_uiChannels = iChannels; - m_uiSamplesPerSec = uiSamplesPerSec; - m_uiBufferSize = 0; - m_uiBitsPerSample = uiBitsPerSample; - m_bPassthrough = encoded == ENCODED_NONE ? false : true; - m_uiBytesPerSecond = uiSamplesPerSec * (uiBitsPerSample / 8) * iChannels; - m_drc = 0; - - m_nCurrentVolume = g_settings.m_nVolumeLevel; - - m_dwPacketSize = iChannels*(uiBitsPerSample/8)*512; - m_dwNumPackets = 16; - -#if !PA_CHECK_VERSION(1,0,0) - /* Open the device */ - if (m_bPassthrough) - { - CLog::Log(LOGWARNING, "PulseAudio: Does not support passthrough"); - return false; - } -#endif - - std::vector<CStdString> hostdevice; - CUtil::Tokenize(device, hostdevice, "@"); - - const char *host = (hostdevice.size() < 2 || hostdevice[1].Equals("default") ? NULL : hostdevice[1].c_str()); - if (!SetupContext(host, &m_Context, &m_MainLoop)) - { - CLog::Log(LOGERROR, "PulseAudio: Failed to create context"); - Deinitialize(); - return false; - } - - pa_threaded_mainloop_lock(m_MainLoop); - - - struct pa_channel_map map; - - // Build the channel map, we dont need to remap, but we still need PCMRemap to handle mono to dual mono stereo - map.channels = iChannels; - if (outLayout) - { - for(int ch = 0; ch < iChannels; ++ch) - { - switch(outLayout[ch]) - { - case PCM_INVALID : break; - case PCM_FRONT_LEFT : map.map[ch] = PA_CHANNEL_POSITION_FRONT_LEFT ; break; - case PCM_FRONT_RIGHT : map.map[ch] = PA_CHANNEL_POSITION_FRONT_RIGHT ; break; - case PCM_FRONT_CENTER : map.map[ch] = PA_CHANNEL_POSITION_FRONT_CENTER ; break; - case PCM_BACK_CENTER : map.map[ch] = PA_CHANNEL_POSITION_REAR_CENTER ; break; - case PCM_BACK_LEFT : map.map[ch] = PA_CHANNEL_POSITION_REAR_LEFT ; break; - case PCM_BACK_RIGHT : map.map[ch] = PA_CHANNEL_POSITION_REAR_RIGHT ; break; - case PCM_LOW_FREQUENCY : map.map[ch] = PA_CHANNEL_POSITION_LFE ; break; - case PCM_FRONT_LEFT_OF_CENTER : map.map[ch] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ; break; - case PCM_FRONT_RIGHT_OF_CENTER: map.map[ch] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER; break; - case PCM_SIDE_LEFT : map.map[ch] = PA_CHANNEL_POSITION_SIDE_LEFT ; break; - case PCM_SIDE_RIGHT : map.map[ch] = PA_CHANNEL_POSITION_SIDE_RIGHT ; break; - case PCM_TOP_CENTER : map.map[ch] = PA_CHANNEL_POSITION_TOP_CENTER ; break; - case PCM_TOP_FRONT_LEFT : map.map[ch] = PA_CHANNEL_POSITION_TOP_FRONT_LEFT ; break; - case PCM_TOP_FRONT_RIGHT : map.map[ch] = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ; break; - case PCM_TOP_FRONT_CENTER : map.map[ch] = PA_CHANNEL_POSITION_TOP_CENTER ; break; - case PCM_TOP_BACK_LEFT : map.map[ch] = PA_CHANNEL_POSITION_TOP_REAR_LEFT ; break; - case PCM_TOP_BACK_RIGHT : map.map[ch] = PA_CHANNEL_POSITION_TOP_REAR_RIGHT ; break; - case PCM_TOP_BACK_CENTER : map.map[ch] = PA_CHANNEL_POSITION_TOP_REAR_CENTER ; break; - } - } - } - else - pa_channel_map_init_auto(&map, m_uiChannels, PA_CHANNEL_MAP_ALSA); - - pa_cvolume_reset(&m_Volume, m_uiChannels); - - if(m_bPassthrough) - { -#if PA_CHECK_VERSION(1,0,0) - pa_format_info *info[1]; - info[0] = pa_format_info_new(); - switch(encoded) - { - case ENCODED_IEC61937_AC3 : info[0]->encoding = PA_ENCODING_AC3_IEC61937 ; break; - case ENCODED_IEC61937_DTS : info[0]->encoding = PA_ENCODING_DTS_IEC61937 ; break; - case ENCODED_IEC61937_EAC3: info[0]->encoding = PA_ENCODING_EAC3_IEC61937; break; - case ENCODED_IEC61937_MPEG: info[0]->encoding = PA_ENCODING_MPEG_IEC61937; break; - default: info[0]->encoding = PA_ENCODING_INVALID ; break; - } - pa_format_info_set_rate(info[0], m_uiSamplesPerSec); - pa_format_info_set_channels(info[0], m_uiChannels); - pa_format_info_set_sample_format(info[0], PA_SAMPLE_S16NE); - m_Stream = pa_stream_new_extended(m_Context, "audio stream", info, 1, NULL); - pa_format_info_free(info[0]); -#endif - } - else - { - - pa_sample_spec spec; - spec.channels = iChannels; - spec.rate = uiSamplesPerSec; - spec.format = PA_SAMPLE_S16NE; - - if (!pa_sample_spec_valid(&spec)) - { - CLog::Log(LOGERROR, "PulseAudio: Invalid sample spec"); - Deinitialize(); - return false; - } - - m_Stream = pa_stream_new(m_Context, "audio stream", &spec, &map); - } - - if (m_Stream == NULL) - { - CLog::Log(LOGERROR, "PulseAudio: Could not create a stream"); - pa_threaded_mainloop_unlock(m_MainLoop); - Deinitialize(); - return false; - } - - pa_stream_set_state_callback(m_Stream, StreamStateCallback, m_MainLoop); - pa_stream_set_write_callback(m_Stream, StreamRequestCallback, m_MainLoop); - pa_stream_set_latency_update_callback(m_Stream, StreamLatencyUpdateCallback, m_MainLoop); - - const char *sink = hostdevice.size() < 1 || hostdevice[0].Equals("default") ? NULL : hostdevice[0].c_str(); - if (pa_stream_connect_playback(m_Stream, sink, NULL, ((pa_stream_flags)(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE)), &m_Volume, NULL) < 0) - { - CLog::Log(LOGERROR, "PulseAudio: Failed to connect stream to output"); - pa_threaded_mainloop_unlock(m_MainLoop); - Deinitialize(); - return false; - } - - /* Wait until the stream is ready */ - do - { - pa_threaded_mainloop_wait(m_MainLoop); - CLog::Log(LOGDEBUG, "PulseAudio: Stream %s", StreamStateToString(pa_stream_get_state(m_Stream))); - } - while (pa_stream_get_state(m_Stream) != PA_STREAM_READY && pa_stream_get_state(m_Stream) != PA_STREAM_FAILED); - - if (pa_stream_get_state(m_Stream) == PA_STREAM_FAILED) - { - CLog::Log(LOGERROR, "PulseAudio: Waited for the stream but it failed"); - pa_threaded_mainloop_unlock(m_MainLoop); - Deinitialize(); - return false; - } - - const pa_buffer_attr *a; - - if (!(a = pa_stream_get_buffer_attr(m_Stream))) - CLog::Log(LOGERROR, "PulseAudio: %s", pa_strerror(pa_context_errno(m_Context))); - else - { - m_dwPacketSize = a->minreq; - CLog::Log(LOGDEBUG, "PulseAudio: Default buffer attributes, maxlength=%u, tlength=%u, prebuf=%u, minreq=%u", a->maxlength, a->tlength, a->prebuf, a->minreq); - pa_buffer_attr b; - b.prebuf = (uint32_t)-1; - b.minreq = a->minreq; - b.tlength = m_uiBufferSize = a->tlength; - b.maxlength = a->maxlength; - b.fragsize = a->fragsize; - - WaitForOperation(pa_stream_set_buffer_attr(m_Stream, &b, NULL, NULL), m_MainLoop, "SetBuffer"); - - if (!(a = pa_stream_get_buffer_attr(m_Stream))) - CLog::Log(LOGERROR, "PulseAudio: %s", pa_strerror(pa_context_errno(m_Context))); - else - { - m_dwPacketSize = a->minreq; - m_uiBufferSize = a->tlength; - CLog::Log(LOGDEBUG, "PulseAudio: Choosen buffer attributes, maxlength=%u, tlength=%u, prebuf=%u, minreq=%u", a->maxlength, a->tlength, a->prebuf, a->minreq); - } - } - - pa_threaded_mainloop_unlock(m_MainLoop); - - m_bIsAllocated = true; - - SetCurrentVolume(m_nCurrentVolume); - Resume(); - return true; -} - -CPulseAudioDirectSound::~CPulseAudioDirectSound() -{ - Deinitialize(); -} - -bool CPulseAudioDirectSound::Deinitialize() -{ - m_bIsAllocated = false; - - if (m_Stream) - WaitCompletion(); - - if (m_MainLoop) - pa_threaded_mainloop_stop(m_MainLoop); - - if (m_Stream) - { - pa_stream_disconnect(m_Stream); - pa_stream_unref(m_Stream); - m_Stream = NULL; - } - - if (m_Context) - { - pa_context_disconnect(m_Context); - pa_context_unref(m_Context); - m_Context = NULL; - } - - if (m_MainLoop) - { - pa_threaded_mainloop_free(m_MainLoop); - m_MainLoop = NULL; - } - - g_audioContext.SetActiveDevice(CAudioContext::DEFAULT_DEVICE); - return true; -} - -inline bool CPulseAudioDirectSound::WaitForOperation(pa_operation *op, pa_threaded_mainloop *mainloop, const char *LogEntry = "") -{ - if (op == NULL) - return false; - - bool sucess = true; - - while (pa_operation_get_state(op) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(mainloop); - - if (pa_operation_get_state(op) != PA_OPERATION_DONE) - { - CLog::Log(LOGERROR, "PulseAudio: %s Operation failed", LogEntry); - sucess = false; - } - - pa_operation_unref(op); - return sucess; -} - -void CPulseAudioDirectSound::Flush() -{ - if (!m_bIsAllocated) - return; - - Pause(); - - pa_threaded_mainloop_lock(m_MainLoop); - WaitForOperation(pa_stream_flush(m_Stream, NULL, NULL), m_MainLoop, "Flush"); - m_bRecentlyFlushed = true; - pa_threaded_mainloop_unlock(m_MainLoop); -} - -bool CPulseAudioDirectSound::Cork(bool cork) -{ - pa_threaded_mainloop_lock(m_MainLoop); - - if (!WaitForOperation(pa_stream_cork(m_Stream, cork ? 1 : 0, NULL, NULL), m_MainLoop, cork ? "Pause" : "Resume")) - cork = !cork; - - pa_threaded_mainloop_unlock(m_MainLoop); - - return cork; -} - -bool CPulseAudioDirectSound::Pause() -{ - if (!m_bIsAllocated) - return -1; - - if (m_bPause) - return true; - - m_bPause = Cork(true); - - return m_bPause; -} - -bool CPulseAudioDirectSound::Resume() -{ - if (!m_bIsAllocated) - return false; - - bool result = false; - - if(m_bPause && !m_bRecentlyFlushed) - { - m_bPause = Cork(false); - result = !m_bPause; - } - else if (m_bPause) - result = m_bAutoResume = true; - - return result; -} - -bool CPulseAudioDirectSound::Stop() -{ - if (!m_bIsAllocated) - return false; - - Flush(); - - return true; -} - -long CPulseAudioDirectSound::GetCurrentVolume() const -{ - return m_nCurrentVolume; -} - -void CPulseAudioDirectSound::Mute(bool bMute) -{ - if (!m_bIsAllocated) - return; - - if (bMute) - SetCurrentVolume(VOLUME_MINIMUM); - else - SetCurrentVolume(m_nCurrentVolume); -} - -bool CPulseAudioDirectSound::SetCurrentVolume(long nVolume) -{ - if (!m_bIsAllocated || m_bPassthrough) - return -1; - - pa_threaded_mainloop_lock(m_MainLoop); - pa_volume_t volume = pa_sw_volume_from_dB((float)nVolume*1.5f / 200.0f); - if ( nVolume <= VOLUME_MINIMUM ) - pa_cvolume_mute(&m_Volume, m_uiChannels); - else - pa_cvolume_set(&m_Volume, m_uiChannels, volume); - pa_operation *op = pa_context_set_sink_input_volume(m_Context, pa_stream_get_index(m_Stream), &m_Volume, NULL, NULL); - if (op == NULL) - CLog::Log(LOGERROR, "PulseAudio: Failed to set volume"); - else - pa_operation_unref(op); - - pa_threaded_mainloop_unlock(m_MainLoop); - - return true; -} - -unsigned int CPulseAudioDirectSound::GetSpace() -{ - if (!m_bIsAllocated) - return 0; - - size_t l; - pa_threaded_mainloop_lock(m_MainLoop); - l = pa_stream_writable_size(m_Stream); - pa_threaded_mainloop_unlock(m_MainLoop); - return (l / m_uiChannels) * m_uiDataChannels; -} - -unsigned int CPulseAudioDirectSound::AddPackets(const void* data, unsigned int len) -{ - if (!m_bIsAllocated) - return len; - - pa_threaded_mainloop_lock(m_MainLoop); - - len = (len / m_uiDataChannels) * m_uiChannels; - int length = std::min((int)pa_stream_writable_size(m_Stream), (int)len); - int frames = length / m_uiChannels / (m_uiBitsPerSample >> 3); - if (frames == 0) - { - pa_threaded_mainloop_unlock(m_MainLoop); - return 0; - } - - if (m_remap.CanRemap()) - { - /* remap the data to the correct channels */ - uint8_t outData[length]; - m_remap.Remap((void *)data, outData, frames, m_drc); - if (pa_stream_write(m_Stream, outData, length, NULL, 0, PA_SEEK_RELATIVE) < 0) - CLog::Log(LOGERROR, "CPulseAudioDirectSound::AddPackets - pa_stream_write failed\n"); - - } - else - if (pa_stream_write(m_Stream, data, length, NULL, 0, PA_SEEK_RELATIVE) < 0) - CLog::Log(LOGERROR, "CPulseAudioDirectSound::AddPackets - pa_stream_write failed\n"); - - - if (m_bRecentlyFlushed) - m_bRecentlyFlushed = false; - - pa_threaded_mainloop_unlock(m_MainLoop); - - if (m_bAutoResume) - m_bAutoResume = !Resume(); - - return (length / m_uiChannels) * m_uiDataChannels; -} - -float CPulseAudioDirectSound::GetCacheTime() -{ - return (float)(m_uiBufferSize - GetSpace()) / (float)m_uiBytesPerSecond; -} - -float CPulseAudioDirectSound::GetCacheTotal() -{ - return (float)m_uiBufferSize / (float)m_uiBytesPerSecond; -} - -float CPulseAudioDirectSound::GetDelay() -{ - if (!m_bIsAllocated) - return 0; - - pa_usec_t latency = (pa_usec_t) -1; - pa_threaded_mainloop_lock(m_MainLoop); - while (pa_stream_get_latency(m_Stream, &latency, NULL) < 0) - { - if (pa_context_errno(m_Context) != PA_ERR_NODATA) - { - CLog::Log(LOGERROR, "PulseAudio: pa_stream_get_latency() failed"); - break; - } - /* Wait until latency data is available again */ - pa_threaded_mainloop_wait(m_MainLoop); - } - pa_threaded_mainloop_unlock(m_MainLoop); - return latency / 1000000.0; -} - -unsigned int CPulseAudioDirectSound::GetChunkLen() -{ - return (m_dwPacketSize / m_uiChannels) * m_uiDataChannels; -} - -int CPulseAudioDirectSound::SetPlaySpeed(int iSpeed) -{ - return 0; -} - -void CPulseAudioDirectSound::RegisterAudioCallback(IAudioCallback *pCallback) -{ - m_pCallback = pCallback; -} - -void CPulseAudioDirectSound::UnRegisterAudioCallback() -{ - m_pCallback = NULL; -} - -void CPulseAudioDirectSound::WaitCompletion() -{ - if (!m_bIsAllocated || m_bRecentlyFlushed) - return; - - pa_threaded_mainloop_lock(m_MainLoop); - WaitForOperation(pa_stream_drain(m_Stream, NULL, NULL), m_MainLoop, "Drain"); - pa_threaded_mainloop_unlock(m_MainLoop); -} - -void CPulseAudioDirectSound::SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) -{ -} - -void CPulseAudioDirectSound::EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough) -{ - pa_context *context; - pa_threaded_mainloop *mainloop; - - if (!SetupContext(NULL, &context, &mainloop)) - { - CLog::Log(LOGERROR, "PulseAudio: Failed to create context"); - return; - } - - pa_threaded_mainloop_lock(mainloop); - - SinkInfoStruct sinkStruct; - sinkStruct.passthrough = passthrough; - sinkStruct.mainloop = mainloop; - sinkStruct.list = &vAudioSinks; - WaitForOperation(pa_context_get_sink_info_list(context, SinkInfo, &sinkStruct), mainloop, "EnumerateAudioSinks"); - - pa_threaded_mainloop_unlock(mainloop); - - if (mainloop) - pa_threaded_mainloop_stop(mainloop); - - if (context) - { - pa_context_disconnect(context); - pa_context_unref(context); - context = NULL; - } - - if (mainloop) - { - pa_threaded_mainloop_free(mainloop); - mainloop = NULL; - } -} - -bool CPulseAudioDirectSound::SetupContext(const char *host, pa_context **context, pa_threaded_mainloop **mainloop) -{ - if ((*mainloop = pa_threaded_mainloop_new()) == NULL) - { - CLog::Log(LOGERROR, "PulseAudio: Failed to allocate main loop"); - return false; - } - - if (((*context) = pa_context_new(pa_threaded_mainloop_get_api(*mainloop), "XBMC")) == NULL) - { - CLog::Log(LOGERROR, "PulseAudio: Failed to allocate context"); - return false; - } - - pa_context_set_state_callback(*context, ContextStateCallback, *mainloop); - - if (pa_context_connect(*context, host, (pa_context_flags_t)0, NULL) < 0) - { - CLog::Log(LOGERROR, "PulseAudio: Failed to connect context"); - return false; - } - pa_threaded_mainloop_lock(*mainloop); - - if (pa_threaded_mainloop_start(*mainloop) < 0) - { - CLog::Log(LOGERROR, "PulseAudio: Failed to start MainLoop"); - pa_threaded_mainloop_unlock(*mainloop); - return false; - } - - /* Wait until the context is ready */ - do - { - pa_threaded_mainloop_wait(*mainloop); - CLog::Log(LOGDEBUG, "PulseAudio: Context %s", ContextStateToString(pa_context_get_state(*context))); - } - while (pa_context_get_state(*context) != PA_CONTEXT_READY && pa_context_get_state(*context) != PA_CONTEXT_FAILED); - - if (pa_context_get_state(*context) == PA_CONTEXT_FAILED) - { - CLog::Log(LOGERROR, "PulseAudio: Waited for the Context but it failed"); - pa_threaded_mainloop_unlock(*mainloop); - return false; - } - - pa_threaded_mainloop_unlock(*mainloop); - return true; -} -#endif - diff --git a/xbmc/cores/AudioRenderers/PulseAudioDirectSound.h b/xbmc/cores/AudioRenderers/PulseAudioDirectSound.h deleted file mode 100644 index 440bd6f580..0000000000 --- a/xbmc/cores/AudioRenderers/PulseAudioDirectSound.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef __PULSE_AUDIO_DIRECT_SOUND_H__ -#define __PULSE_AUDIO_DIRECT_SOUND_H__ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "IAudioRenderer.h" -#include "cores/IAudioCallback.h" - -#include <pulse/pulseaudio.h> - -#include "../../utils/PCMAmplifier.h" - -extern void RegisterAudioCallback(IAudioCallback* pCallback); -extern void UnRegisterAudioCallback(); - -class CPulseAudioDirectSound : public IAudioRenderer -{ -public: - virtual void UnRegisterAudioCallback(); - virtual void RegisterAudioCallback(IAudioCallback* pCallback); - virtual unsigned int GetChunkLen(); - virtual float GetDelay(); - virtual float GetCacheTime(); - virtual float GetCacheTotal(); - CPulseAudioDirectSound(); - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = IAudioRenderer::ENCODED_NONE); - virtual ~CPulseAudioDirectSound(); - - virtual unsigned int AddPackets(const void* data, unsigned int len); - virtual unsigned int GetSpace(); - virtual bool Deinitialize(); - virtual bool Pause(); - virtual bool Stop(); - virtual bool Resume(); - - virtual long GetCurrentVolume() const; - virtual void Mute(bool bMute); - virtual bool SetCurrentVolume(long nVolume); - virtual void SetDynamicRangeCompression(long drc) { m_drc = drc; } - virtual int SetPlaySpeed(int iSpeed); - virtual void WaitCompletion(); - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers); - - virtual void Flush(); - - static void EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough); -private: - static bool SetupContext(const char *host, pa_context **context, pa_threaded_mainloop **mainloop); - bool Cork(bool cork); - static inline bool WaitForOperation(pa_operation *op, pa_threaded_mainloop *mainloop, const char *LogEntry); - - IAudioCallback* m_pCallback; - - long m_nCurrentVolume; - long m_drc; - unsigned int m_dwPacketSize; - unsigned int m_dwNumPackets; - - bool m_bIsAllocated; - - unsigned int m_uiBytesPerSecond; - unsigned int m_uiBufferSize; - unsigned int m_uiSamplesPerSec; - unsigned int m_uiBitsPerSample; - unsigned int m_uiDataChannels; - unsigned int m_uiChannels; - bool m_bPause, m_bRecentlyFlushed, m_bAutoResume; - bool m_bPassthrough; - - pa_stream *m_Stream; - pa_cvolume m_Volume; - - pa_context *m_Context; - pa_threaded_mainloop *m_MainLoop; -}; - -#endif - diff --git a/xbmc/cores/AudioRenderers/Win32DirectSound.cpp b/xbmc/cores/AudioRenderers/Win32DirectSound.cpp deleted file mode 100644 index 1ac873287a..0000000000 --- a/xbmc/cores/AudioRenderers/Win32DirectSound.cpp +++ /dev/null @@ -1,674 +0,0 @@ -/* -* XBMC Media Center -* Copyright (c) 2002 d7o3g4q and RUNTiME -* Portions Copyright (c) by the authors of ffmpeg and xvid -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "threads/SystemClock.h" -#include "system.h" // WIN32INCLUDES needed for the directsound stuff below -#include "Win32DirectSound.h" -#include "guilib/AudioContext.h" -#include "settings/Settings.h" -#include <initguid.h> -#include <Mmreg.h> -#include "threads/SingleLock.h" -#include "utils/SystemInfo.h" -#include "utils/log.h" -#include "utils/TimeUtils.h" -#include "utils/CharsetConverter.h" - -#ifdef HAS_DX -#pragma comment(lib, "dxguid.lib") -#endif - -DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, WAVE_FORMAT_IEEE_FLOAT, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ); -DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_PCM, WAVE_FORMAT_PCM, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ); -DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF, WAVE_FORMAT_DOLBY_AC3_SPDIF, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ); - -const enum PCMChannels dsound_default_channel_layout[][8] = -{ - {PCM_FRONT_CENTER}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_SIDE_LEFT, PCM_SIDE_RIGHT} -}; - -const enum PCMChannels dsound_channel_order[] = {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_FRONT_LEFT_OF_CENTER, PCM_FRONT_RIGHT_OF_CENTER, PCM_BACK_CENTER, PCM_SIDE_LEFT, PCM_SIDE_RIGHT}; - -#define DSOUND_TOTAL_CHANNELS 11 - -static BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCTSTR lpcstrDescription, LPCTSTR lpcstrModule, LPVOID lpContext) -{ - AudioSinkList& enumerator = *static_cast<AudioSinkList*>(lpContext); - - CStdString device(lpcstrDescription); - g_charsetConverter.unknownToUTF8(device); - - enumerator.push_back(AudioSink(CStdString("DirectSound: ").append(device), CStdString("directsound:").append(device))); - - return TRUE; -} - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// -//*********************************************************************************************** -CWin32DirectSound::CWin32DirectSound() : - m_Passthrough(false), - m_AvgBytesPerSec(0), - m_CacheLen(0), - m_dwChunkSize(0), - m_dwDataChunkSize(0), - m_dwBufferLen(0), - m_PreCacheSize(0), - m_LastCacheCheck(0) -{ -} - -bool CWin32DirectSound::Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels* channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, EEncoded bAudioPassthrough) -{ - m_uiDataChannels = iChannels; - - if(!bAudioPassthrough && channelMap) - { - PCMChannels *outLayout = m_remap.SetInputFormat(iChannels, channelMap, uiBitsPerSample / 8, uiSamplesPerSec); - - for(iChannels = 0; outLayout[iChannels] != PCM_INVALID;) ++iChannels; - - BuildChannelMapping(iChannels, outLayout); - m_remap.SetOutputFormat(iChannels, m_SpeakerOrder, false); - } - - bool bAudioOnAllSpeakers(false); - g_audioContext.SetupSpeakerConfig(iChannels, bAudioOnAllSpeakers, bIsMusic); - if(bAudioPassthrough) - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE_DIGITAL); - else - g_audioContext.SetActiveDevice(CAudioContext::DIRECTSOUND_DEVICE); - m_pDSound=g_audioContext.GetDirectSoundDevice(); - - m_bPause = false; - m_bIsAllocated = false; - m_pBuffer = NULL; - m_uiChannels = iChannels; - m_uiSamplesPerSec = uiSamplesPerSec; - m_uiBitsPerSample = uiBitsPerSample; - m_Passthrough = (bAudioPassthrough != ENCODED_NONE); - - m_nCurrentVolume = g_settings.m_nVolumeLevel; - m_drc = 0; - - WAVEFORMATEXTENSIBLE wfxex = {0}; - - //fill waveformatex - ZeroMemory(&wfxex, sizeof(WAVEFORMATEXTENSIBLE)); - wfxex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); - wfxex.Format.nChannels = iChannels; - wfxex.Format.nSamplesPerSec = uiSamplesPerSec; - if (bAudioPassthrough) - { - wfxex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; - wfxex.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; - wfxex.SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF; - wfxex.Format.wBitsPerSample = 16; - wfxex.Format.nChannels = 2; - } - else - { - wfxex.dwChannelMask = m_uiSpeakerMask; - - if (iChannels > 2) - wfxex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - else - wfxex.Format.wFormatTag = WAVE_FORMAT_PCM; - - wfxex.SubFormat = _KSDATAFORMAT_SUBTYPE_PCM; - wfxex.Format.wBitsPerSample = uiBitsPerSample; - } - - wfxex.Samples.wValidBitsPerSample = wfxex.Format.wBitsPerSample; - wfxex.Format.nBlockAlign = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3); - wfxex.Format.nAvgBytesPerSec = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign; - - m_AvgBytesPerSec = wfxex.Format.nAvgBytesPerSec; - - m_uiBytesPerFrame = wfxex.Format.nBlockAlign; - m_uiDataBytesPerFrame = (wfxex.Format.nBlockAlign / iChannels) * m_uiDataChannels; - - // unsure if these are the right values - m_dwChunkSize = wfxex.Format.nBlockAlign * 3096; - m_dwDataChunkSize = (m_dwChunkSize / iChannels) * m_uiDataChannels; - m_dwBufferLen = m_dwChunkSize * 16; - m_PreCacheSize = m_dwBufferLen - 2*m_dwChunkSize; - - CLog::Log(LOGDEBUG, __FUNCTION__": Packet Size = %d. Avg Bytes Per Second = %d.", m_dwChunkSize, m_AvgBytesPerSec); - - // fill in the secondary sound buffer descriptor - DSBUFFERDESC dsbdesc; - memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); - dsbdesc.dwSize = sizeof(DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 /** Better position accuracy */ - | DSBCAPS_GLOBALFOCUS /** Allows background playing */ - | DSBCAPS_CTRLVOLUME; /** volume control enabled */ - - if (!g_sysinfo.IsVistaOrHigher()) - dsbdesc.dwFlags |= DSBCAPS_LOCHARDWARE; /** Needed for 5.1 on emu101k, always fails on Vista, by design */ - - dsbdesc.dwBufferBytes = m_dwBufferLen; - dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&wfxex; - - // now create the stream buffer - HRESULT res = IDirectSound_CreateSoundBuffer(m_pDSound, &dsbdesc, &m_pBuffer, NULL); - if (res != DS_OK) - { - if (dsbdesc.dwFlags & DSBCAPS_LOCHARDWARE) - { - SAFE_RELEASE(m_pBuffer); - CLog::Log(LOGDEBUG, __FUNCTION__": Couldn't create secondary buffer (%s). Trying without LOCHARDWARE.", dserr2str(res)); - // Try without DSBCAPS_LOCHARDWARE - dsbdesc.dwFlags &= ~DSBCAPS_LOCHARDWARE; - res = IDirectSound_CreateSoundBuffer(m_pDSound, &dsbdesc, &m_pBuffer, NULL); - } - if (res != DS_OK && dsbdesc.dwFlags & DSBCAPS_CTRLVOLUME) - { - SAFE_RELEASE(m_pBuffer); - CLog::Log(LOGDEBUG, __FUNCTION__": Couldn't create secondary buffer (%s). Trying without CTRLVOLUME.", dserr2str(res)); - // Try without DSBCAPS_CTRLVOLUME - dsbdesc.dwFlags &= ~DSBCAPS_CTRLVOLUME; - res = IDirectSound_CreateSoundBuffer(m_pDSound, &dsbdesc, &m_pBuffer, NULL); - } - if (res != DS_OK) - { - SAFE_RELEASE(m_pBuffer); - CLog::Log(LOGERROR, __FUNCTION__": cannot create secondary buffer (%s)", dserr2str(res)); - return false; - } - } - CLog::Log(LOGDEBUG, __FUNCTION__": secondary buffer created"); - - m_pBuffer->Stop(); - - if (DSERR_CONTROLUNAVAIL == m_pBuffer->SetVolume(g_settings.m_nVolumeLevel)) - CLog::Log(LOGINFO, __FUNCTION__": Volume control is unavailable in the current configuration"); - - m_bIsAllocated = true; - m_BufferOffset = 0; - m_CacheLen = 0; - m_LastCacheCheck = XbmcThreads::SystemClockMillis(); - - return m_bIsAllocated; -} - -//*********************************************************************************************** -CWin32DirectSound::~CWin32DirectSound() -{ - Deinitialize(); -} - -//*********************************************************************************************** -bool CWin32DirectSound::Deinitialize() -{ - if (m_bIsAllocated) - { - CLog::Log(LOGDEBUG, __FUNCTION__": Cleaning up"); - m_bIsAllocated = false; - if (m_pBuffer) - { - m_pBuffer->Stop(); - SAFE_RELEASE(m_pBuffer); - } - - m_pBuffer = NULL; - m_pDSound = NULL; - m_BufferOffset = 0; - m_CacheLen = 0; - m_dwChunkSize = 0; - m_dwBufferLen = 0; - - g_audioContext.SetActiveDevice(CAudioContext::DEFAULT_DEVICE); - } - return true; -} - -//*********************************************************************************************** -bool CWin32DirectSound::Pause() -{ - CSingleLock lock (m_critSection); - if (m_bPause) // Already paused - return true; - m_bPause = true; - m_pBuffer->Stop(); - - return true; -} - -//*********************************************************************************************** -bool CWin32DirectSound::Resume() -{ - CSingleLock lock (m_critSection); - if (!m_bPause) // Already playing - return true; - m_bPause = false; - if (m_CacheLen >= m_PreCacheSize) // Make sure we have some data to play (if not, playback will start when we add some) - m_pBuffer->Play(0, 0, DSBPLAY_LOOPING); - - return true; -} - -//*********************************************************************************************** -bool CWin32DirectSound::Stop() -{ - CSingleLock lock (m_critSection); - // Stop and reset DirectSound buffer - m_pBuffer->Stop(); - m_pBuffer->SetCurrentPosition(0); - - // Reset buffer management members - m_BufferOffset = 0; - m_CacheLen = 0; - m_bPause = false; - - return true; -} - -//*********************************************************************************************** -long CWin32DirectSound::GetCurrentVolume() const -{ - return m_nCurrentVolume; -} - -//*********************************************************************************************** -void CWin32DirectSound::Mute(bool bMute) -{ - CSingleLock lock (m_critSection); - if (!m_bIsAllocated) return; - if (bMute) - m_pBuffer->SetVolume(VOLUME_MINIMUM); - else - m_pBuffer->SetVolume(m_nCurrentVolume); -} - -//*********************************************************************************************** -bool CWin32DirectSound::SetCurrentVolume(long nVolume) -{ - CSingleLock lock (m_critSection); - if (!m_bIsAllocated) return false; - m_nCurrentVolume = nVolume; - return m_pBuffer->SetVolume( m_nCurrentVolume ) == S_OK; -} - -//*********************************************************************************************** -unsigned int CWin32DirectSound::AddPackets(const void* data, unsigned int len) -{ - CSingleLock lock (m_critSection); - DWORD total = len; - unsigned char* pBuffer = (unsigned char*)data; - - DWORD bufferStatus = 0; - m_pBuffer->GetStatus(&bufferStatus); - if (bufferStatus & DSBSTATUS_BUFFERLOST) - { - CLog::Log(LOGDEBUG, __FUNCTION__ ": Buffer allocation was lost. Restoring buffer."); - m_pBuffer->Restore(); - } - - while (len >= m_dwDataChunkSize && GetSpace() >= m_dwDataChunkSize) // We want to write at least one chunk at a time - { - LPVOID start = NULL, startWrap = NULL; - DWORD size = 0, sizeWrap = 0; - if (m_BufferOffset >= m_dwBufferLen) // Wrap-around manually - m_BufferOffset = 0; - HRESULT res = m_pBuffer->Lock(m_BufferOffset, m_dwChunkSize, &start, &size, &startWrap, &sizeWrap, 0); - if (DS_OK != res) - { - CLog::Log(LOGERROR, __FUNCTION__ ": Unable to lock buffer at offset %u. HRESULT: 0x%08x", m_BufferOffset, res); - break; - } - - // Remap the data to the correct channels into the buffer - if (m_remap.CanRemap()) - m_remap.Remap((void*)pBuffer, start, size / m_uiBytesPerFrame, m_drc); - else - memcpy(start, pBuffer, size); - - pBuffer += size * m_uiDataBytesPerFrame / m_uiBytesPerFrame; - len -= size * m_uiDataBytesPerFrame / m_uiBytesPerFrame; - - m_BufferOffset += size; - if (startWrap) // Write-region wraps to beginning of buffer - { - // Remap the data to the correct channels into the buffer - if (m_remap.CanRemap()) - m_remap.Remap((void*)pBuffer, startWrap, sizeWrap / m_uiBytesPerFrame, m_drc); - else - memcpy(startWrap, pBuffer, sizeWrap); - m_BufferOffset = sizeWrap; - - pBuffer += sizeWrap * m_uiDataBytesPerFrame / m_uiBytesPerFrame; - len -= sizeWrap * m_uiDataBytesPerFrame / m_uiBytesPerFrame; - } - - m_CacheLen += size + sizeWrap; // This data is now in the cache - m_pBuffer->Unlock(start, size, startWrap, sizeWrap); - } - - CheckPlayStatus(); - - return total - len; // Bytes used -} - -void CWin32DirectSound::UpdateCacheStatus() -{ - CSingleLock lock (m_critSection); - // TODO: Check to see if we may have cycled around since last time - unsigned int time = XbmcThreads::SystemClockMillis(); - if (time == m_LastCacheCheck) - return; // Don't recalc more frequently than once/ms (that is our max resolution anyway) - - DWORD playCursor = 0, writeCursor = 0; - HRESULT res = m_pBuffer->GetCurrentPosition(&playCursor, &writeCursor); // Get the current playback and safe write positions - if (DS_OK != res) - { - CLog::Log(LOGERROR,__FUNCTION__ ": GetCurrentPosition failed. Unable to determine buffer status. HRESULT = 0x%08x", res); - return; - } - - m_LastCacheCheck = time; - // Check the state of the ring buffer (P->O->W == underrun) - // These are the logical situations that can occur - // O: CurrentOffset W: WriteCursor P: PlayCursor - // | | | | | | | | | | - // ***O----W----P***** < underrun P > W && O < W (1) - // | | | | | | | | | | - // ---P****O----W----- < underrun O > P && O < W (2) - // | | | | | | | | | | - // ---W----P****O----- < underrun P > W && P < O (3) - // | | | | | | | | | | - // ***W****O----P***** P > W && P > O (4) - // | | | | | | | | | | - // ---P****W****O----- P < W && O > W (5) - // | | | | | | | | | | - // ***O----P****W***** P < W && O < P (6) - - // Check for underruns - if ((playCursor > writeCursor && m_BufferOffset < writeCursor) || // (1) - (playCursor < m_BufferOffset && m_BufferOffset < writeCursor) || // (2) - (playCursor > writeCursor && playCursor < m_BufferOffset)) // (3) - { - CLog::Log(LOGWARNING, "CWin32DirectSound::GetSpace - buffer underrun - W:%u, P:%u, O:%u.", writeCursor, playCursor, m_BufferOffset); - m_BufferOffset = writeCursor; // Catch up - m_pBuffer->Stop(); // Wait until someone gives us some data to restart playback (prevents glitches) - } - - // Calculate available space in the ring buffer - if (playCursor == m_BufferOffset && m_BufferOffset == writeCursor) // Playback is stopped and we are all at the same place - m_CacheLen = 0; - else if (m_BufferOffset > playCursor) - m_CacheLen = m_BufferOffset - playCursor; - else - m_CacheLen = m_dwBufferLen - (playCursor - m_BufferOffset); -} - -void CWin32DirectSound::CheckPlayStatus() -{ - DWORD status = 0; - m_pBuffer->GetStatus(&status); - - if(!m_bPause && !(status & DSBSTATUS_PLAYING) && m_CacheLen >= m_PreCacheSize) // If we have some data, see if we can start playback - { - m_pBuffer->Play(0, 0, DSBPLAY_LOOPING); - CLog::Log(LOGDEBUG,__FUNCTION__ ": Resuming Playback"); - } -} - -unsigned int CWin32DirectSound::GetSpace() -{ - CSingleLock lock (m_critSection); - UpdateCacheStatus(); - unsigned int space = ((m_dwBufferLen - m_CacheLen) / m_uiChannels) * m_uiDataChannels; - - // We can never allow the internal buffers to fill up complete - // as we get confused between if the buffer is full or empty - // so never allow the last chunk to be added - if(space > m_dwDataChunkSize) - return space - m_dwDataChunkSize; - else - return 0; -} - -//*********************************************************************************************** -float CWin32DirectSound::GetDelay() -{ - // Make sure we know how much data is in the cache - UpdateCacheStatus(); - - CSingleLock lock (m_critSection); - float delay = 0.008f; // WTF? - delay += (float)m_CacheLen / (float)m_AvgBytesPerSec; - return delay; -} - -//*********************************************************************************************** -float CWin32DirectSound::GetCacheTime() -{ - CSingleLock lock (m_critSection); - // Make sure we know how much data is in the cache - UpdateCacheStatus(); - - return (float)m_CacheLen / (float)m_AvgBytesPerSec; -} - -float CWin32DirectSound::GetCacheTotal() -{ - CSingleLock lock (m_critSection); - return (float)(m_dwBufferLen - m_dwDataChunkSize) / (float)m_AvgBytesPerSec; -} - -//*********************************************************************************************** -unsigned int CWin32DirectSound::GetChunkLen() -{ - return m_dwDataChunkSize; -} - -//*********************************************************************************************** -int CWin32DirectSound::SetPlaySpeed(int iSpeed) -{ - return 0; -} - -//*********************************************************************************************** -void CWin32DirectSound::RegisterAudioCallback(IAudioCallback *pCallback) -{ - m_pCallback = pCallback; -} - -//*********************************************************************************************** -void CWin32DirectSound::UnRegisterAudioCallback() -{ - m_pCallback = NULL; -} - -//*********************************************************************************************** -void CWin32DirectSound::WaitCompletion() -{ - CSingleLock lock (m_critSection); - DWORD status; - unsigned int timeout; - unsigned char* silence; - - if (!m_pBuffer) - return ; - - if(FAILED(m_pBuffer->GetStatus(&status)) || (status & DSBSTATUS_PLAYING) == 0) - return; // We weren't playing anyway - - // The drain should complete in the time occupied by the cache - timeout = (unsigned int)(1000 * GetDelay()); - unsigned int startTime = XbmcThreads::SystemClockMillis(); - silence = (unsigned char*)calloc(1,m_dwChunkSize); // Initialize 'silence' to zero... - - while(AddPackets(silence, m_dwChunkSize) == 0) - { - if(FAILED(m_pBuffer->GetStatus(&status)) || (status & DSBSTATUS_PLAYING) == 0) - break; - - if((XbmcThreads::SystemClockMillis() - startTime) > timeout) - { - CLog::Log(LOGWARNING, __FUNCTION__ ": timeout adding silence to buffer"); - break; - } - } - free(silence); - - while(m_CacheLen) - { - if(FAILED(m_pBuffer->GetStatus(&status)) || (status & DSBSTATUS_PLAYING) == 0) - break; - - if((XbmcThreads::SystemClockMillis() - startTime) > timeout) - { - CLog::Log(LOGDEBUG, "CWin32DirectSound::WaitCompletion - timeout waiting for silence"); - break; - } - else - Sleep(1); - GetSpace(); - } - - m_pBuffer->Stop(); -} - -//*********************************************************************************************** -void CWin32DirectSound::SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) -{ - return; -} - -//*********************************************************************************************** - -void CWin32DirectSound::EnumerateAudioSinks(AudioSinkList &vAudioSinks, bool passthrough) -{ - if (FAILED(DirectSoundEnumerate(DSEnumCallback, &vAudioSinks))) - CLog::Log(LOGERROR, "%s - failed to enumerate output devices", __FUNCTION__); -} - -//*********************************************************************************************** -char * CWin32DirectSound::dserr2str(int err) -{ - switch (err) - { - case DS_OK: return "DS_OK"; - case DS_NO_VIRTUALIZATION: return "DS_NO_VIRTUALIZATION"; - case DSERR_ALLOCATED: return "DS_NO_VIRTUALIZATION"; - case DSERR_CONTROLUNAVAIL: return "DSERR_CONTROLUNAVAIL"; - case DSERR_INVALIDPARAM: return "DSERR_INVALIDPARAM"; - case DSERR_INVALIDCALL: return "DSERR_INVALIDCALL"; - case DSERR_GENERIC: return "DSERR_GENERIC"; - case DSERR_PRIOLEVELNEEDED: return "DSERR_PRIOLEVELNEEDED"; - case DSERR_OUTOFMEMORY: return "DSERR_OUTOFMEMORY"; - case DSERR_BADFORMAT: return "DSERR_BADFORMAT"; - case DSERR_UNSUPPORTED: return "DSERR_UNSUPPORTED"; - case DSERR_NODRIVER: return "DSERR_NODRIVER"; - case DSERR_ALREADYINITIALIZED: return "DSERR_ALREADYINITIALIZED"; - case DSERR_NOAGGREGATION: return "DSERR_NOAGGREGATION"; - case DSERR_BUFFERLOST: return "DSERR_BUFFERLOST"; - case DSERR_OTHERAPPHASPRIO: return "DSERR_OTHERAPPHASPRIO"; - case DSERR_UNINITIALIZED: return "DSERR_UNINITIALIZED"; - case DSERR_NOINTERFACE: return "DSERR_NOINTERFACE"; - case DSERR_ACCESSDENIED: return "DSERR_ACCESSDENIED"; - default: return "unknown"; - } -} - -//*********************************************************************************************** -void CWin32DirectSound::BuildChannelMapping(int channels, enum PCMChannels* map) -{ - bool usedChannels[DSOUND_TOTAL_CHANNELS]; - - memset(usedChannels, false, sizeof(usedChannels)); - - m_uiSpeakerMask = 0; - - if(!map) - map = (PCMChannels *)dsound_default_channel_layout[channels - 1]; - - //Build the speaker mask and note which are used. - for(int i = 0; i < channels; i++) - { - switch(map[i]) - { - case PCM_FRONT_LEFT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_LEFT; - break; - case PCM_FRONT_RIGHT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_RIGHT; - break; - case PCM_FRONT_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_CENTER; - break; - case PCM_LOW_FREQUENCY: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_LOW_FREQUENCY; - break; - case PCM_BACK_LEFT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_BACK_LEFT; - break; - case PCM_BACK_RIGHT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_BACK_RIGHT; - break; - case PCM_FRONT_LEFT_OF_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_LEFT_OF_CENTER; - break; - case PCM_FRONT_RIGHT_OF_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_RIGHT_OF_CENTER; - break; - case PCM_BACK_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_BACK_CENTER; - break; - case PCM_SIDE_LEFT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_SIDE_LEFT; - break; - case PCM_SIDE_RIGHT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_SIDE_RIGHT; - break; - } - } - - //Assemble a compacted channel set. - for(int i = 0, j = 0; i < DSOUND_TOTAL_CHANNELS; i++) - { - if(usedChannels[i]) - { - m_SpeakerOrder[j] = dsound_channel_order[i]; - j++; - } - } -} diff --git a/xbmc/cores/AudioRenderers/Win32DirectSound.h b/xbmc/cores/AudioRenderers/Win32DirectSound.h deleted file mode 100644 index b8dece37a9..0000000000 --- a/xbmc/cores/AudioRenderers/Win32DirectSound.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -* XBMC Media Center -* Copyright (c) 2002 d7o3g4q and RUNTiME -* Portions Copyright (c) by the authors of ffmpeg and xvid -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -// AsyncAudioRenderer.h: interface for the CAsyncDirectSound class. -// -////////////////////////////////////////////////////////////////////// - -#if !defined(AFX_ASYNCAUDIORENDERER_H__B590A94D_D15E_43A6_A41D_527BD441B5F5__INCLUDED_) -#define AFX_ASYNCAUDIORENDERER_H__B590A94D_D15E_43A6_A41D_527BD441B5F5__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "IAudioRenderer.h" -#include "threads/CriticalSection.h" - -extern void RegisterAudioCallback(IAudioCallback* pCallback); -extern void UnRegisterAudioCallback(); - -class CWin32DirectSound : public IAudioRenderer -{ -public: - virtual void UnRegisterAudioCallback(); - virtual void RegisterAudioCallback(IAudioCallback* pCallback); - virtual unsigned int GetChunkLen(); - virtual float GetDelay(); - virtual float GetCacheTime(); - virtual float GetCacheTotal(); - CWin32DirectSound(); - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels* channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = IAudioRenderer::ENCODED_NONE); - virtual ~CWin32DirectSound(); - - virtual unsigned int AddPackets(const void* data, unsigned int len); - virtual unsigned int GetSpace(); - virtual bool Deinitialize(); - virtual bool Pause(); - virtual bool Stop(); - virtual bool Resume(); - - virtual long GetCurrentVolume() const; - virtual void Mute(bool bMute); - virtual bool SetCurrentVolume(long nVolume); - virtual void SetDynamicRangeCompression(long drc) { m_drc = drc; } - virtual int SetPlaySpeed(int iSpeed); - virtual void WaitCompletion(); - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers); - - static void EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough); - -private: - void UpdateCacheStatus(); - void CheckPlayStatus(); - void BuildChannelMapping(int channels, enum PCMChannels* map); - - LPDIRECTSOUNDBUFFER m_pBuffer; - LPDIRECTSOUND8 m_pDSound; - - IAudioCallback* m_pCallback; - - long m_nCurrentVolume; - long m_drc; - unsigned int m_dwChunkSize; - unsigned int m_dwDataChunkSize; - unsigned int m_dwBufferLen; - bool m_bPause; - bool m_bIsAllocated; - - bool m_Passthrough; - unsigned int m_uiSamplesPerSec; - unsigned int m_uiBitsPerSample; - unsigned int m_uiChannels; - unsigned int m_uiDataChannels; - unsigned int m_AvgBytesPerSec; - unsigned int m_uiBytesPerFrame; - unsigned int m_uiDataBytesPerFrame; - unsigned int m_uiSpeakerMask; - enum PCMChannels m_SpeakerOrder[8]; - - char * dserr2str(int err); - - unsigned int m_BufferOffset; - unsigned int m_CacheLen; - - unsigned int m_LastCacheCheck; - size_t m_PreCacheSize; - - CCriticalSection m_critSection; -}; - -#endif // !defined(AFX_ASYNCAUDIORENDERER_H__B590A94D_D15E_43A6_A41D_527BD441B5F5__INCLUDED_) diff --git a/xbmc/cores/AudioRenderers/Win32WASAPI.cpp b/xbmc/cores/AudioRenderers/Win32WASAPI.cpp deleted file mode 100644 index d5b383af5e..0000000000 --- a/xbmc/cores/AudioRenderers/Win32WASAPI.cpp +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Copyright (C) 2005-2009 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "threads/SystemClock.h" -#include "system.h" // WIN32INCLUDES needed for the WASAPI stuff below - -#include <mmdeviceapi.h> -#include <Audioclient.h> -#include <Functiondiscoverykeys_devpkey.h> -#include <avrt.h> -#include <initguid.h> -#include <Mmreg.h> -#include "Win32WASAPI.h" -#include "guilib/AudioContext.h" -#include "settings/Settings.h" -#include "threads/SingleLock.h" -#include "utils/SystemInfo.h" -#include "utils/log.h" -#include "utils/TimeUtils.h" -#include "utils/CharsetConverter.h" - -#pragma comment(lib, "Avrt.lib") - -const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator); -const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator); -const IID IID_IAudioClient = __uuidof(IAudioClient); -const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient); - -DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_PCM, WAVE_FORMAT_PCM, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ); -DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF, WAVE_FORMAT_DOLBY_AC3_SPDIF, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ); - -const enum PCMChannels wasapi_default_channel_layout[][8] = -{ - {PCM_FRONT_CENTER}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT}, - {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_SIDE_LEFT, PCM_SIDE_RIGHT} -}; - -const enum PCMChannels wasapi_channel_order[] = {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_FRONT_LEFT_OF_CENTER, PCM_FRONT_RIGHT_OF_CENTER, PCM_BACK_CENTER, PCM_SIDE_LEFT, PCM_SIDE_RIGHT}; - -#define WASAPI_TOTAL_CHANNELS 11 - -#define EXIT_ON_FAILURE(hr, reason, ...) if(FAILED(hr)) {CLog::Log(LOGERROR, reason, __VA_ARGS__); goto failed;} - -//This needs to be static since only one exclusive stream can exist at one time. -bool CWin32WASAPI::m_bIsAllocated = false; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// -//*********************************************************************************************** -CWin32WASAPI::CWin32WASAPI() : - m_bPassthrough(false), - m_uiAvgBytesPerSec(0), - m_CacheLen(0), - m_uiChunkSize(0), - m_uiSrcChunkSize(0), - m_uiBufferLen(0), - m_PreCacheSize(0), - m_LastCacheCheck(0), - m_pAudioClient(NULL), - m_pRenderClient(NULL), - m_pDevice(NULL) -{ -} - -bool CWin32WASAPI::Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic, EEncoded bAudioPassthrough) -{ - CLog::Log(LOGDEBUG, __FUNCTION__": endpoint device %s", device.c_str()); - - //First check if the version of Windows we are running on even supports WASAPI. - if (!g_sysinfo.IsVistaOrHigher()) - { - CLog::Log(LOGERROR, __FUNCTION__": WASAPI output requires Vista or higher."); - return false; - } - - //Only one exclusive stream may be initialized at one time. - if(m_bIsAllocated) - { - CLog::Log(LOGERROR, __FUNCTION__": Cannot create more then one WASAPI stream at one time."); - return false; - } - - int layoutChannels = 0; - - if(!bAudioPassthrough && channelMap) - { - PCMChannels *outLayout = m_remap.SetInputFormat(iChannels, channelMap, uiBitsPerSample / 8, uiSamplesPerSec); - - for(PCMChannels *channel = outLayout; *channel != PCM_INVALID; channel++) - ++layoutChannels; - - //Expand monural to stereo as most devices don't seem to like 1 channel PCM streams. - //Stereo sources should be sent explicitly as two channels so that the external hardware - //can apply ProLogic/5CH Stereo/etc processing on it. - if(iChannels <= 2) - { - BuildChannelMapping(2, (PCMChannels *)wasapi_default_channel_layout[1]); - - layoutChannels = 2; - m_remap.SetOutputFormat(2, m_SpeakerOrder, false); - } - else //Do the standard remapping. - { - BuildChannelMapping(layoutChannels, outLayout); - m_remap.SetOutputFormat(layoutChannels, m_SpeakerOrder, false); - } - } - - m_bPlaying = false; - m_bPause = false; - m_bMuting = false; - m_uiChannels = iChannels; - m_uiBitsPerSample = uiBitsPerSample; - m_bPassthrough = (bAudioPassthrough != ENCODED_NONE); - - m_nCurrentVolume = g_settings.m_nVolumeLevel; - m_pcmAmplifier.SetVolume(m_nCurrentVolume); - m_drc = 0; - - WAVEFORMATEXTENSIBLE wfxex = {0}; - - //fill waveformatex - ZeroMemory(&wfxex, sizeof(WAVEFORMATEXTENSIBLE)); - wfxex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); - wfxex.Format.nChannels = layoutChannels; - wfxex.Format.nSamplesPerSec = uiSamplesPerSec; - if (bAudioPassthrough) - { - wfxex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; - wfxex.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF; - wfxex.SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF; - wfxex.Format.wBitsPerSample = 16; - wfxex.Format.nChannels = 2; - } - else - { - wfxex.dwChannelMask = m_uiSpeakerMask; - wfxex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - wfxex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - wfxex.Format.wBitsPerSample = uiBitsPerSample; - } - - wfxex.Samples.wValidBitsPerSample = uiBitsPerSample == 32 ? 24 : uiBitsPerSample; - wfxex.Format.nBlockAlign = wfxex.Format.nChannels * (wfxex.Format.wBitsPerSample >> 3); - wfxex.Format.nAvgBytesPerSec = wfxex.Format.nSamplesPerSec * wfxex.Format.nBlockAlign; - - m_uiAvgBytesPerSec = wfxex.Format.nAvgBytesPerSec; - - m_uiBytesPerFrame = wfxex.Format.nBlockAlign; - m_uiBytesPerSrcFrame = bAudioPassthrough ? m_uiBytesPerFrame : iChannels * wfxex.Format.wBitsPerSample >> 3; - - IMMDeviceEnumerator* pEnumerator = NULL; - IMMDeviceCollection* pEnumDevices = NULL; - - //Shut down Directsound. - g_audioContext.SetActiveDevice(CAudioContext::NONE); - - HRESULT 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: %i", hr) - - //Get our device. - //First try to find the named device. - UINT uiCount = 0; - - 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++) - { - IPropertyStore *pProperty = NULL; - PROPVARIANT varName; - - hr = pEnumDevices->Item(i, &m_pDevice); - EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of WASAPI endpoint failed.") - - hr = m_pDevice->OpenPropertyStore(STGM_READ, &pProperty); - EXIT_ON_FAILURE(hr, __FUNCTION__": Retrieval of WASAPI endpoint properties failed.") - - hr = pProperty->GetValue(PKEY_Device_FriendlyName, &varName); - if(FAILED(hr)) - { - CLog::Log(LOGERROR, __FUNCTION__": Retrieval of WASAPI endpoint device name failed."); - SAFE_RELEASE(pProperty); - goto failed; - } - - CStdStringW strRawDevName(varName.pwszVal); - CStdString strDevName; - g_charsetConverter.wToUTF8(strRawDevName, strDevName); - - if(device == strDevName) - i = uiCount; - else - SAFE_RELEASE(m_pDevice); - - PropVariantClear(&varName); - SAFE_RELEASE(pProperty); - } - - SAFE_RELEASE(pEnumDevices); - - if(!m_pDevice) - { - CLog::Log(LOGDEBUG, __FUNCTION__": Could not locate the device named \"%s\" in the list of WASAPI endpoint devices. Trying the default device...", device.c_str()); - hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_pDevice); - EXIT_ON_FAILURE(hr, __FUNCTION__": Could not retrieve the default WASAPI audio endpoint.") - } - - //We are done with the enumerator. - SAFE_RELEASE(pEnumerator); - - hr = m_pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&m_pAudioClient); - EXIT_ON_FAILURE(hr, __FUNCTION__": Activating the WASAPI endpoint device failed.") - - hr = m_pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &wfxex.Format, NULL); - EXIT_ON_FAILURE(hr, __FUNCTION__": Audio format not supported by the WASAPI device. Channels: %i, Rate: %i, Bits/sample: %i.", iChannels, uiSamplesPerSec, uiBitsPerSample) - - REFERENCE_TIME hnsRequestedDuration, hnsPeriodicity; - hr = m_pAudioClient->GetDevicePeriod(&hnsPeriodicity, NULL); - EXIT_ON_FAILURE(hr, __FUNCTION__": Could not retrieve the WASAPI endpoint device period."); - - //The default periods of some devices are VERY low (less than 3ms). - //For audio stability make sure we have at least an 8ms buffer. - if(hnsPeriodicity < 80000) hnsPeriodicity = 80000; - - hnsRequestedDuration = hnsPeriodicity * 16; - - // now create the stream buffer - hr = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE, 0, hnsRequestedDuration, hnsPeriodicity, &wfxex.Format, NULL); - EXIT_ON_FAILURE(hr, __FUNCTION__": Could not initialize the WASAPI endpoint device. %i", hr) - - hr = m_pAudioClient->GetBufferSize(&m_uiBufferLen); - m_uiBufferLen *= m_uiBytesPerFrame; - - //Chunk sizes are 1/16 the buffer size. - //WASAPI chunk sizes need to be evenly divisable into the buffer size or pops and clicks will result. - m_uiChunkSize = m_uiBufferLen / 16; - m_uiSrcChunkSize = (m_uiChunkSize / m_uiBytesPerFrame) * m_uiBytesPerSrcFrame; - - m_PreCacheSize = m_uiBufferLen - m_uiChunkSize; - - CLog::Log(LOGDEBUG, __FUNCTION__": Packet Size = %d. Avg Bytes Per Second = %d.", m_uiChunkSize, m_uiAvgBytesPerSec); - - hr = m_pAudioClient->GetService(IID_IAudioRenderClient, (void**)&m_pRenderClient); - EXIT_ON_FAILURE(hr, __FUNCTION__": Could not initialize the WASAPI render client interface.") - - m_bIsAllocated = true; - m_CacheLen = 0; - m_LastCacheCheck = XbmcThreads::SystemClockMillis(); - - return m_bIsAllocated; - -failed: - CLog::Log(LOGERROR, __FUNCTION__": WASAPI initialization failed."); - SAFE_RELEASE(pEnumDevices); - SAFE_RELEASE(pEnumerator); - SAFE_RELEASE(m_pRenderClient); - SAFE_RELEASE(m_pAudioClient); - SAFE_RELEASE(m_pDevice); - - //Restart Directsound - g_audioContext.SetActiveDevice(CAudioContext::DEFAULT_DEVICE); - - return false; -} - -//*********************************************************************************************** -CWin32WASAPI::~CWin32WASAPI() -{ - Deinitialize(); -} - -//*********************************************************************************************** -bool CWin32WASAPI::Deinitialize() -{ - if (m_bIsAllocated) - { - CLog::Log(LOGDEBUG, __FUNCTION__": Cleaning up"); - - m_pAudioClient->Stop(); - - SAFE_RELEASE(m_pRenderClient); - SAFE_RELEASE(m_pAudioClient); - SAFE_RELEASE(m_pDevice); - - m_CacheLen = 0; - m_uiChunkSize = 0; - m_uiBufferLen = 0; - - m_bIsAllocated = false; - - //Restart Directsound for the interface sounds. - g_audioContext.SetActiveDevice(CAudioContext::DEFAULT_DEVICE); - } - return true; -} - -//*********************************************************************************************** -bool CWin32WASAPI::Pause() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return false; - - if (m_bPause) // Already paused - return true; - - m_bPause = true; - m_pAudioClient->Stop(); - - return true; -} - -//*********************************************************************************************** -bool CWin32WASAPI::Resume() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return false; - - if(!m_bPause) // Already playing - return true; - - m_bPause = false; - - UpdateCacheStatus(); - if(m_CacheLen >= m_PreCacheSize) // Make sure we have some data to play (if not, playback will start when we add some) - m_pAudioClient->Start(); - else - m_bPlaying = false; // Trigger playback restart the next time data is added to the buffer. - - return true; -} - -//*********************************************************************************************** -bool CWin32WASAPI::Stop() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return false; - - // Stop and reset WASAPI buffer - m_pAudioClient->Stop(); - m_pAudioClient->Reset(); - - // Reset buffer management members - m_CacheLen = 0; - m_bPause = false; - m_bPlaying = false; - - return true; -} - -//*********************************************************************************************** -long CWin32WASAPI::GetCurrentVolume() const -{ - return m_nCurrentVolume; -} - -//*********************************************************************************************** -void CWin32WASAPI::Mute(bool bMute) -{ - CSingleLock lock (m_critSection); - - m_bMuting = bMute; -} - -//*********************************************************************************************** -bool CWin32WASAPI::SetCurrentVolume(long nVolume) -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return false; - - m_nCurrentVolume = nVolume; - m_pcmAmplifier.SetVolume(m_nCurrentVolume); - return true; -} - -//*********************************************************************************************** -unsigned int CWin32WASAPI::AddPackets(const void* data, unsigned int len) -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated || m_bPause) - return 0; - - DWORD dwFlags = m_bMuting || m_nCurrentVolume == VOLUME_MINIMUM ? AUDCLNT_BUFFERFLAGS_SILENT : 0; - - unsigned int uiBytesToWrite, uiSrcBytesToWrite; - BYTE* pBuffer = NULL; - HRESULT hr; - - UpdateCacheStatus(); - - uiBytesToWrite = std::min(m_uiBufferLen - m_CacheLen, (len / m_uiBytesPerSrcFrame) * m_uiBytesPerFrame); - uiBytesToWrite /= m_uiChunkSize; - - uiSrcBytesToWrite = uiBytesToWrite * m_uiSrcChunkSize; - - uiBytesToWrite *= m_uiChunkSize; - - if(uiBytesToWrite == 0) - return 0; - - // Get the buffer - if (SUCCEEDED(hr = m_pRenderClient->GetBuffer(uiBytesToWrite/m_uiBytesPerFrame, &pBuffer))) - { - // Write data into the buffer - AddDataToBuffer((unsigned char*)data, uiSrcBytesToWrite, pBuffer); - - //Adjust the volume if necessary. - if(!m_bPassthrough) - m_pcmAmplifier.DeAmplify((short*)pBuffer, uiBytesToWrite / 2); - - // Release the buffer - if (FAILED(hr=m_pRenderClient->ReleaseBuffer(uiBytesToWrite/m_uiBytesPerFrame, dwFlags))) - CLog::Log(LOGERROR, __FUNCTION__": ReleaseBuffer failed (%i)", hr); - } - else - { - CLog::Log(LOGERROR, __FUNCTION__": GetBuffer failed (%i)", hr); - } - m_CacheLen += uiBytesToWrite; - - CheckPlayStatus(); - - return uiSrcBytesToWrite; // Bytes used -} - -void CWin32WASAPI::UpdateCacheStatus() -{ - unsigned int time = XbmcThreads::SystemClockMillis(); - if (time == m_LastCacheCheck) - return; // Don't recalc more frequently than once/ms (that is our max resolution anyway) - - m_LastCacheCheck = time; - - m_pAudioClient->GetCurrentPadding(&m_CacheLen); - m_CacheLen *= m_uiBytesPerFrame; -} - -void CWin32WASAPI::CheckPlayStatus() -{ - if(!m_bPause && !m_bPlaying && m_CacheLen >= m_PreCacheSize) // If we have some data, see if we can start playback - { - m_pAudioClient->Start(); - m_bPlaying = true; - } -} - -unsigned int CWin32WASAPI::GetSpace() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return 0; - - // Make sure we know how much data is in the cache - UpdateCacheStatus(); - - return ((m_uiBufferLen - m_CacheLen) / m_uiBytesPerFrame) * m_uiBytesPerSrcFrame; -} - -//*********************************************************************************************** -float CWin32WASAPI::GetDelay() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return 0.0f; - - // Make sure we know how much data is in the cache - UpdateCacheStatus(); - - return (float)m_CacheLen / (float)m_uiAvgBytesPerSec; -} - -//*********************************************************************************************** -float CWin32WASAPI::GetCacheTime() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return 0.0f; - - // Make sure we know how much data is in the cache - UpdateCacheStatus(); - - return (float)m_CacheLen / (float)m_uiAvgBytesPerSec; -} - -//*********************************************************************************************** -float CWin32WASAPI::GetCacheTotal() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return 0.0f; - - return (float)m_uiBufferLen / (float)m_uiAvgBytesPerSec; -} - -//*********************************************************************************************** -unsigned int CWin32WASAPI::GetChunkLen() -{ - return m_uiSrcChunkSize; -} - -//*********************************************************************************************** -int CWin32WASAPI::SetPlaySpeed(int iSpeed) -{ - return 0; -} - -//*********************************************************************************************** -void CWin32WASAPI::RegisterAudioCallback(IAudioCallback *pCallback) -{ - m_pCallback = pCallback; -} - -//*********************************************************************************************** -void CWin32WASAPI::UnRegisterAudioCallback() -{ - m_pCallback = NULL; -} - -//*********************************************************************************************** - -void CWin32WASAPI::EnumerateAudioSinks(AudioSinkList &vAudioSinks, bool passthrough) -{ - //First check if the version of Windows we are running on even supports WASAPI. - if (!g_sysinfo.IsVistaOrHigher()) - { - CLog::Log(LOGDEBUG, __FUNCTION__": WASAPI enumeration requires Vista or higher."); - return; - } - - IMMDeviceEnumerator* pEnumerator = NULL; - IMMDeviceCollection* pEnumDevices = NULL; - - HRESULT 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: %i", hr) - - UINT uiCount = 0; - - 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; - - 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; - } - - CStdStringW strRawDevName(varName.pwszVal); - CStdString strDevName; - g_charsetConverter.wToUTF8(strRawDevName, strDevName); - - CLog::Log(LOGDEBUG, __FUNCTION__": found endpoint device: %s", strDevName.c_str()); - vAudioSinks.push_back(AudioSink(CStdString("WASAPI: ").append(strDevName), CStdString("wasapi:").append(strDevName))); - - SAFE_RELEASE(pDevice); - - PropVariantClear(&varName); - SAFE_RELEASE(pProperty); - } - -failed: - - if(FAILED(hr)) - CLog::Log(LOGERROR, __FUNCTION__": Failed to enumerate WASAPI endpoint devices."); - - SAFE_RELEASE(pEnumDevices); - SAFE_RELEASE(pEnumerator); -} - -//*********************************************************************************************** -void CWin32WASAPI::WaitCompletion() -{ - CSingleLock lock (m_critSection); - - if (!m_bIsAllocated) - return; - - DWORD dwTimeRemaining; - - if(!m_bPlaying) - return; // We weren't playing anyway - - //Calculate the remaining cache time and wait for it to finish. - dwTimeRemaining = (DWORD)(1000 * GetDelay()); - Sleep(dwTimeRemaining); - - m_pAudioClient->Stop(); - m_pAudioClient->Reset(); - - m_CacheLen = 0; - m_bPause = false; - m_bPlaying = false; -} - -//*********************************************************************************************** -void CWin32WASAPI::AddDataToBuffer(unsigned char* pData, unsigned int len, unsigned char* pOut) -{ - // Remap the data to the correct channels - if(m_remap.CanRemap() && !m_bPassthrough) - m_remap.Remap((void*)pData, pOut, len / m_uiBytesPerSrcFrame, m_drc); - else - memcpy(pOut, pData, len); -} - -//*********************************************************************************************** -void CWin32WASAPI::SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers) -{ - return; -} - -//*********************************************************************************************** -void CWin32WASAPI::BuildChannelMapping(int channels, enum PCMChannels* map) -{ - bool usedChannels[WASAPI_TOTAL_CHANNELS]; - - memset(usedChannels, false, sizeof(usedChannels)); - - m_uiSpeakerMask = 0; - - if(!map) - map = (PCMChannels *)wasapi_default_channel_layout[channels - 1]; - - //Build the speaker mask and note which are used. - for(int i = 0; i < channels; i++) - { - switch(map[i]) - { - case PCM_FRONT_LEFT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_LEFT; - break; - case PCM_FRONT_RIGHT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_RIGHT; - break; - case PCM_FRONT_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_CENTER; - break; - case PCM_LOW_FREQUENCY: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_LOW_FREQUENCY; - break; - case PCM_BACK_LEFT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_BACK_LEFT; - break; - case PCM_BACK_RIGHT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_BACK_RIGHT; - break; - case PCM_FRONT_LEFT_OF_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_LEFT_OF_CENTER; - break; - case PCM_FRONT_RIGHT_OF_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_FRONT_RIGHT_OF_CENTER; - break; - case PCM_BACK_CENTER: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_BACK_CENTER; - break; - case PCM_SIDE_LEFT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_SIDE_LEFT; - break; - case PCM_SIDE_RIGHT: - usedChannels[map[i]] = true; - m_uiSpeakerMask |= SPEAKER_SIDE_RIGHT; - break; - } - } - - //Assemble a compacted channel set. - for(int i = 0, j = 0; i < WASAPI_TOTAL_CHANNELS; i++) - { - if(usedChannels[i]) - { - m_SpeakerOrder[j] = wasapi_channel_order[i]; - j++; - } - } -} diff --git a/xbmc/cores/AudioRenderers/Win32WASAPI.h b/xbmc/cores/AudioRenderers/Win32WASAPI.h deleted file mode 100644 index 7fd8287c85..0000000000 --- a/xbmc/cores/AudioRenderers/Win32WASAPI.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2005-2009 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef __WIN32WASAPI_H__ -#define __WIN32WASAPI_H__ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -#include "IAudioRenderer.h" -#include "threads/CriticalSection.h" -#include "utils/PCMAmplifier.h" -#include <mmdeviceapi.h> -#include <Audioclient.h> - -extern void RegisterAudioCallback(IAudioCallback* pCallback); -extern void UnRegisterAudioCallback(); - -class CWin32WASAPI : public IAudioRenderer -{ -public: - CWin32WASAPI(); - virtual ~CWin32WASAPI(); - virtual void UnRegisterAudioCallback(); - virtual void RegisterAudioCallback(IAudioCallback* pCallback); - virtual unsigned int GetChunkLen(); - virtual float GetDelay(); - virtual float GetCacheTime(); - virtual float GetCacheTotal(); - virtual bool Initialize(IAudioCallback* pCallback, const CStdString& device, int iChannels, enum PCMChannels *channelMap, unsigned int uiSamplesPerSec, unsigned int uiBitsPerSample, bool bResample, bool bIsMusic=false, EEncoded encoded = IAudioRenderer::ENCODED_NONE); - - virtual unsigned int AddPackets(const void* data, unsigned int len); - virtual unsigned int GetSpace(); - virtual bool Deinitialize(); - virtual bool Pause(); - virtual bool Stop(); - virtual bool Resume(); - - virtual long GetCurrentVolume() const; - virtual void Mute(bool bMute); - virtual bool SetCurrentVolume(long nVolume); - virtual void SetDynamicRangeCompression(long drc) { m_drc = drc; } - virtual int SetPlaySpeed(int iSpeed); - virtual void WaitCompletion(); - virtual void SwitchChannels(int iAudioStream, bool bAudioOnAllSpeakers); - - static void EnumerateAudioSinks(AudioSinkList& vAudioSinks, bool passthrough); - -private: - void AddDataToBuffer(unsigned char* pData, unsigned int len, unsigned char* pOut); - void UpdateCacheStatus(); - void CheckPlayStatus(); - void BuildChannelMapping(int channels, enum PCMChannels* map); - - IMMDevice* m_pDevice; - IAudioClient* m_pAudioClient; - IAudioRenderClient* m_pRenderClient; - - IAudioCallback* m_pCallback; - - long m_nCurrentVolume; - long m_drc; - float m_fVolAdjustFactor; - - unsigned int m_uiChunkSize; - unsigned int m_uiSrcChunkSize; - unsigned int m_uiBufferLen; - unsigned int m_uiBytesPerFrame; - unsigned int m_uiBytesPerSrcFrame; - unsigned int m_uiBitsPerSample; - unsigned int m_uiChannels; - unsigned int m_uiAvgBytesPerSec; - unsigned int m_uiSpeakerMask; - enum PCMChannels m_SpeakerOrder[8]; - - static bool m_bIsAllocated; - bool m_bPlaying; - bool m_bPause; - bool m_bMuting; - bool m_bPassthrough; - - unsigned int m_CacheLen; - unsigned int m_LastCacheCheck; - size_t m_PreCacheSize; - - CPCMAmplifier m_pcmAmplifier; - CCriticalSection m_critSection; -}; - -#endif //__WIN32WASAPI_H__ diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.cpp deleted file mode 100644 index 0189e659d8..0000000000 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2005-2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#define AC3_ENCODE_BITRATE 640000 - -#include "DVDAudioEncoderFFmpeg.h" -#include "utils/log.h" -#include <string.h> - -CDVDAudioEncoderFFmpeg::CDVDAudioEncoderFFmpeg(): - m_CodecCtx(NULL), - m_AudioConvert(NULL), - m_Buffer(NULL), - m_TmpBuffer(NULL), - m_TmpBuffer2(NULL) -{ -} - -CDVDAudioEncoderFFmpeg::~CDVDAudioEncoderFFmpeg() -{ - Reset(); - if(m_dllAvUtil.IsLoaded()) - { - m_dllAvUtil.av_freep(&m_CodecCtx); - } - - if(m_dllAvCodec.IsLoaded()) - { - if (m_AudioConvert) - m_dllAvCodec.av_audio_convert_free(m_AudioConvert); - } - delete[] m_Buffer; - delete[] m_TmpBuffer; - delete[] m_TmpBuffer2; -} - -bool CDVDAudioEncoderFFmpeg::Initialize(unsigned int channels, enum PCMChannels *channelMap, unsigned int bitsPerSample, unsigned int sampleRate) -{ - Reset(); - if (!channelMap || !m_dllAvUtil.Load() || !m_dllAvCodec.Load()) - return false; - - m_dllAvCodec.avcodec_register_all(); - AVCodec *codec; - codec = m_dllAvCodec.avcodec_find_encoder(CODEC_ID_AC3); - if (!codec) - return false; - - /* always assume 6 channels, 5.1... m_remap will give us what we want */ - m_CodecCtx = m_dllAvCodec.avcodec_alloc_context3(codec); - m_CodecCtx->bit_rate = AC3_ENCODE_BITRATE; - m_CodecCtx->sample_rate = sampleRate; - m_CodecCtx->channels = 6; - m_CodecCtx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK; - - switch(bitsPerSample) - { - case 8: m_CodecCtx->sample_fmt = AV_SAMPLE_FMT_U8 ; break; - case 16: m_CodecCtx->sample_fmt = AV_SAMPLE_FMT_S16; break; - case 32: m_CodecCtx->sample_fmt = AV_SAMPLE_FMT_S32; break; - default: - m_dllAvUtil.av_freep(&m_CodecCtx); - return false; - } - - /* check if the sample format is supported by the encoder */ - if (codec->sample_fmts) - { - int i; - for (i = 0; codec->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) - if (m_CodecCtx->sample_fmt == codec->sample_fmts[i]) - break; - if (codec->sample_fmts[i] == AV_SAMPLE_FMT_NONE) - { - /* the input format was not supported, initiate conversion to the first - * supported format */ - CLog::Log(LOGDEBUG, "CDVDAudioEncoderFFmpeg: Initializing audio conversion for encoding"); - m_AudioConvert = m_dllAvCodec.av_audio_convert_alloc(codec->sample_fmts[0], 1, - m_CodecCtx->sample_fmt, 1, NULL, 0); - if (!m_AudioConvert) - { - m_dllAvUtil.av_freep(&m_CodecCtx); - return false; - } - m_CodecCtx->sample_fmt = codec->sample_fmts[0]; - } - } - - if (m_dllAvCodec.avcodec_open2(m_CodecCtx, codec, NULL)) - { - m_dllAvUtil.av_freep(&m_CodecCtx); - return false; - } - - /* remap the channels according to the specified channel layout */ - int index = 0; - if (m_CodecCtx->channel_layout & AV_CH_FRONT_LEFT ) m_ChannelMap[index++] = PCM_FRONT_LEFT ; - if (m_CodecCtx->channel_layout & AV_CH_FRONT_RIGHT ) m_ChannelMap[index++] = PCM_FRONT_RIGHT ; - if (m_CodecCtx->channel_layout & AV_CH_FRONT_CENTER ) m_ChannelMap[index++] = PCM_FRONT_CENTER ; - if (m_CodecCtx->channel_layout & AV_CH_LOW_FREQUENCY ) m_ChannelMap[index++] = PCM_LOW_FREQUENCY ; - if (m_CodecCtx->channel_layout & AV_CH_BACK_LEFT ) m_ChannelMap[index++] = PCM_BACK_LEFT ; - if (m_CodecCtx->channel_layout & AV_CH_BACK_RIGHT ) m_ChannelMap[index++] = PCM_BACK_RIGHT ; - if (m_CodecCtx->channel_layout & AV_CH_FRONT_LEFT_OF_CENTER ) m_ChannelMap[index++] = PCM_FRONT_LEFT_OF_CENTER ; - if (m_CodecCtx->channel_layout & AV_CH_FRONT_RIGHT_OF_CENTER) m_ChannelMap[index++] = PCM_FRONT_RIGHT_OF_CENTER; - if (m_CodecCtx->channel_layout & AV_CH_BACK_CENTER ) m_ChannelMap[index++] = PCM_BACK_CENTER ; - if (m_CodecCtx->channel_layout & AV_CH_SIDE_LEFT ) m_ChannelMap[index++] = PCM_SIDE_LEFT ; - if (m_CodecCtx->channel_layout & AV_CH_SIDE_RIGHT ) m_ChannelMap[index++] = PCM_SIDE_RIGHT ; - if (m_CodecCtx->channel_layout & AV_CH_TOP_CENTER ) m_ChannelMap[index++] = PCM_TOP_CENTER ; - if (m_CodecCtx->channel_layout & AV_CH_TOP_FRONT_LEFT ) m_ChannelMap[index++] = PCM_TOP_FRONT_LEFT ; - if (m_CodecCtx->channel_layout & AV_CH_TOP_FRONT_CENTER ) m_ChannelMap[index++] = PCM_TOP_FRONT_CENTER ; - if (m_CodecCtx->channel_layout & AV_CH_TOP_FRONT_RIGHT ) m_ChannelMap[index++] = PCM_TOP_FRONT_RIGHT ; - if (m_CodecCtx->channel_layout & AV_CH_TOP_BACK_LEFT ) m_ChannelMap[index++] = PCM_TOP_BACK_LEFT ; - if (m_CodecCtx->channel_layout & AV_CH_TOP_BACK_CENTER ) m_ChannelMap[index++] = PCM_TOP_BACK_CENTER ; - if (m_CodecCtx->channel_layout & AV_CH_TOP_BACK_RIGHT ) m_ChannelMap[index++] = PCM_TOP_BACK_RIGHT ; - - m_Remap.SetInputFormat (channels, channelMap, bitsPerSample / 8, sampleRate); - m_Remap.SetOutputFormat(index, m_ChannelMap, true); - - if (!m_Remap.CanRemap()) - { - m_dllAvUtil.av_freep(&m_CodecCtx); - return false; - } - - m_BitsPerSample = bitsPerSample; - m_NeededFrames = m_CodecCtx->frame_size; - m_NeededBytes = m_Remap.FramesToInBytes (m_NeededFrames); - m_OutputBytes = m_Remap.FramesToOutBytes(m_NeededFrames); - m_Buffer = new uint8_t[FF_MIN_BUFFER_SIZE]; - m_TmpBuffer = new uint8_t[m_OutputBytes]; - - if (m_AudioConvert) - m_TmpBuffer2 = new uint8_t[m_NeededFrames * m_CodecCtx->channels * - m_dllAvUtil.av_get_bytes_per_sample(m_CodecCtx->sample_fmt)]; - - return true; -} - -void CDVDAudioEncoderFFmpeg::Reset() -{ - m_BufferSize = 0; -} - -unsigned int CDVDAudioEncoderFFmpeg::GetBitRate() -{ - return AC3_ENCODE_BITRATE; -} - -CodecID CDVDAudioEncoderFFmpeg::GetCodecID() -{ - return CODEC_ID_AC3; -} - -unsigned int CDVDAudioEncoderFFmpeg::GetPacketSize() -{ - return m_NeededBytes; -} - -int CDVDAudioEncoderFFmpeg::Encode(uint8_t *data, int size) -{ - /* remap the data and encode it in blocks */ - if (size < (int)m_NeededBytes) - return 0; - - m_Remap.Remap(data, m_TmpBuffer, m_NeededFrames); - - if (m_AudioConvert) { - void *convInBuf[] = { m_TmpBuffer }; - int convInStr[] = { m_BitsPerSample / 8 }; - void *convOutBuf[] = { m_TmpBuffer2 }; - int convOutStr[] = { m_dllAvUtil.av_get_bytes_per_sample(m_CodecCtx->sample_fmt) }; - if (m_dllAvCodec.av_audio_convert(m_AudioConvert, convOutBuf, convOutStr, - convInBuf, convInStr, m_NeededFrames * m_CodecCtx->channels) < 0) { - CLog::Log(LOGERROR, "CDVDAudioEncoderFFmpeg: Audio conversion failed"); - m_BufferSize = 0; - return m_NeededBytes; - } - } - - short *inBuf = (short *)(m_AudioConvert ? m_TmpBuffer2 : m_TmpBuffer); - m_BufferSize = m_dllAvCodec.avcodec_encode_audio(m_CodecCtx, m_Buffer, FF_MIN_BUFFER_SIZE, inBuf); - return m_NeededBytes; -} - -int CDVDAudioEncoderFFmpeg::GetData(uint8_t **data) -{ - int size; - *data = m_Buffer; - size = m_BufferSize; - m_BufferSize = 0; - return size; -} - diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.h deleted file mode 100644 index 40be42bc42..0000000000 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/DVDAudioEncoderFFmpeg.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "IDVDAudioEncoder.h" -#include "DllAvCodec.h" -#include "DllAvFormat.h" -#include "DllAvUtil.h" - -class CDVDAudioEncoderFFmpeg: public IDVDAudioEncoder -{ -public: - CDVDAudioEncoderFFmpeg(); - virtual ~CDVDAudioEncoderFFmpeg(); - virtual bool Initialize(unsigned int channels, enum PCMChannels *channelMap, unsigned int bitsPerSample, unsigned int sampleRate); - virtual void Reset(); - - /* returns this DSPs output format */ - virtual unsigned int GetBitRate (); - virtual CodecID GetCodecID (); - virtual unsigned int GetPacketSize(); - - /* add/get packets to/from the DSP */ - virtual int Encode (uint8_t *data, int size); - virtual int GetData(uint8_t **data); -private: - DllAvCodec m_dllAvCodec; - DllAvUtil m_dllAvUtil; - - AVCodecContext *m_CodecCtx; - AVAudioConvert *m_AudioConvert; - enum PCMChannels m_ChannelMap[PCM_MAX_CH]; - CPCMRemap m_Remap; - uint8_t *m_Buffer; - uint8_t *m_TmpBuffer; - uint8_t *m_TmpBuffer2; - int m_BufferSize; - - unsigned int m_NeededFrames; - unsigned int m_NeededBytes; - unsigned int m_OutputBytes; - unsigned int m_BitsPerSample; -}; - diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/IDVDAudioEncoder.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/IDVDAudioEncoder.h deleted file mode 100644 index 566763f81c..0000000000 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Encoders/IDVDAudioEncoder.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -/* - * Copyright (C) 2005-2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "utils/PCMRemap.h" -#include "DVDStreamInfo.h" - -class IDVDAudioEncoder -{ -public: - IDVDAudioEncoder() {}; - virtual ~IDVDAudioEncoder() {}; - virtual bool Initialize(unsigned int channels, enum PCMChannels *channelMap, unsigned int bitsPerSample, unsigned int sampleRate) = 0; - virtual void Reset() = 0; - - /* returns this DSPs output format */ - virtual unsigned int GetBitRate () = 0; - virtual CodecID GetCodecID () = 0; - virtual unsigned int GetPacketSize() = 0; - - /* add/get packets to/from the DSP */ - virtual int Encode (uint8_t *data, int size) = 0; - virtual int GetData(uint8_t **data) = 0; -}; - diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Makefile.in b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Makefile.in index e81a5168f5..5423f9da8b 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/Makefile.in +++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/Makefile.in @@ -5,10 +5,8 @@ CXXFLAGS+=-DHAVE_MMX SRCS= DVDAudioCodecFFmpeg.cpp \ DVDAudioCodecLibMad.cpp \ DVDAudioCodecLPcm.cpp \ - DVDAudioCodecPassthroughFFmpeg.cpp \ - DVDAudioCodecPassthrough.cpp - DVDAudioCodecPcm.cpp \ - Encoders/DVDAudioEncoderFFmpeg.cpp + DVDAudioCodecPassthrough.cpp \ + DVDAudioCodecPcm.cpp LIB=Audio.a diff --git a/xbmc/guilib/AudioContext.cpp b/xbmc/guilib/AudioContext.cpp deleted file mode 100644 index 1ae0ccfdcb..0000000000 --- a/xbmc/guilib/AudioContext.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "system.h" -#include "AudioContext.h" -#include "GUIAudioManager.h" -#include "settings/Settings.h" -#include "settings/GUISettings.h" -#ifdef _WIN32 -#include "WINDirectSound.h" -#endif -extern HWND g_hWnd; - -#ifdef _WIN32 -static GUID g_digitaldevice; -BOOL CALLBACK DSEnumCallback( - LPGUID lpGuid, - LPCSTR lpcstrDescription, - LPCSTR lpcstrModule, - LPVOID lpContext -) -{ - if(strstr(lpcstrDescription, "Digital Output") != NULL) - { - g_digitaldevice = *lpGuid; - return false; - } - return true; -} -#endif - -CAudioContext::CAudioContext() -{ - m_bAC3EncoderActive=false; - m_iDevice=DEFAULT_DEVICE; - m_strDevice.clear(); -#ifdef HAS_AUDIO -#ifdef HAS_AUDIO_PASS_THROUGH - m_pAC97Device=NULL; -#endif - m_pDirectSoundDevice=NULL; -#endif -} - -CAudioContext::~CAudioContext() -{ -} - -// \brief Create a new device by type (DEFAULT_DEVICE, DIRECTSOUND_DEVICE, AC97_DEVICE) -void CAudioContext::SetActiveDevice(int iDevice) -{ - CStdString strAudioDev = g_guiSettings.GetString("audiooutput.audiodevice"); - - /* if device is the same, no need to bother */ -#ifdef _WIN32 - - HRESULT hr; - int iPos = strAudioDev.Find(':'); - if(iPos != CStdString::npos) - strAudioDev.erase(0, iPos+1); - - if (iDevice == DEFAULT_DEVICE) - iDevice = DIRECTSOUND_DEVICE; // default device on win32 is directsound device - if(m_iDevice == iDevice && strAudioDev.Equals(m_strDevice)) - { - if (iDevice != NONE && m_pDirectSoundDevice) - { - DSCAPS devCaps = {0}; - devCaps.dwSize = sizeof(devCaps); - HRESULT hr = m_pDirectSoundDevice->GetCaps(&devCaps); - if (SUCCEEDED(hr)) // Make sure the DirectSound interface is still valid. - return; - CLog::Log(LOGDEBUG, "%s - DirectSoundDevice no longer valid and is going to be recreated (0x%08x)", __FUNCTION__, hr); - } - } - -#else - if(m_iDevice == iDevice) - return; -#endif - - CLog::Log(LOGDEBUG, "%s - SetActiveDevice from %i to %i", __FUNCTION__, m_iDevice, iDevice); - /* deinit current device */ - RemoveActiveDevice(); - - m_iDevice=iDevice; - m_strDevice=strAudioDev; - -#ifdef HAS_AUDIO - memset(&g_digitaldevice, 0, sizeof(GUID)); - hr = DirectSoundEnumerate(DSEnumCallback, this); - if (FAILED(hr)) - CLog::Log(LOGERROR, "%s - failed to enumerate output devices (0x%08X)", __FUNCTION__, hr); - - if (iDevice==DIRECTSOUND_DEVICE - || iDevice==DIRECTSOUND_DEVICE_DIGITAL) - { - LPGUID guid = NULL; -#ifdef _WIN32 - CWDSound p_dsound; - std::vector<DSDeviceInfo > deviceList = p_dsound.GetSoundDevices(); - if (deviceList.size() == 0) - CLog::Log(LOGDEBUG, "%s - no output devices found.", __FUNCTION__); - - std::vector<DSDeviceInfo >::const_iterator iter = deviceList.begin(); - for (int i=0; iter != deviceList.end(); i++) - { - DSDeviceInfo dev = *iter; - - if (strAudioDev.Equals(dev.strDescription)) - { - guid = dev.lpGuid; - CLog::Log(LOGDEBUG, "%s - selecting %s as output devices", __FUNCTION__, dev.strDescription.c_str()); - break; - } - - ++iter; - } - if (guid == NULL) - CLog::Log(LOGDEBUG, "%s - (default playback device).", __FUNCTION__); -#else - if(iDevice == DIRECTSOUND_DEVICE_DIGITAL - && ( g_digitaldevice.Data1 || g_digitaldevice.Data2 - || g_digitaldevice.Data3 || g_digitaldevice.Data4 )) - guid = &g_digitaldevice; -#endif - - // Create DirectSound - hr = DirectSoundCreate( guid, &m_pDirectSoundDevice, NULL ); - if (FAILED(hr)) - { - CLog::Log(LOGERROR, "DirectSoundCreate() Failed (0x%08X)", hr); - return; - } - hr = m_pDirectSoundDevice->SetCooperativeLevel(g_hWnd, DSSCL_PRIORITY); - if (FAILED(hr)) - { - CLog::Log(LOGERROR, "DirectSoundDevice::SetCooperativeLevel() Failed (0x%08X)", hr); - return; - } - } - else if (iDevice == DIRECTSOUND_DEVICE_DIGITAL) - { - - } -#ifdef HAS_AUDIO_PASS_THROUGH - else if (iDevice==AC97_DEVICE) - { - // Create AC97 Device - if (FAILED(Ac97CreateMediaObject(DSAC97_CHANNEL_DIGITAL, NULL, NULL, &m_pAC97Device))) - { - CLog::Log(LOGERROR, "Failed to create digital Ac97CreateMediaObject()"); - return; - } - } -#endif - // Don't log an error if the caller specifically asked for no device - // externalplayer does this to ensure all audio devices are closed - // during external playback - else if (iDevice != NONE) - { - CLog::Log(LOGERROR, "Failed to create audio device"); - return; - } -#endif - g_audioManager.Initialize(m_iDevice); -} - -// \brief Return the active device type (NONE, DEFAULT_DEVICE, DIRECTSOUND_DEVICE, AC97_DEVICE) -int CAudioContext::GetActiveDevice() -{ - return m_iDevice; -} - -// \brief Remove the current sound device, eg. to setup new speaker config -void CAudioContext::RemoveActiveDevice() -{ - CLog::Log(LOGDEBUG, "%s - Removing device %i", __FUNCTION__, m_iDevice); - g_audioManager.DeInitialize(m_iDevice); - m_iDevice=NONE; - -#ifdef HAS_AUDIO -#ifdef HAS_AUDIO_PASS_THROUGH - SAFE_RELEASE(m_pAC97Device); -#endif - SAFE_RELEASE(m_pDirectSoundDevice); -#endif -} - -// \brief set a new speaker config -void CAudioContext::SetupSpeakerConfig(int iChannels, bool& bAudioOnAllSpeakers, bool bIsMusic) -{ - m_bAC3EncoderActive = false; - bAudioOnAllSpeakers = false; - -#ifdef HAS_AUDIO - return; //not implemented - DWORD spconfig = DSSPEAKER_USE_DEFAULT; - if (AUDIO_IS_BITSTREAM(g_guiSettings.GetInt("audiooutput.mode"))) - { - if (g_settings.m_currentVideoSettings.m_OutputToAllSpeakers && !bIsMusic) - { - bAudioOnAllSpeakers = true; - m_bAC3EncoderActive = true; - spconfig = DSSPEAKER_USE_DEFAULT; //Allows ac3 encoder should it be enabled - } - else - { - if (iChannels == 1) - spconfig = DSSPEAKER_MONO; - else if (iChannels == 2) - spconfig = DSSPEAKER_STEREO; - else - spconfig = DSSPEAKER_USE_DEFAULT; //Allows ac3 encoder should it be enabled - } - } - else // We don't want to use the Dolby Digital Encoder output. Downmix to surround instead. - { - if (iChannels == 1) - spconfig = DSSPEAKER_MONO; - else - { - // check if surround mode is allowed, if not then use normal stereo - // don't always set it to default as that enabled ac3 encoder if that is allowed in dash - // ruining quality - spconfig = DSSPEAKER_STEREO; - } - } - - DWORD spconfig_old = DSSPEAKER_USE_DEFAULT; - if(m_pDirectSoundDevice) - { - m_pDirectSoundDevice->GetSpeakerConfig(&spconfig_old); - spconfig_old = DSSPEAKER_CONFIG(spconfig_old); - } - - /* speaker config identical, no need to do anything */ - if(spconfig == spconfig_old) return; - CLog::Log(LOGDEBUG, "%s - Speakerconfig changed from %i to %i", __FUNCTION__, spconfig_old, spconfig); -#endif - - /* speaker config has changed, caller need to recreate it */ - RemoveActiveDevice(); -} - -bool CAudioContext::IsAC3EncoderActive() const -{ - return m_bAC3EncoderActive; -} - -bool CAudioContext::IsPassthroughActive() const -{ - return (m_iDevice == DIRECTSOUND_DEVICE_DIGITAL); -} - diff --git a/xbmc/guilib/AudioContext.h b/xbmc/guilib/AudioContext.h deleted file mode 100644 index b46d4f61b8..0000000000 --- a/xbmc/guilib/AudioContext.h +++ /dev/null @@ -1,76 +0,0 @@ -/*! -\file AudioContext.h -\brief -*/ - -#pragma once - -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "utils/StdString.h" - -#define DSMIXBINTYPE_STANDARD 1 -#define DSMIXBINTYPE_DMO 2 -#define DSMIXBINTYPE_AAC 3 -#define DSMIXBINTYPE_OGG 4 -#define DSMIXBINTYPE_CUSTOM 5 -#define DSMIXBINTYPE_STEREOALL 6 -#define DSMIXBINTYPE_STEREOLEFT 7 -#define DSMIXBINTYPE_STEREORIGHT 8 - -class CAudioContext -{ -public: - CAudioContext(); - virtual ~CAudioContext(); - - void SetActiveDevice(int iDevice); - int GetActiveDevice(); - -#ifdef HAS_AUDIO - LPDIRECTSOUND8 GetDirectSoundDevice() { return m_pDirectSoundDevice; } -#ifdef HAS_AUDIO_PASS_THROUGH - LPAC97MEDIAOBJECT GetAc97Device() { return m_pAC97Device; } -#endif -#endif - - void SetupSpeakerConfig(int iChannels, bool& bAudioOnAllSpeakers, bool bIsMusic=true); - bool IsAC3EncoderActive() const; - bool IsPassthroughActive() const; - - enum AUDIO_DEVICE {NONE=0, DEFAULT_DEVICE, DIRECTSOUND_DEVICE, AC97_DEVICE, DIRECTSOUND_DEVICE_DIGITAL }; -protected: - void RemoveActiveDevice(); - -#ifdef HAS_AUDIO -#ifdef HAS_AUDIO_PASS_THROUGH - LPAC97MEDIAOBJECT m_pAC97Device; -#endif - LPDIRECTSOUND8 m_pDirectSoundDevice; -#endif - - int m_iDevice; - CStdString m_strDevice; - bool m_bAC3EncoderActive; -}; - -extern CAudioContext g_audioContext; diff --git a/xbmc/guilib/GUISound.cpp b/xbmc/guilib/GUISound.cpp deleted file mode 100644 index 316792ba5a..0000000000 --- a/xbmc/guilib/GUISound.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "system.h" -#include "GUISound.h" -#include "AudioContext.h" -#include "settings/Settings.h" -#include "filesystem/File.h" -#include "utils/log.h" -#ifdef HAS_SDL_AUDIO -#include <SDL/SDL_mixer.h> -#endif -#include "filesystem/SpecialProtocol.h" -#ifndef HAS_SDL_AUDIO - -typedef struct -{ - char chunk_id[4]; - long chunksize; -} WAVE_CHUNK; - -typedef struct -{ - char riff[4]; - long filesize; - char rifftype[4]; -} WAVE_RIFFHEADER; -#else -#define GUI_SOUND_CHANNEL 0 -#endif - -CGUISound::CGUISound() -{ - m_soundBuffer=NULL; -} - -CGUISound::~CGUISound() -{ -#ifdef _WIN32 - FreeBuffer(); -#elif defined(HAS_SDL_AUDIO) - Mix_FreeChunk(m_soundBuffer); -#endif -} - -// \brief Loads a wav file by filename -bool CGUISound::Load(const CStdString& strFile) -{ -#ifdef _WIN32 - LPBYTE pbData=NULL; - WAVEFORMATEX wfx; - int size=0; - if (!LoadWav(strFile, &wfx, &pbData, &size)) - return false; - - bool bReady=(CreateBuffer(&wfx, size) && FillBuffer(pbData, size)); - - if (!bReady) - FreeBuffer(); - - delete[] pbData; - - return bReady; -#elif defined(HAS_SDL_AUDIO) - m_soundBuffer = Mix_LoadWAV(CSpecialProtocol::TranslatePath(strFile)); - if (!m_soundBuffer) - return false; - - return true; -#else - return false; -#endif -} - -// \brief Starts playback of the sound -void CGUISound::Play() -{ - if (m_soundBuffer) - { -#ifdef _WIN32 - m_soundBuffer->Play(0, 0, 0); -#elif defined(HAS_SDL_AUDIO) - Mix_PlayChannel(GUI_SOUND_CHANNEL, m_soundBuffer, 0); -#endif - } -} - -// \brief returns true if the sound is playing -bool CGUISound::IsPlaying() -{ -#ifdef _WIN32 - if (m_soundBuffer) - { - DWORD dwStatus; - m_soundBuffer->GetStatus(&dwStatus); - return (dwStatus & DSBSTATUS_PLAYING); - } - - return false; -#elif defined(HAS_SDL_AUDIO) - return Mix_Playing(GUI_SOUND_CHANNEL) != 0; -#else - return false; -#endif -} - -// \brief Stops playback if the sound -void CGUISound::Stop() -{ - if (m_soundBuffer) - { -#ifdef _WIN32 - m_soundBuffer->Stop(); -#elif defined(HAS_SDL_AUDIO) - Mix_HaltChannel(GUI_SOUND_CHANNEL); -#endif - Wait(); - } -} - -// \brief Sets the volume of the sound -void CGUISound::SetVolume(int level) -{ - if (m_soundBuffer) - { -#ifdef _WIN32 - m_soundBuffer->SetVolume(level); -#elif defined(HAS_SDL_AUDIO) - Mix_Volume(GUI_SOUND_CHANNEL, level); -#endif - } -} - -void CGUISound::Wait(uint32_t millis/*=500*/) -{ - millis /= 10; - while (IsPlaying() && millis--) - Sleep(10); -} - -#ifdef _WIN32 -bool CGUISound::CreateBuffer(LPWAVEFORMATEX wfx, int iLength) -{ - // Set up DSBUFFERDESC structure - DSBUFFERDESC dsbdesc; - memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); - dsbdesc.dwSize=sizeof(DSBUFFERDESC); - // directsound requires ctrlvolume to be set - dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME; - dsbdesc.dwBufferBytes=iLength; - dsbdesc.lpwfxFormat=wfx; - - LPDIRECTSOUND directSound=g_audioContext.GetDirectSoundDevice(); - if (!directSound) - return false; - - // Create buffer - if (FAILED(directSound->CreateSoundBuffer(&dsbdesc, &m_soundBuffer, NULL))) - { - m_soundBuffer = NULL; - CLog::Log(LOGERROR, __FUNCTION__" Creating sound buffer failed!"); - return false; - } - - // Make effects as loud as possible - m_soundBuffer->SetVolume(g_settings.m_nVolumeLevel); - - return true; -} - -bool CGUISound::FillBuffer(LPBYTE pbData, int iLength) -{ - if (!m_soundBuffer) - return false; - - LPVOID lpvWrite; - DWORD dwLength; - - if (SUCCEEDED(m_soundBuffer->Lock(0, 0, &lpvWrite, &dwLength, NULL, NULL, DSBLOCK_ENTIREBUFFER))) - { - memcpy(lpvWrite, pbData, iLength); - m_soundBuffer->Unlock(lpvWrite, dwLength, NULL, 0); - return true; - } - - CLog::Log(LOGERROR, __FUNCTION__" Filling sound buffer failed!"); - - return false; -} - -void CGUISound::FreeBuffer() -{ - if (IsPlaying()) - Stop(); - - SAFE_RELEASE(m_soundBuffer); -} - -bool CGUISound::LoadWav(const CStdString& strFile, WAVEFORMATEX* wfx, LPBYTE* ppWavData, int* pDataSize) -{ - XFILE::CFile file; - if (!file.Open(strFile)) - return false; - - // read header - WAVE_RIFFHEADER riffh; - file.Read(&riffh, sizeof(WAVE_RIFFHEADER)); - - // file valid? - if (strncmp(riffh.riff, "RIFF", 4)!=0 && strncmp(riffh.rifftype, "WAVE", 4)!=0) - { - file.Close(); - return false; - } - - long offset=0; - offset += sizeof(WAVE_RIFFHEADER); - offset -= sizeof(WAVE_CHUNK); - - // parse chunks - do - { - WAVE_CHUNK chunk; - - // always seeking to the start of a chunk - file.Seek(offset + sizeof(WAVE_CHUNK), SEEK_SET); - file.Read(&chunk, sizeof(WAVE_CHUNK)); - - if (!strncmp(chunk.chunk_id, "fmt ", 4)) - { // format chunk - memset(wfx, 0, sizeof(WAVEFORMATEX)); - file.Read(wfx, 16); - // we only need 16 bytes of the fmt chunk - if (chunk.chunksize-16>0) - file.Seek(chunk.chunksize-16, SEEK_CUR); - } - else if (!strncmp(chunk.chunk_id, "data", 4)) - { // data chunk - *ppWavData=new BYTE[chunk.chunksize+1]; - file.Read(*ppWavData, chunk.chunksize); - *pDataSize=chunk.chunksize; - - if (chunk.chunksize & 1) - offset++; - } - else - { // other chunk - unused, just skip - file.Seek(chunk.chunksize, SEEK_CUR); - } - - offset+=(chunk.chunksize+sizeof(WAVE_CHUNK)); - - if (offset & 1) - offset++; - - } while (offset+(int)sizeof(WAVE_CHUNK) < riffh.filesize); - - file.Close(); - return (*ppWavData!=NULL); -} - -#endif diff --git a/xbmc/guilib/GUISound.h b/xbmc/guilib/GUISound.h deleted file mode 100644 index d756c128d5..0000000000 --- a/xbmc/guilib/GUISound.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#pragma once - -#include "utils/StdString.h" - -#ifdef HAS_SDL_AUDIO -#include <SDL/SDL_mixer.h> -#endif - -class CGUISound -{ -public: - CGUISound(); - virtual ~CGUISound(); - - bool Load(const CStdString& strFile); - void Play(); - void Stop(); - bool IsPlaying(); - void SetVolume(int level); - void Wait(uint32_t millis = 500); - -private: -#ifdef _WIN32 - bool LoadWav(const CStdString& strFile, WAVEFORMATEX* wfx, LPBYTE* ppWavData, int* pDataSize); - bool CreateBuffer(LPWAVEFORMATEX wfx, int iLength); - bool FillBuffer(LPBYTE pbData, int iLength); - void FreeBuffer(); - - LPDIRECTSOUNDBUFFER m_soundBuffer; -#elif defined(HAS_SDL_AUDIO) - Mix_Chunk* m_soundBuffer; -#else - void *m_soundBuffer; -#endif -}; diff --git a/xbmc/guilib/Makefile.in b/xbmc/guilib/Makefile.in index 8bbbd39bed..d824caa797 100644 --- a/xbmc/guilib/Makefile.in +++ b/xbmc/guilib/Makefile.in @@ -1,5 +1,4 @@ SRCS=AnimatedGif.cpp \ - AudioContext.cpp \ DDSImage.cpp \ DirectXGraphics.cpp \ DirtyRegionSolvers.cpp \ @@ -49,7 +48,6 @@ SRCS=AnimatedGif.cpp \ GUISelectButtonControl.cpp \ GUISettingsSliderControl.cpp \ GUISliderControl.cpp \ - GUISound.cpp \ GUISpinControl.cpp \ GUISpinControlEx.cpp \ GUIStandardWindow.cpp \ diff --git a/xbmc/osx/CocoaInterface.h b/xbmc/osx/CocoaInterface.h index 0376cbe620..2d7358e1af 100644 --- a/xbmc/osx/CocoaInterface.h +++ b/xbmc/osx/CocoaInterface.h @@ -73,8 +73,6 @@ extern "C" const char *Cocoa_Paste() ; - void Cocoa_ResetAudioDevices(); - #ifdef __cplusplus } #endif diff --git a/xbmc/osx/CocoaInterface.mm b/xbmc/osx/CocoaInterface.mm index 21f312de02..e1a63b4745 100644 --- a/xbmc/osx/CocoaInterface.mm +++ b/xbmc/osx/CocoaInterface.mm @@ -40,7 +40,6 @@ #import "AutoPool.h" -#import "CoreAudio.h" // hack for Cocoa_GL_ResizeWindow //extern "C" void SDL_SetWidthHeight(int w, int h); @@ -626,50 +625,4 @@ const char *Cocoa_Paste() return NULL; } -void Cocoa_ResetAudioDevices() -{ - // Reset any devices with an AC3/DTS/SPDIF stream back to a Linear PCM - // so that they can become a default output device - CoreAudioDeviceList deviceList; - CCoreAudioHardware::GetOutputDevices(&deviceList); - for (CoreAudioDeviceList::iterator d = deviceList.begin(); d != deviceList.end(); d++) - { - CCoreAudioDevice device(*d); - AudioStreamIdList streamList; - if (device.GetStreams(&streamList)) - { - for (AudioStreamIdList::iterator s = streamList.begin(); s != streamList.end(); s++) - { - CCoreAudioStream stream; - if (stream.Open(*s)) - { - AudioStreamBasicDescription currentFormat; - if (stream.GetPhysicalFormat(¤tFormat)) - { - if (currentFormat.mFormatID == 'IAC3' || currentFormat.mFormatID == kAudioFormat60958AC3) - { - StreamFormatList formatList; - if (stream.GetAvailablePhysicalFormats(&formatList)) - { - for (StreamFormatList::iterator f = formatList.begin(); f != formatList.end(); f++) - { - if ((*f).mFormat.mFormatID == kAudioFormatLinearPCM) - { - if (stream.SetPhysicalFormat(&(*f).mFormat)) - { - sleep(1); - break; - } - } - } - } - } - } - stream.Close(); - } - } - } - } -} - #endif diff --git a/xbmc/osx/CoreAudio.cpp b/xbmc/osx/CoreAudio.cpp deleted file mode 100644 index 0a45c2903d..0000000000 --- a/xbmc/osx/CoreAudio.cpp +++ /dev/null @@ -1,1971 +0,0 @@ -#ifdef __APPLE__ -/* - * Copyright (C) 2005-2009 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#if !defined(__arm__) -#include <CoreServices/CoreServices.h> - -#include "CoreAudio.h" -#include "PlatformDefs.h" -#include "utils/log.h" -#include "math.h" - -#define MAX_CHANNEL_LABEL 15 -const char* g_ChannelLabels[] = -{ - "Unused", // kAudioChannelLabel_Unused - "Left", // kAudioChannelLabel_Left - "Right", // kAudioChannelLabel_Right - "Center", // kAudioChannelLabel_Center - "LFE", // kAudioChannelLabel_LFEScreen - "Side Left", // kAudioChannelLabel_LeftSurround - "Side Right", // kAudioChannelLabel_RightSurround - "Left Center", // kAudioChannelLabel_LeftCenter - "Right Center", // kAudioChannelLabel_RightCenter - "Back Center", // kAudioChannelLabel_CenterSurround - "Back Left", // kAudioChannelLabel_LeftSurroundDirect - "Back Right", // kAudioChannelLabel_RightSurroundDirect - "Top Center", // kAudioChannelLabel_TopCenterSurround - "Top Back Left", // kAudioChannelLabel_VerticalHeightLeft - "Top Back Center", // kAudioChannelLabel_VerticalHeightCenter - "Top Back Right", // kAudioChannelLabel_VerticalHeightRight -}; - -char* UInt32ToFourCC(UInt32* pVal) // NOT NULL TERMINATED! Modifies input value. -{ - UInt32 inVal = *pVal; - char* pIn = (char*)&inVal; - char* fourCC = (char*)pVal; - fourCC[3] = pIn[0]; - fourCC[2] = pIn[1]; - fourCC[1] = pIn[2]; - fourCC[0] = pIn[3]; - return fourCC; -} - -const char* StreamDescriptionToString(AudioStreamBasicDescription desc, CStdString& str) -{ - UInt32 formatId = desc.mFormatID; - char* fourCC = UInt32ToFourCC(&formatId); - - switch (desc.mFormatID) - { - case kAudioFormatLinearPCM: - str.Format("[%4.4s] %s%sInterleaved %u Channel %u-bit %s %s(%uHz)", - fourCC, - (desc.mFormatFlags & kAudioFormatFlagIsNonMixable) ? "" : "Mixable ", - (desc.mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? "Non-" : "", - desc.mChannelsPerFrame, - desc.mBitsPerChannel, - (desc.mFormatFlags & kAudioFormatFlagIsFloat) ? "Floating Point" : "Signed Integer", - (desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE", - (UInt32)desc.mSampleRate); - break; - case kAudioFormatAC3: - str.Format("[%4.4s] AC-3/DTS (%uHz)", - fourCC, - (desc.mFormatFlags & kAudioFormatFlagIsBigEndian) ? "BE" : "LE", - (UInt32)desc.mSampleRate); - break; - case kAudioFormat60958AC3: - str.Format("[%4.4s] AC-3/DTS for S/PDIF (%uHz)", fourCC, (UInt32)desc.mSampleRate); - break; - default: - str.Format("[%4.4s]", fourCC); - break; - } - return str.c_str(); -} - -CCoreAudioChannelLayout::CCoreAudioChannelLayout() : - m_pLayout(NULL) -{ - -} - -CCoreAudioChannelLayout::CCoreAudioChannelLayout(AudioChannelLayout& layout) : - m_pLayout(NULL) -{ - CopyLayout(layout); -} - -CCoreAudioChannelLayout::~CCoreAudioChannelLayout() -{ - if (m_pLayout) - free(m_pLayout); -} - -bool CCoreAudioChannelLayout::CopyLayout(AudioChannelLayout& layout) -{ - if (m_pLayout) - free(m_pLayout); - m_pLayout = NULL; - - // This method always produces a layout with a ChannelDescriptions structure - - OSStatus ret = 0; - UInt32 channels = GetChannelCountForLayout(layout); - UInt32 size = sizeof(AudioChannelLayout) + (channels - kVariableLengthArray) * sizeof(AudioChannelDescription); - - if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) // We can copy the whole layout - { - m_pLayout = (AudioChannelLayout*)malloc(size); - memcpy(m_pLayout, &layout, size); - } - else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) // Deconstruct the bitmap to get the layout - { - UInt32 propSize = 0; - AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize); - m_pLayout = (AudioChannelLayout*)malloc(propSize); - ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize, m_pLayout); - m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; - } - else // Convert the known layout to a custom layout - { - UInt32 propSize = 0; - AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize); - m_pLayout = (AudioChannelLayout*)malloc(propSize); - ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize, m_pLayout); - m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; - } - - return (ret == noErr); -} - -bool CCoreAudioChannelLayout::SetLayout(AudioChannelLayoutTag layoutTag) -{ - UInt32 propSize = 0; - AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layoutTag), &layoutTag, &propSize); - m_pLayout = (AudioChannelLayout*)malloc(propSize); - OSStatus ret = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layoutTag), &layoutTag, &propSize, m_pLayout); - m_pLayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions; - return (ret == noErr); -} - -AudioChannelLabel CCoreAudioChannelLayout::GetChannelLabel(UInt32 index) -{ - if (!m_pLayout || (index >= m_pLayout->mNumberChannelDescriptions)) - return kAudioChannelLabel_Unknown; - - return m_pLayout->mChannelDescriptions[index].mChannelLabel; -} - -UInt32 CCoreAudioChannelLayout::GetChannelCountForLayout(AudioChannelLayout& layout) -{ - UInt32 channels = 0; - if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) // Channels are in fixed-order('USB Order'), any combination - { - UInt32 bitmap = layout.mChannelBitmap; - for (UInt32 c = 0; c < (sizeof(layout.mChannelBitmap) << 3); c++) - { - if (bitmap & 0x1) - channels++; - bitmap >>= 1; - } - } - else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) // Channels are in any order, any combination - channels = layout.mNumberChannelDescriptions; - else // Channels are in a predefined order and combination - channels = AudioChannelLayoutTag_GetNumberOfChannels(layout.mChannelLayoutTag); - - return channels; -} - -UInt32 CCoreAudioChannelLayout::GetChannelCount() -{ - if (m_pLayout) - return GetChannelCountForLayout(*m_pLayout); - return 0; -} - -const char* CCoreAudioChannelLayout::ChannelLabelToString(UInt32 label) -{ - if (label > MAX_CHANNEL_LABEL) - return "Unknown"; - return g_ChannelLabels[label]; -} - -const char* CCoreAudioChannelLayout::ChannelLayoutToString(AudioChannelLayout& layout, CStdString& str) -{ - AudioChannelLayout* pLayout = NULL; - - if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) - { - pLayout = &layout; - } - else if (layout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) // Deconstruct the bitmap to get the layout - { - UInt32 propSize = 0; - AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize); - pLayout = (AudioChannelLayout*)calloc(propSize, 1); - AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(layout.mChannelBitmap), &layout.mChannelBitmap, &propSize, pLayout); - } - else // Predefinied layout 'tag' - { - UInt32 propSize = 0; - AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize); - pLayout = (AudioChannelLayout*)calloc(propSize, 1); - AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag, sizeof(layout.mChannelLayoutTag), &layout.mChannelLayoutTag, &propSize, pLayout); - } - - for (UInt32 c = 0; c < pLayout->mNumberChannelDescriptions; c++) - { - str += "["; - str += ChannelLabelToString(pLayout->mChannelDescriptions[c].mChannelLabel); - str += "] "; - } - - if (layout.mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions) - free(pLayout); - - return str.c_str(); -} - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CCoreAudioHardware -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -AudioDeviceID CCoreAudioHardware::FindAudioDevice(CStdString searchName) -{ - if (!searchName.length()) - return 0; - - UInt32 size = 0; - AudioDeviceID deviceId = 0; - OSStatus ret; - - if (searchName.Equals("Default Output Device")) - { - AudioDeviceID defaultDevice = GetDefaultOutputDevice(); - CLog::Log(LOGDEBUG, "CCoreAudioHardware::FindAudioDevice: " - "Returning default device [0x%04x].", (unsigned int)defaultDevice); - return defaultDevice; - } - CLog::Log(LOGDEBUG, "CCoreAudioHardware::FindAudioDevice: " - "Searching for device - %s.", searchName.c_str()); - - // Obtain a list of all available audio devices - AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, NULL); - UInt32 deviceCount = size / sizeof(AudioDeviceID); - AudioDeviceID* pDevices = new AudioDeviceID[deviceCount]; - ret = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, pDevices); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioHardware::FindAudioDevice: " - "Unable to retrieve the list of available devices. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - delete[] pDevices; - return 0; - } - - // Attempt to locate the requested device - CStdString deviceName; - for (UInt32 dev = 0; dev < deviceCount; dev++) - { - CCoreAudioDevice device; - device.Open((pDevices[dev])); - device.GetName(deviceName); - UInt32 totalChannels = device.GetTotalOutputChannels(); - CLog::Log(LOGDEBUG, "CCoreAudioHardware::FindAudioDevice: " - "Device[0x%04x] - Name: '%s', Total Ouput Channels: %u. ", - (unsigned int)pDevices[dev], deviceName.c_str(), (unsigned int)totalChannels); - if (searchName.Equals(deviceName)) - deviceId = pDevices[dev]; - if (deviceId) - break; - } - delete[] pDevices; - - return deviceId; -} - -AudioDeviceID CCoreAudioHardware::GetDefaultOutputDevice() -{ - UInt32 size = sizeof(AudioDeviceID); - AudioDeviceID deviceId = 0; - OSStatus ret = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &deviceId); - if (ret || !deviceId) // outputDevice is set to 0 if there is no audio device available, or if the default device is set to an encoded format - { - CLog::Log(LOGERROR, "CCoreAudioHardware::GetDefaultOutputDevice: " - "Unable to identify default output device. Error = 0x%08x (%4.4s).", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0; - } - return deviceId; -} - -UInt32 CCoreAudioHardware::GetOutputDevices(CoreAudioDeviceList* pList) -{ - if (!pList) - return 0; - - // Obtain a list of all available audio devices - UInt32 found = 0; - UInt32 size = 0; - AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, NULL); - UInt32 deviceCount = size / sizeof(AudioDeviceID); - AudioDeviceID* pDevices = new AudioDeviceID[deviceCount]; - OSStatus ret = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, pDevices); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioHardware::GetOutputDevices: " - "Unable to retrieve the list of available devices. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - else - { - for (UInt32 dev = 0; dev < deviceCount; dev++) - { - CCoreAudioDevice device(pDevices[dev]); - if (device.GetTotalOutputChannels() == 0) - continue; - found++; - pList->push_back(pDevices[dev]); - } - } - delete[] pDevices; - return found; -} - -bool CCoreAudioHardware::GetAutoHogMode() -{ - UInt32 val = 0; - UInt32 size = sizeof(val); - OSStatus ret = AudioHardwareGetProperty(kAudioHardwarePropertyHogModeIsAllowed, &size, &val); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioHardware::GetAutoHogMode: " - "Unable to get auto 'hog' mode. Error = 0x%08x (%4.4s).", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return (val == 1); -} - -void CCoreAudioHardware::SetAutoHogMode(bool enable) -{ - UInt32 val = enable ? 1 : 0; - OSStatus ret = AudioHardwareSetProperty(kAudioHardwarePropertyHogModeIsAllowed, sizeof(val), &val); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioHardware::SetAutoHogMode: " - "Unable to set auto 'hog' mode. Error = 0x%08x (%4.4s).", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CCoreAudioDevice -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -CCoreAudioDevice::CCoreAudioDevice() : - m_DeviceId(0), - m_Started(false), - m_Hog(-1), - m_MixerRestore(-1), - m_IoProc(NULL), - m_SampleRateRestore(0.0f), - m_BufferSizeRestore(0) -{ - -} - -CCoreAudioDevice::CCoreAudioDevice(AudioDeviceID deviceId) : - m_DeviceId(deviceId), - m_Started(false), - m_Hog(-1), - m_MixerRestore(-1), - m_IoProc(NULL), - m_SampleRateRestore(0.0f), - m_BufferSizeRestore(0) -{ - Open(m_DeviceId); -} - -CCoreAudioDevice::~CCoreAudioDevice() -{ - Close(); -} - -bool CCoreAudioDevice::Open(AudioDeviceID deviceId) -{ - m_DeviceId = deviceId; - m_BufferSizeRestore = GetBufferSize(); - CLog::Log(LOGDEBUG, "CCoreAudioDevice::Open: " - "Opened device 0x%04x. Buffer size is %d", - (unsigned int)m_DeviceId, (int)m_BufferSizeRestore); - return true; -} - -void CCoreAudioDevice::Close() -{ - if (!m_DeviceId) - return; - - Stop(); // Stop the device if it was started - - RemoveIOProc(); // Unregister the IOProc if we have one - - SetHogStatus(false); - if (m_MixerRestore > -1) // We changed the mixer status - SetMixingSupport((m_MixerRestore ? true : false)); - m_MixerRestore = -1; - - if (m_SampleRateRestore != 0.0f) - { - CLog::Log(LOGDEBUG, "CCoreAudioDevice::Close: Restoring original nominal samplerate."); - SetNominalSampleRate(m_SampleRateRestore); - m_SampleRateRestore =0.0f; - } - - if (m_BufferSizeRestore != GetBufferSize()) // Put this back the way we found it... - { - CLog::Log(LOGDEBUG, "CCoreAudioDevice::Close: Restoring original buffer size."); - SetBufferSize(m_BufferSizeRestore); - m_BufferSizeRestore = 0; - } - - CLog::Log(LOGDEBUG, "CCoreAudioDevice::Close: Closed device 0x%04x", (unsigned int)m_DeviceId); - m_DeviceId = 0; - m_IoProc = NULL; // Probably uneccessary since this is reset in RemoveIOProc - -} - -void CCoreAudioDevice::Start() -{ - if (!m_DeviceId || m_Started) - return; - - OSStatus ret = AudioDeviceStart(m_DeviceId, m_IoProc); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioDevice::Start: " - "Unable to start device. Error = 0x%08x (%4.4s).", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - else - m_Started = true; -} - -void CCoreAudioDevice::Stop() -{ - if (!m_DeviceId || !m_Started) - return; - - OSStatus ret = AudioDeviceStop(m_DeviceId, m_IoProc); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioDevice::Stop: " - "Unable to stop device. Error = 0x%08x (%4.4s).", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - m_Started = false; -} - -bool CCoreAudioDevice::AddIOProc(AudioDeviceIOProc ioProc, void* pCallbackData) -{ - if (!m_DeviceId || m_IoProc) // Only one IOProc at a time - return false; - - OSStatus ret = AudioDeviceAddIOProc(m_DeviceId, ioProc, pCallbackData); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioDevice::Stop: " - "Unable to add IOProc. Error = 0x%08x (%4.4s).", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - m_IoProc = ioProc; - CLog::Log(LOGDEBUG, "CCoreAudioDevice::AddIOProc: " - "IOProc set for device 0x%04x", (unsigned int)m_DeviceId); - return true; -} - -void CCoreAudioDevice::RemoveIOProc() -{ - if (!m_DeviceId || !m_IoProc) - return; - - Stop(); - - OSStatus ret = AudioDeviceRemoveIOProc(m_DeviceId, m_IoProc); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioDevice::RemoveIOProc: " - "Unable to remove IOProc. Error = 0x%08x (%4.4s).", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - else - CLog::Log(LOGDEBUG, "CCoreAudioDevice::AddIOProc: " - "IOProc removed for device 0x%04x", (unsigned int)m_DeviceId); - m_IoProc = NULL; // Clear the reference no matter what -} - -const char* CCoreAudioDevice::GetName(CStdString& name) -{ - if (!m_DeviceId) - return NULL; - - UInt32 size = 0; - AudioDeviceGetPropertyInfo(m_DeviceId,0, false, kAudioDevicePropertyDeviceName, &size, NULL); // TODO: Change to kAudioObjectPropertyObjectName - OSStatus ret = AudioDeviceGetProperty(m_DeviceId, 0, false, kAudioDevicePropertyDeviceName, &size, name.GetBufferSetLength(size)); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioDevice::GetName: " - "Unable to get device name - id: 0x%04x Error = 0x%08x (%4.4s)", - (unsigned int)m_DeviceId, (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return NULL; - } - return name.c_str(); -} - -const char* CCoreAudioDevice::GetName() -{ - // Use internal storage - return GetName(m_Name); -} - - -UInt32 CCoreAudioDevice::GetTotalOutputChannels() -{ - if (!m_DeviceId) - return 0; - UInt32 channels = 0; - UInt32 size = 0; - AudioDeviceGetPropertyInfo(m_DeviceId, 0, false, kAudioDevicePropertyStreamConfiguration, &size, NULL); - AudioBufferList* pList = (AudioBufferList*)malloc(size); - OSStatus ret = AudioDeviceGetProperty(m_DeviceId, 0, false, kAudioDevicePropertyStreamConfiguration, &size, pList); - if (!ret) - for(UInt32 buffer = 0; buffer < pList->mNumberBuffers; ++buffer) - channels += pList->mBuffers[buffer].mNumberChannels; - else - CLog::Log(LOGERROR, "CCoreAudioDevice::GetTotalOutputChannels: " - "Unable to get total device output channels - id: 0x%04x Error = 0x%08x (%4.4s)", - (unsigned int)m_DeviceId, (unsigned int)ret, CONVERT_OSSTATUS(ret)); - CLog::Log(LOGDEBUG, "CCoreAudioDevice::GetTotalOutputChannels: " - "Found %u channels in %u buffers", (unsigned int)channels, (unsigned int)pList->mNumberBuffers); - free(pList); - return channels; -} - -bool CCoreAudioDevice::GetStreams(AudioStreamIdList* pList) -{ - if (!pList || !m_DeviceId) - return false; - - UInt32 propertySize = 0; - Boolean writable = false; - OSStatus ret = AudioDeviceGetPropertyInfo(m_DeviceId, 0, false, kAudioDevicePropertyStreams, &propertySize, &writable); - if (ret) - return false; - UInt32 streamCount = propertySize / sizeof(AudioStreamID); - AudioStreamID* pStreamList = new AudioStreamID[streamCount]; - ret = AudioDeviceGetProperty(m_DeviceId, 0, false, kAudioDevicePropertyStreams, &propertySize, pStreamList); - if (!ret) - { - for (UInt32 stream = 0; stream < streamCount; stream++) - pList->push_back(pStreamList[stream]); - } - delete[] pStreamList; - return (ret == noErr); -} - - -bool CCoreAudioDevice::IsRunning() -{ - UInt32 isRunning = false; - UInt32 size = sizeof(isRunning); - OSStatus ret = AudioDeviceGetProperty(m_DeviceId, 0, false, kAudioDevicePropertyDeviceIsRunning, &size, &isRunning); - if (ret) - return false; - return (isRunning != 0); -} - -bool CCoreAudioDevice::SetHogStatus(bool hog) -{ - // According to Jeff Moore (Core Audio, Apple), Setting kAudioDevicePropertyHogMode - // is a toggle and the only way to tell if you do get hog mode is to compare - // the returned pid against getpid, if the match, you have hog mode, if not you don't. - if (!m_DeviceId) - return false; - - if (hog) - { - if (m_Hog == -1) // Not already set - { - CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: " - "Setting 'hog' status on device 0x%04x", (unsigned int)m_DeviceId); - OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertyHogMode, sizeof(m_Hog), &m_Hog); - if (ret || m_Hog != getpid()) - { - CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: " - "Unable to set 'hog' status. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: " - "Successfully set 'hog' status on device 0x%04x", (unsigned int)m_DeviceId); - } - } - else - { - if (m_Hog > -1) // Currently Set - { - CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetHogStatus: " - "Releasing 'hog' status on device 0x%04x", (unsigned int)m_DeviceId); - pid_t hogPid = -1; - OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertyHogMode, sizeof(hogPid), &hogPid); - if (ret || hogPid == getpid()) - { - CLog::Log(LOGERROR, "CCoreAudioDevice::SetHogStatus: " - "Unable to release 'hog' status. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - m_Hog = hogPid; // Reset internal state - } - } - return true; -} - -pid_t CCoreAudioDevice::GetHogStatus() -{ - if (!m_DeviceId) - return false; - - pid_t hogPid = -1; - UInt32 size = sizeof(hogPid); - AudioDeviceGetProperty(m_DeviceId, 0, false, kAudioDevicePropertyHogMode, &size, &hogPid); - - return hogPid; -} - -bool CCoreAudioDevice::SetMixingSupport(bool mix) -{ - if (!m_DeviceId) - return false; - int restore = -1; - if (m_MixerRestore == -1) // This is our first change to this setting. Store the original setting for restore - restore = (GetMixingSupport() ? 1 : 0); - UInt32 mixEnable = mix ? 1 : 0; - CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetMixingSupport: " - "%sabling mixing for device 0x%04x", mix ? "En" : "Dis", (unsigned int)m_DeviceId); - OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertySupportsMixing, sizeof(mixEnable), &mixEnable); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioDevice::SetMixingSupport: " - "Unable to set MixingSupport to %s. Error = 0x%08x (%4.4s)", - mix ? "'On'" : "'Off'", (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - if (m_MixerRestore == -1) - m_MixerRestore = restore; - return true; -} - -bool CCoreAudioDevice::GetMixingSupport() -{ - if (!m_DeviceId) - return false; - UInt32 val = 0; - UInt32 size = sizeof(val); - OSStatus ret = AudioDeviceGetProperty(m_DeviceId, 0, false, kAudioDevicePropertySupportsMixing, &size, &val); - if (ret) - return false; - return (val > 0); -} - -bool CCoreAudioDevice::GetPreferredChannelLayout(CCoreAudioChannelLayout& layout) -{ - if (!m_DeviceId) - return false; - - UInt32 propertySize = 0; - Boolean writable = false; - OSStatus ret = AudioDeviceGetPropertyInfo(m_DeviceId, 0, false, - kAudioDevicePropertyPreferredChannelLayout, &propertySize, &writable); - if (ret) - return false; - - void* pBuf = malloc(propertySize); - ret = AudioDeviceGetProperty(m_DeviceId, 0, false, - kAudioDevicePropertyPreferredChannelLayout, &propertySize, pBuf); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioDevice::GetPreferredChannelLayout: " - "Unable to retrieve preferred channel layout. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - else - layout.CopyLayout(*((AudioChannelLayout*)pBuf)); // Copy the result into the caller's instance - free(pBuf); - return (ret == noErr); -} - -bool CCoreAudioDevice::GetDataSources(CoreAudioDataSourceList* pList) -{ - if (!pList || !m_DeviceId) - return false; - - UInt32 propertySize = 0; - Boolean writable = false; - OSStatus ret = AudioDeviceGetPropertyInfo(m_DeviceId, 0, false, - kAudioDevicePropertyDataSources, &propertySize, &writable); - if (ret) - return false; - UInt32 sources = propertySize / sizeof(UInt32); - UInt32* pSources = new UInt32[sources]; - ret = AudioDeviceGetProperty(m_DeviceId, 0, false, - kAudioDevicePropertyDataSources, &propertySize, pSources); - if (!ret) - for (UInt32 i = 0; i < sources; i++) - pList->push_back(pSources[i]);; - delete[] pSources; - return (!ret); -} - -Float64 CCoreAudioDevice::GetNominalSampleRate() -{ - if (!m_DeviceId) - return 0.0f; - - Float64 sampleRate = 0.0f; - UInt32 size = sizeof(Float64); - OSStatus ret = AudioDeviceGetProperty(m_DeviceId, 0, false, - kAudioDevicePropertyNominalSampleRate, &size, &sampleRate); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioDevice::GetNominalSampleRate: " - "Unable to retrieve current device sample rate. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return sampleRate; -} - -bool CCoreAudioDevice::SetNominalSampleRate(Float64 sampleRate) -{ - if (!m_DeviceId || sampleRate == 0.0f) - return false; - - Float64 currentRate = GetNominalSampleRate(); - if (currentRate == sampleRate) - return true; //No need to change - - UInt32 size = sizeof(Float64); - OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, kAudioDevicePropertyNominalSampleRate, size, &sampleRate); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioDevice::SetNominalSampleRate: " - "Unable to set current device sample rate to %0.0f. Error = 0x%08x (%4.4s)", - (float)sampleRate, (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetNominalSampleRate: Changed device sample rate from %0.0f to %0.0f.", (float)currentRate, (float)sampleRate); - if (m_SampleRateRestore == 0.0f) - m_SampleRateRestore = currentRate; - - return true; -} - -UInt32 CCoreAudioDevice::GetNumLatencyFrames() -{ - UInt32 i_param, i_param_size, num_latency_frames = 0; - if (!m_DeviceId) - return 0; - - i_param_size = sizeof(uint32_t); - - // number of frames of latency in the AudioDevice - if (noErr == AudioDeviceGetProperty(m_DeviceId, 0, false, - kAudioDevicePropertyLatency, &i_param_size, &i_param)) - { - num_latency_frames += i_param; - } - - // number of frames in the IO buffers - if (noErr == AudioDeviceGetProperty(m_DeviceId, 0, false, - kAudioDevicePropertyBufferFrameSize, &i_param_size, &i_param)) - { - num_latency_frames += i_param; - } - - // number for frames in ahead the current hardware position that is safe to do IO - if (noErr == AudioDeviceGetProperty(m_DeviceId, 0, false, - kAudioDevicePropertySafetyOffset, &i_param_size, &i_param)) - { - num_latency_frames += i_param; - } - - return(num_latency_frames); -} - -UInt32 CCoreAudioDevice::GetBufferSize() -{ - if (!m_DeviceId) - return false; - - UInt32 size = 0; - UInt32 propertySize = sizeof(size); - OSStatus ret = AudioDeviceGetProperty(m_DeviceId, 0, false, - kAudioDevicePropertyBufferFrameSize, &propertySize, &size); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioDevice::GetBufferSize: " - "Unable to retrieve buffer size. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return size; -} - -bool CCoreAudioDevice::SetBufferSize(UInt32 size) -{ - if (!m_DeviceId) - return false; - - UInt32 propertySize = sizeof(size); - OSStatus ret = AudioDeviceSetProperty(m_DeviceId, NULL, 0, false, - kAudioDevicePropertyBufferFrameSize, propertySize, &size); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: " - "Unable to set buffer size. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - - if (GetBufferSize() != size) - CLog::Log(LOGERROR, "CCoreAudioDevice::SetBufferSize: Buffer size change not applied."); - else - CLog::Log(LOGDEBUG, "CCoreAudioDevice::SetBufferSize: Set buffer size to %d", (int)size); - - return (ret == noErr); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CCoreAudioStream -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -CCoreAudioStream::CCoreAudioStream() : -m_StreamId(0) -{ - m_OriginalVirtualFormat.mFormatID = 0; - m_OriginalPhysicalFormat.mFormatID = 0; -} - -CCoreAudioStream::~CCoreAudioStream() -{ - Close(); -} - -bool CCoreAudioStream::Open(AudioStreamID streamId) -{ - m_StreamId = streamId; - CLog::Log(LOGDEBUG, "CCoreAudioStream::Open: Opened stream 0x%04x.", (unsigned int)m_StreamId); - return true; -} - -// TODO: Should it even be possible to change both the physical and virtual formats, since the devices do it themselves? -void CCoreAudioStream::Close() -{ - if (!m_StreamId) - return; - - CStdString formatString; - - // Revert any format changes we made - if (m_OriginalVirtualFormat.mFormatID && m_StreamId) - { - CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: " - "Restoring original virtual format for stream 0x%04x. (%s)", - (unsigned int)m_StreamId, StreamDescriptionToString(m_OriginalVirtualFormat, formatString)); - SetVirtualFormat(&m_OriginalVirtualFormat); - } - if (m_OriginalPhysicalFormat.mFormatID && m_StreamId) - { - CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: " - "Restoring original physical format for stream 0x%04x. (%s)", - (unsigned int)m_StreamId, StreamDescriptionToString(m_OriginalPhysicalFormat, formatString)); - SetPhysicalFormat(&m_OriginalPhysicalFormat); - } - - m_OriginalPhysicalFormat.mFormatID = 0; - m_OriginalVirtualFormat.mFormatID = 0; - CLog::Log(LOGDEBUG, "CCoreAudioStream::Close: Closed stream 0x%04x.", (unsigned int)m_StreamId); - m_StreamId = 0; -} - -UInt32 CCoreAudioStream::GetDirection() -{ - if (!m_StreamId) - return 0; - UInt32 size = sizeof(UInt32); - UInt32 val = 0; - OSStatus ret = AudioStreamGetProperty(m_StreamId, 0, kAudioStreamPropertyDirection, &size, &val); - if (ret) - return 0; - return val; -} - -UInt32 CCoreAudioStream::GetTerminalType() -{ - if (!m_StreamId) - return 0; - UInt32 size = sizeof(UInt32); - UInt32 val = 0; - OSStatus ret = AudioStreamGetProperty(m_StreamId, 0, kAudioStreamPropertyTerminalType, &size, &val); - if (ret) - return 0; - return val; -} - -UInt32 CCoreAudioStream::GetNumLatencyFrames() -{ - UInt32 i_param, i_param_size, num_latency_frames = 0; - if (!m_StreamId) - return 0; - - i_param_size = sizeof(uint32_t); - - // number of frames of latency in the AudioStream - if (noErr == AudioStreamGetProperty(m_StreamId, 0, - kAudioStreamPropertyLatency, &i_param_size, &i_param)) - { - num_latency_frames += i_param; - } - - return(num_latency_frames); -} - -bool CCoreAudioStream::GetVirtualFormat(AudioStreamBasicDescription* pDesc) -{ - if (!pDesc || !m_StreamId) - return false; - UInt32 size = sizeof(AudioStreamBasicDescription); - OSStatus ret = AudioStreamGetProperty(m_StreamId, 0, - kAudioStreamPropertyVirtualFormat, &size, pDesc); - if (ret) - return false; - return true; -} - -bool CCoreAudioStream::SetVirtualFormat(AudioStreamBasicDescription* pDesc) -{ - if (!pDesc || !m_StreamId) - return false; - if (!m_OriginalVirtualFormat.mFormatID) - { - // Store the original format (as we found it) so that it can be restored later - if (!GetVirtualFormat(&m_OriginalVirtualFormat)) - { - CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: " - "Unable to retrieve current virtual format for stream 0x%04x.", (unsigned int)m_StreamId); - return false; - } - } - OSStatus ret = AudioStreamSetProperty(m_StreamId, NULL, 0, - kAudioStreamPropertyVirtualFormat, sizeof(AudioStreamBasicDescription), pDesc); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: " - "Unable to set virtual format for stream 0x%04x. Error = 0x%08x (%4.4s)", - (unsigned int)m_StreamId, (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CCoreAudioStream::GetPhysicalFormat(AudioStreamBasicDescription* pDesc) -{ - if (!pDesc || !m_StreamId) - return false; - UInt32 size = sizeof(AudioStreamBasicDescription); - OSStatus ret = AudioStreamGetProperty(m_StreamId, 0, kAudioStreamPropertyPhysicalFormat, &size, pDesc); - if (ret) - return false; - return true; -} - -bool CCoreAudioStream::SetPhysicalFormat(AudioStreamBasicDescription* pDesc) -{ - if (!pDesc || !m_StreamId) - return false; - if (!m_OriginalPhysicalFormat.mFormatID) - { - // Store the original format (as we found it) so that it can be restored later - if (!GetPhysicalFormat(&m_OriginalPhysicalFormat)) - { - CLog::Log(LOGERROR, "CCoreAudioStream::SetPhysicalFormat: " - "Unable to retrieve current physical format for stream 0x%04x.", - (unsigned int)m_StreamId); - return false; - } - } - OSStatus ret = AudioStreamSetProperty(m_StreamId, NULL, 0, - kAudioStreamPropertyPhysicalFormat, sizeof(AudioStreamBasicDescription), pDesc); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioStream::SetVirtualFormat: " - "Unable to set physical format for stream 0x%04x. Error = 0x%08x (%4.4s)", - (unsigned int)m_StreamId, (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - sleep(1); // For the change to take effect - return true; -} - -bool CCoreAudioStream::GetAvailableVirtualFormats(StreamFormatList* pList) -{ - if (!pList || !m_StreamId) - return false; - - UInt32 propertySize = 0; - Boolean writable = false; - OSStatus ret = AudioStreamGetPropertyInfo(m_StreamId, 0, - kAudioStreamPropertyAvailableVirtualFormats, &propertySize, &writable); - if (ret) - return false; - UInt32 formatCount = propertySize / sizeof(AudioStreamRangedDescription); - AudioStreamRangedDescription* pFormatList = new AudioStreamRangedDescription[formatCount]; - ret = AudioStreamGetProperty(m_StreamId, 0, - kAudioStreamPropertyAvailableVirtualFormats, &propertySize, pFormatList); - if (!ret) - { - for (UInt32 format = 0; format < formatCount; format++) - pList->push_back(pFormatList[format]); - } - delete[] pFormatList; - return (ret == noErr); -} - -bool CCoreAudioStream::GetAvailablePhysicalFormats(StreamFormatList* pList) -{ - if (!pList || !m_StreamId) - return false; - - UInt32 propertySize = 0; - Boolean writable = false; - OSStatus ret = AudioStreamGetPropertyInfo(m_StreamId, 0, - kAudioStreamPropertyAvailablePhysicalFormats, &propertySize, &writable); - if (ret) - return false; - UInt32 formatCount = propertySize / sizeof(AudioStreamRangedDescription); - AudioStreamRangedDescription* pFormatList = new AudioStreamRangedDescription[formatCount]; - ret = AudioStreamGetProperty(m_StreamId, 0, - kAudioStreamPropertyAvailablePhysicalFormats, &propertySize, pFormatList); - if (!ret) - { - for (UInt32 format = 0; format < formatCount; format++) - pList->push_back(pFormatList[format]); - } - delete[] pFormatList; - return (ret == noErr); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CCoreAudioUnit -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -CCoreAudioUnit::CCoreAudioUnit() : -m_Initialized(false), -m_Component(NULL), -m_pSource(NULL) -{ -} - -CCoreAudioUnit::~CCoreAudioUnit() -{ - Close(); -} - -bool CCoreAudioUnit::Open(ComponentDescription desc) -{ - if (m_Component) - Close(); - - // Find the required Component - Component outputComp = FindNextComponent(NULL, &desc); - if (outputComp == NULL) // Unable to find the AudioUnit we requested - { - CLog::Log(LOGERROR, "CCoreAudioUnit::Open: Unable to locate AudioUnit Component."); - return false; - } - - // Create an instance of the AudioUnit Component - OSStatus ret = OpenAComponent(outputComp, &m_Component); - if (ret) // Unable to open AudioUnit - { - CLog::Log(LOGERROR, "CCoreAudioUnit::Open: " - "Unable to open AudioUnit Component. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CCoreAudioUnit::Open(OSType type, OSType subType, OSType manufacturer) -{ - ComponentDescription desc; - desc.componentType = type; - desc.componentSubType = subType; - desc.componentManufacturer = manufacturer; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - return Open(desc); -} - - -void CCoreAudioUnit::Close() -{ - if (m_Initialized) - AudioUnitUninitialize(m_Component); - if (m_Component) - CloseComponent(m_Component); - m_Initialized = false; - m_Component = 0; - m_pSource = NULL; -} - -bool CCoreAudioUnit::Initialize() -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitInitialize(m_Component); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::Initialize: " - "Unable to Initialize AudioUnit. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - m_Initialized = true; - return true; -} - - -bool CCoreAudioUnit::GetInputFormat(AudioStreamBasicDescription* pDesc) -{ - if (!m_Component || !pDesc) - return false; - - UInt32 size = sizeof(AudioStreamBasicDescription); - OSStatus ret = AudioUnitGetProperty(m_Component, - kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, pDesc, &size); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::GetInputFormat: " - "Unable to get AudioUnit input format. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CCoreAudioUnit::GetOutputFormat(AudioStreamBasicDescription* pDesc) -{ - if (!m_Component || !pDesc) - return false; - - UInt32 size = sizeof(AudioStreamBasicDescription); - OSStatus ret = AudioUnitGetProperty(m_Component, - kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, pDesc, &size); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::GetInputFormat: " - "Unable to get AudioUnit output format. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CCoreAudioUnit::SetInputFormat(AudioStreamBasicDescription* pDesc) -{ - if (!m_Component || !pDesc) - return false; - - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, 0, pDesc, sizeof(AudioStreamBasicDescription)); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::SetInputFormat: " - "Unable to set AudioUnit input format. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CCoreAudioUnit::SetOutputFormat(AudioStreamBasicDescription* pDesc) -{ - if (!m_Component || !pDesc) - return false; - - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Output, 0, pDesc, sizeof(AudioStreamBasicDescription)); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::SetInputFormat: " - "Unable to set AudioUnit output format. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CCoreAudioUnit::SetMaxFramesPerSlice(UInt32 maxFrames) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioUnitProperty_MaximumFramesPerSlice, - kAudioUnitScope_Global, 0, &maxFrames, sizeof(UInt32)); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::SetMaxFramesPerSlice: " - "Unable to set AudioUnit max frames per slice. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CCoreAudioUnit::GetSupportedChannelLayouts(AudioChannelLayoutList* pLayouts) -{ - if (!m_Component) - return false; - if (!pLayouts) - return false; - - UInt32 propSize = 0; - Boolean writable = false; - OSStatus ret = AudioUnitGetPropertyInfo(m_Component, kAudioUnitProperty_SupportedChannelLayoutTags, - kAudioUnitScope_Input, 0, &propSize, &writable); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::GetSupportedChannelLayouts: " - "Unable to retrieve supported channel layout property info. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - UInt32 layoutCount = propSize / sizeof(AudioChannelLayoutTag); - AudioChannelLayoutTag* pSuppLayouts = new AudioChannelLayoutTag[layoutCount]; - ret = AudioUnitGetProperty(m_Component, kAudioUnitProperty_SupportedChannelLayoutTags, - kAudioUnitScope_Output, 0, pSuppLayouts, &propSize); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::GetSupportedChannelLayouts: " - "Unable to retrieve supported channel layouts. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - for (UInt32 layout = 0; layout < layoutCount; layout++) - pLayouts->push_back(pSuppLayouts[layout]); - delete[] pSuppLayouts; - return true; -} - -// Data Source Management Routines -bool CCoreAudioUnit::SetInputSource(ICoreAudioSource* pSource) -{ - m_pSource = pSource; - if (pSource) - return SetRenderProc(RenderCallback, this); - else - return SetRenderProc(NULL, NULL); // TODO: Is this correct, or is there another way to clear the render proc? -} - -bool CCoreAudioUnit::SetRenderProc(AURenderCallback callback, void* pClientData) -{ - if (!m_Component) - return false; - - AURenderCallbackStruct callbackInfo; - callbackInfo.inputProc = callback; // Function to be called each time the AudioUnit needs data - callbackInfo.inputProcRefCon = pClientData; // Pointer to be returned in the callback proc - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Input, 0, &callbackInfo, sizeof(AURenderCallbackStruct)); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::SetRenderProc: " - "Unable to set AudioUnit render callback. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -OSStatus CCoreAudioUnit::OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - if (m_pSource) - return m_pSource->Render(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); - return siInputDeviceErr; // TODO: Should we do something else here instead? -} - -OSStatus CCoreAudioUnit::RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - return ((CCoreAudioUnit*)inRefCon)->OnRender(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CAUGenericSource -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -CAUGenericSource::CAUGenericSource() -{ - -} - -CAUGenericSource::~CAUGenericSource() -{ - -} - -OSStatus CAUGenericSource::Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList) -{ - OSStatus ret = AudioUnitRender(m_Component, actionFlags, pTimeStamp, busNumber, frameCount, pBufList); - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CAUOutputDevice -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// TODO: The channel map setter/getter are inefficient - -CAUOutputDevice::CAUOutputDevice() -{ - -} - -CAUOutputDevice::~CAUOutputDevice() -{ - -} - -bool CAUOutputDevice::SetCurrentDevice(AudioDeviceID deviceId) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID)); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::SetCurrentDevice: " - "Unable to set current device. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CAUOutputDevice::GetChannelMap(CoreAudioChannelList* pChannelMap) -{ - if (!m_Component) - return false; - - UInt32 size = 0; - Boolean writable = false; - AudioUnitGetPropertyInfo(m_Component, kAudioOutputUnitProperty_ChannelMap, - kAudioUnitScope_Input, 0, &size, &writable); - UInt32 channels = size/sizeof(SInt32); - SInt32* pMap = new SInt32[channels]; - OSStatus ret = AudioUnitGetProperty(m_Component, kAudioOutputUnitProperty_ChannelMap, - kAudioUnitScope_Input, 0, pMap, &size); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioUnit::GetInputChannelMap: " - "Unable to retrieve AudioUnit input channel map. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - else - for (UInt32 i = 0; i < channels; i++) - pChannelMap->push_back(pMap[i]); - delete[] pMap; - return (!ret); -} - -bool CAUOutputDevice::SetChannelMap(CoreAudioChannelList* pChannelMap) -{ - // The number of array elements must match the number of output channels provided by the device - if (!m_Component || !pChannelMap) - return false; - UInt32 channels = pChannelMap->size(); - UInt32 size = sizeof(SInt32) * channels; - SInt32* pMap = new SInt32[channels]; - for (UInt32 i = 0; i < channels; i++) - pMap[i] = (*pChannelMap)[i]; - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioOutputUnitProperty_ChannelMap, - kAudioUnitScope_Input, 0, pMap, size); - if (ret) - CLog::Log(LOGERROR, "CCoreAudioUnit::GetBufferFrameSize: " - "Unable to get current device's buffer size. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - delete[] pMap; - return (!ret); -} - -void CAUOutputDevice::Start() -{ - // TODO: Check component status - if (m_Component && m_Initialized) - AudioOutputUnitStart(m_Component); -} - -void CAUOutputDevice::Stop() -{ - // TODO: Check component status - if (m_Component && m_Initialized) - AudioOutputUnitStop(m_Component); -} - -Float32 CAUOutputDevice::GetCurrentVolume() -{ - if (!m_Component) - return 0.0f; - - Float32 volPct = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kHALOutputParam_Volume, - kAudioUnitScope_Global, 0, &volPct); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::GetCurrentVolume: " - "Unable to get AudioUnit volume. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return volPct; -} - -bool CAUOutputDevice::SetCurrentVolume(Float32 vol) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kHALOutputParam_Volume, - kAudioUnitScope_Global, 0, vol, 0); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::SetCurrentVolume: " - "Unable to set AudioUnit volume. Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CAUOutputDevice::IsRunning() -{ - if (!m_Component) - return false; - - UInt32 isRunning = 0; - UInt32 size = sizeof(isRunning); - AudioUnitGetProperty(m_Component, kAudioOutputUnitProperty_IsRunning, - kAudioUnitScope_Global, 0, &isRunning, &size); - return (isRunning != 0); -} - -UInt32 CAUOutputDevice::GetBufferFrameSize() -{ - if (!m_Component) - return 0; - - UInt32 size = sizeof(UInt32); - UInt32 bufferSize = 0; - OSStatus ret = AudioUnitGetProperty(m_Component, kAudioDevicePropertyBufferFrameSize, - kAudioUnitScope_Input, 0, &bufferSize, &size); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioUnit::GetBufferFrameSize: " - "Unable to get current device's buffer size. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0; - } - return bufferSize; -} - -OSStatus CAUOutputDevice::OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - OSStatus ret = CCoreAudioUnit::OnRender(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CAUMatrixMixer -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -CAUMatrixMixer::CAUMatrixMixer() -{ - -} - -CAUMatrixMixer::~CAUMatrixMixer() -{ - -} - -bool CAUMatrixMixer::Open() -{ - return CCoreAudioUnit::Open(kAudioUnitType_Mixer, kAudioUnitSubType_MatrixMixer, kAudioUnitManufacturer_Apple); -} - -bool CAUMatrixMixer::Open(OSType type, OSType subType, OSType manufacturer) -{ - return Open(); -} - -OSStatus CAUMatrixMixer::Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList) -{ - OSStatus ret = CAUGenericSource::Render(actionFlags, pTimeStamp, busNumber, frameCount, pBufList); - return ret; -} - -bool CAUMatrixMixer::Initialize() -{ - bool ret = CCoreAudioUnit::Initialize(); - if (ret) - { - // Fetch the channel configuration - UInt32 dims[2]; - UInt32 size = sizeof(dims); - if (noErr != AudioUnitGetProperty(m_Component, kAudioUnitProperty_MatrixDimensions, - kAudioUnitScope_Global, 0, dims, &size)) - return false; - // Initialize global, input, and output levels - if (!SetGlobalVolume(1.0f)) - return false; - for (UInt32 i = 0; i < dims[0]; i++) - if (!SetInputVolume(i, 1.0f)) - return false; - for (UInt32 i = 0; i < dims[1]; i++) - if (!SetOutputVolume(i, 1.0f)) - return false; - } - return ret; -} - -UInt32 CAUMatrixMixer::GetInputBusCount() -{ - if (!m_Component) - return 0; - - UInt32 busCount = 0; - UInt32 size = sizeof(busCount); - OSStatus ret = AudioUnitGetProperty(m_Component, kAudioUnitProperty_BusCount, - kAudioUnitScope_Input, 0, &busCount, &size); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::GetInputBusCount: " - "Unable to get input bus count. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0; - } - return busCount; -} - -bool CAUMatrixMixer::SetInputBusCount(UInt32 busCount) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioUnitProperty_BusCount, - kAudioUnitScope_Input, 0, &busCount, sizeof(UInt32)); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::SetInputBusCount: " - "Unable to set input bus count. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -UInt32 CAUMatrixMixer::GetOutputBusCount() -{ - if (!m_Component) - return 0; - - UInt32 busCount = 0; - UInt32 size = sizeof(busCount); - OSStatus ret = AudioUnitGetProperty(m_Component, kAudioUnitProperty_BusCount, - kAudioUnitScope_Output, 0, &busCount, &size); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::GetOutputBusCount: " - "Unable to get output bus count. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0; - } - return busCount; -} - -bool CAUMatrixMixer::SetOutputBusCount(UInt32 busCount) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetProperty(m_Component, kAudioUnitProperty_BusCount, - kAudioUnitScope_Output, 0, &busCount, sizeof(UInt32)); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::SetOutputBusCount: " - "Unable to set output bus count. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUMatrixMixer::GetGlobalVolume() -{ - if (!m_Component) - return 0.0f; - - Float32 vol = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kMatrixMixerParam_Volume, - kAudioUnitScope_Global, 0xFFFFFFFF, &vol); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::GetGlobalVolume: " - "Unable to get global volume. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return vol; -} - -bool CAUMatrixMixer::SetGlobalVolume(Float32 vol) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kMatrixMixerParam_Volume, - kAudioUnitScope_Global, 0xFFFFFFFF, vol, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::SetGlobalVolume: " - "Unable to set global volume. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUMatrixMixer::GetInputVolume(UInt32 element) -{ - if (!m_Component) - return 0.0f; - - Float32 vol = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kMatrixMixerParam_Volume, - kAudioUnitScope_Input, element, &vol); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::GetInputVolume: " - "Unable to get input volume. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return vol; -} - -bool CAUMatrixMixer::SetInputVolume(UInt32 element, Float32 vol) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kMatrixMixerParam_Volume, - kAudioUnitScope_Input, element, vol, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::SetInputVolume: " - "Unable to set input volume. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUMatrixMixer::GetOutputVolume(UInt32 element) -{ - if (!m_Component) - return 0.0f; - - Float32 vol = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kMatrixMixerParam_Volume, - kAudioUnitScope_Output, element, &vol); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::GetOutputVolume: " - "Unable to get output volume. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return vol; -} - -bool CAUMatrixMixer::SetOutputVolume(UInt32 element, Float32 vol) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kMatrixMixerParam_Volume, - kAudioUnitScope_Output, element, vol, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUMatrixMixer::SetOutputVolume: " - "Unable to set output volume. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -CAUMultibandCompressor::CAUMultibandCompressor() -{ - -} - -CAUMultibandCompressor::~CAUMultibandCompressor() -{ - -} - -bool CAUMultibandCompressor::Open() -{ - return CCoreAudioUnit::Open(kAudioUnitType_Effect, kAudioUnitSubType_MultiBandCompressor, kAudioUnitManufacturer_Apple); -} - -bool CAUMultibandCompressor::Open(OSType type, OSType subType, OSType manufacturer) -{ - return Open(); -} - -OSStatus CAUMultibandCompressor::Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList) -{ - OSStatus ret = CAUGenericSource::Render(actionFlags, pTimeStamp, busNumber, frameCount, pBufList); - return ret; -} - -bool CAUMultibandCompressor::Initialize() -{ - bool ret = CCoreAudioUnit::Initialize(); - if (ret) - { - if (!SetPreGain(-30.0) || - !SetAttackTime(0.02) || - !SetReleaseTime(0.04)) - return false; - } - return ret; -} - -bool CAUMultibandCompressor::SetPostGain(Float32 gain) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kMultibandCompressorParam_Postgain, kAudioUnitScope_Global, 0, gain, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::SetPostGain: " - "Unable to set post-gain. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUMultibandCompressor::GetPostGain() -{ - if (!m_Component) - return 0.0f; - - Float32 gain = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kMultibandCompressorParam_Postgain, - kAudioUnitScope_Output, 0, &gain); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::GetPostGain: " - "Unable to get post-gain. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return gain; -} - -bool CAUMultibandCompressor::SetPreGain(Float32 gain) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kMultibandCompressorParam_Pregain, kAudioUnitScope_Global, 0, gain, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::SetPreGain: " - "Unable to set pre-gain. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUMultibandCompressor::GetPreGain() -{ - if (!m_Component) - return 0.0f; - - Float32 gain = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kMultibandCompressorParam_Pregain, - kAudioUnitScope_Output, 0, &gain); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::GetPreGain: " - "Unable to get pre-gain. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return gain; -} - -bool CAUMultibandCompressor::SetAttackTime(Float32 time) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kMultibandCompressorParam_AttackTime, kAudioUnitScope_Global, 0, time, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::SetAttackTime: " - "Unable to set attack time. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUMultibandCompressor::GetAttackTime() -{ - if (!m_Component) - return 0.0f; - - Float32 time = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kMultibandCompressorParam_AttackTime, kAudioUnitScope_Global, 0, &time); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::GetAttackTime: " - "Unable to get attack time. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return time; -} - -bool CAUMultibandCompressor::SetReleaseTime(Float32 time) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, kMultibandCompressorParam_ReleaseTime, kAudioUnitScope_Global, 0, time, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::SetReleaseTime: " - "Unable to set attack time. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUMultibandCompressor::GetReleaseTime() -{ - if (!m_Component) - return 0.0f; - - Float32 time = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, kMultibandCompressorParam_ReleaseTime, kAudioUnitScope_Global, 0, &time); - if (ret) - { - CLog::Log(LOGERROR, "CAUMultibandCompressor::GetReleaseTime: " - "Unable to get attack time. ErrCode = Error = 0x%08x (%4.4s)", - (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return time; -} - -CAUDynamicsProcessor::CAUDynamicsProcessor() -{ - -} - -CAUDynamicsProcessor::~CAUDynamicsProcessor() -{ - -} - -bool CAUDynamicsProcessor::Open() -{ - return CCoreAudioUnit::Open(kAudioUnitType_Effect, kAudioUnitSubType_DynamicsProcessor, kAudioUnitManufacturer_Apple); -} - -bool CAUDynamicsProcessor::Open(OSType type, OSType subType, OSType manufacturer) -{ - return Open(); -} - -OSStatus CAUDynamicsProcessor::Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList) -{ - OSStatus ret = CAUGenericSource::Render(actionFlags, pTimeStamp, busNumber, frameCount, pBufList); - return ret; -} - -bool CAUDynamicsProcessor::Initialize() -{ - bool ret = CCoreAudioUnit::Initialize(); - if (ret) - { - if (!SetMasterGain(0.0) || - !SetCompressionThreshold(-35.0) || - !SetHeadroom(30.0) || - !SetExpansionRatio(1.0) || - !SetExpansionThreshold(-100.0) || - !SetAttackTime(0.03) || - !SetReleaseTime(0.03)) - return false; - } - return ret; -} - -bool CAUDynamicsProcessor::SetFloatParam(UInt32 param, UInt32 element, Float32 val) -{ - if (!m_Component) - return false; - - OSStatus ret = AudioUnitSetParameter(m_Component, param, kAudioUnitScope_Global, element, val, 0); - if (ret) - { - CLog::Log(LOGERROR, "CAUDynamicsProcessor::SetFloatParam: " - "Unable to set parameter (id: %d). ErrCode = Error = 0x%08x (%4.4s)", - param, (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CAUDynamicsProcessor::GetFloatParam(UInt32 param, UInt32 element) -{ - if (!m_Component) - return 0.0f; - - Float32 val = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_Component, param, kAudioUnitScope_Global, element, &val); - if (ret) - { - CLog::Log(LOGERROR, "CAUDynamicsProcessor::GetFloatParam: " - "Unable to get parameter (id: %d). ErrCode = Error = 0x%08x (%4.4s)", - param, (unsigned int)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return val; -} - -#endif -#endif diff --git a/xbmc/osx/CoreAudio.h b/xbmc/osx/CoreAudio.h deleted file mode 100644 index 73764a06d9..0000000000 --- a/xbmc/osx/CoreAudio.h +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (C) 2005-2009 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef __COREAUDIO_H__ -#define __COREAUDIO_H__ - -#if !defined(__arm__) -#include "utils/StdString.h" - -#include <AudioUnit/AudioUnit.h> -#include <AudioToolbox/AudioToolbox.h> -#include <list> -#include <vector> - -// Forward declarations -class CCoreAudioHardware; -class CCoreAudioDevice; -class CCoreAudioStream; -class CCoreAudioUnit; - -typedef std::list<AudioDeviceID> CoreAudioDeviceList; - -// Not yet implemented -// kAudioHardwarePropertyDevices -// kAudioHardwarePropertyDefaultInputDevice -// kAudioHardwarePropertyDefaultSystemOutputDevice -// kAudioHardwarePropertyDeviceForUID - -// There is only one AudioSystemObject instance system-side. -// Therefore, all CCoreAudioHardware methods are static -class CCoreAudioHardware -{ -public: - static AudioDeviceID FindAudioDevice(CStdString deviceName); - static AudioDeviceID GetDefaultOutputDevice(); - static UInt32 GetOutputDevices(CoreAudioDeviceList* pList); - static bool GetAutoHogMode(); - static void SetAutoHogMode(bool enable); -}; - -// Not yet implemented -// kAudioDevicePropertyDeviceIsRunning, kAudioDevicePropertyDeviceIsRunningSomewhere, kAudioDevicePropertyLatency, -// kAudioDevicePropertyBufferFrameSize, kAudioDevicePropertyBufferFrameSizeRange, kAudioDevicePropertyUsesVariableBufferFrameSizes, -// kAudioDevicePropertySafetyOffset, kAudioDevicePropertyIOCycleUsage, kAudioDevicePropertyStreamConfiguration -// kAudioDevicePropertyIOProcStreamUsage, kAudioDevicePropertyPreferredChannelsForStereo, kAudioDevicePropertyPreferredChannelLayout, -// kAudioDevicePropertyAvailableNominalSampleRates, kAudioDevicePropertyActualSampleRate, -// kAudioDevicePropertyTransportType - -typedef std::list<AudioStreamID> AudioStreamIdList; -typedef std::list<UInt32> CoreAudioDataSourceList; -typedef std::vector<SInt32> CoreAudioChannelList; - -class CCoreAudioChannelLayout -{ -public: - CCoreAudioChannelLayout(); - CCoreAudioChannelLayout(AudioChannelLayout& layout); - virtual ~CCoreAudioChannelLayout(); - operator AudioChannelLayout*() {return m_pLayout;} - bool CopyLayout(AudioChannelLayout& layout); - bool SetLayout(AudioChannelLayoutTag layoutTag); - UInt32 GetChannelCount(); - AudioChannelLabel GetChannelLabel(UInt32 index); - static UInt32 GetChannelCountForLayout(AudioChannelLayout& layout); - static const char* ChannelLabelToString(UInt32 label); - static const char* ChannelLayoutToString(AudioChannelLayout& layout, CStdString& str); -protected: - AudioChannelLayout* m_pLayout; -}; - -class CCoreAudioDevice -{ -public: - CCoreAudioDevice(); - CCoreAudioDevice(AudioDeviceID deviceId); - virtual ~CCoreAudioDevice(); - - bool Open(AudioDeviceID deviceId); - void Close(); - - void Start(); - void Stop(); - bool AddIOProc(AudioDeviceIOProc ioProc, void* pCallbackData); - void RemoveIOProc(); - - AudioDeviceID GetId() {return m_DeviceId;} - const char* GetName(CStdString& name); - const char* GetName(); - UInt32 GetTotalOutputChannels(); - bool GetStreams(AudioStreamIdList* pList); - bool IsRunning(); - bool SetHogStatus(bool hog); - pid_t GetHogStatus(); - bool SetMixingSupport(bool mix); - bool GetMixingSupport(); - bool GetPreferredChannelLayout(CCoreAudioChannelLayout& layout); - bool GetDataSources(CoreAudioDataSourceList* pList); - Float64 GetNominalSampleRate(); - bool SetNominalSampleRate(Float64 sampleRate); - UInt32 GetNumLatencyFrames(); - UInt32 GetBufferSize(); - bool SetBufferSize(UInt32 size); -protected: - AudioDeviceID m_DeviceId; - bool m_Started; - pid_t m_Hog; - int m_MixerRestore; - AudioDeviceIOProc m_IoProc; - Float64 m_SampleRateRestore; - UInt32 m_BufferSizeRestore; - CStdString m_Name; -}; - -typedef std::list<AudioStreamRangedDescription> StreamFormatList; - -class CCoreAudioStream -{ -public: - CCoreAudioStream(); - virtual ~CCoreAudioStream(); - - bool Open(AudioStreamID streamId); - void Close(); - - AudioStreamID GetId() {return m_StreamId;} - UInt32 GetDirection(); - UInt32 GetTerminalType(); - UInt32 GetNumLatencyFrames(); - bool GetVirtualFormat(AudioStreamBasicDescription* pDesc); - bool GetPhysicalFormat(AudioStreamBasicDescription* pDesc); - bool SetVirtualFormat(AudioStreamBasicDescription* pDesc); - bool SetPhysicalFormat(AudioStreamBasicDescription* pDesc); - bool GetAvailableVirtualFormats(StreamFormatList* pList); - bool GetAvailablePhysicalFormats(StreamFormatList* pList); - -protected: - AudioStreamID m_StreamId; - AudioStreamBasicDescription m_OriginalVirtualFormat; - AudioStreamBasicDescription m_OriginalPhysicalFormat; -}; - -class ICoreAudioSource -{ -public: - virtual ~ICoreAudioSource() {}; - // Function to request rendered data from a data source - virtual OSStatus Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList) = 0; -}; - -typedef std::list<AudioChannelLayoutTag> AudioChannelLayoutList; - -class CCoreAudioUnit -{ -public: - CCoreAudioUnit(); - virtual ~CCoreAudioUnit(); - - virtual bool Open(ComponentDescription desc); - virtual bool Open(OSType type, OSType subType, OSType manufacturer); - virtual void Attach(AudioUnit audioUnit) {m_Component = audioUnit;} - virtual AudioUnit GetComponent(){return m_Component;} - virtual void Close(); - virtual bool Initialize(); - virtual bool IsInitialized() {return m_Initialized;} - virtual bool SetInputSource(ICoreAudioSource* pSource); - virtual bool GetInputFormat(AudioStreamBasicDescription* pDesc); - virtual bool GetOutputFormat(AudioStreamBasicDescription* pDesc); - virtual bool SetInputFormat(AudioStreamBasicDescription* pDesc); - virtual bool SetOutputFormat(AudioStreamBasicDescription* pDesc); - virtual bool SetMaxFramesPerSlice(UInt32 maxFrames); - virtual bool GetSupportedChannelLayouts(AudioChannelLayoutList* pLayouts); -protected: - bool SetRenderProc(AURenderCallback callback, void* pClientData); - static OSStatus RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - virtual OSStatus OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - - ICoreAudioSource* m_pSource; - AudioUnit m_Component; - bool m_Initialized; -}; - -class CAUGenericSource : public CCoreAudioUnit, public ICoreAudioSource -{ -public: - CAUGenericSource(); - virtual ~CAUGenericSource(); - virtual OSStatus Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList); -}; - -class CAUOutputDevice : public CCoreAudioUnit -{ -public: - CAUOutputDevice(); - virtual ~CAUOutputDevice(); - bool SetCurrentDevice(AudioDeviceID deviceId); - bool GetChannelMap(CoreAudioChannelList* pChannelMap); - bool SetChannelMap(CoreAudioChannelList* pChannelMap); - UInt32 GetBufferFrameSize(); - - void Start(); - void Stop(); - bool IsRunning(); - - Float32 GetCurrentVolume(); - bool SetCurrentVolume(Float32 vol); -protected: - virtual OSStatus OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); -}; - -class CAUMatrixMixer : public CAUGenericSource -{ -public: - CAUMatrixMixer(); - virtual ~CAUMatrixMixer(); - bool Open(OSType type, OSType subType, OSType manufacturer); - bool Open(); - OSStatus Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList); - bool Initialize(); - - UInt32 GetInputBusCount(); - bool SetInputBusCount(UInt32 busCount); - UInt32 GetOutputBusCount(); - bool SetOutputBusCount(UInt32 busCount); - - Float32 GetGlobalVolume(); - bool SetGlobalVolume(Float32 vol); - Float32 GetInputVolume(UInt32 element); - bool SetInputVolume(UInt32 element, Float32 vol); - Float32 GetOutputVolume(UInt32 element); - bool SetOutputVolume(UInt32 element, Float32 vol); -protected: -}; - -class CAUMultibandCompressor : public CAUGenericSource -{ -public: - CAUMultibandCompressor(); - virtual ~CAUMultibandCompressor(); - - bool Open(OSType type, OSType subType, OSType manufacturer); - bool Open(); - - OSStatus Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList); - bool Initialize(); - - bool SetPostGain(Float32 gain); - Float32 GetPostGain(); - bool SetPreGain(Float32 gain); - Float32 GetPreGain(); - bool SetAttackTime(Float32 time); - Float32 GetAttackTime(); - bool SetReleaseTime(Float32 time); - Float32 GetReleaseTime(); - -protected: -}; - -class CAUDynamicsProcessor : public CAUGenericSource -{ -public: - CAUDynamicsProcessor(); - virtual ~CAUDynamicsProcessor(); - - bool Open(OSType type, OSType subType, OSType manufacturer); - bool Open(); - - OSStatus Render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* pTimeStamp, UInt32 busNumber, UInt32 frameCount, AudioBufferList* pBufList); - bool Initialize(); - - bool SetCompressionThreshold(Float32 db) {return SetFloatParam(kDynamicsProcessorParam_Threshold, 0, db);} - Float32 SetCompressionThreshold() {return GetFloatParam(kDynamicsProcessorParam_Threshold, 0);} - bool SetHeadroom(Float32 db) {return SetFloatParam(kDynamicsProcessorParam_HeadRoom, 0, db);} - Float32 GetHeadroom() {return GetFloatParam(kDynamicsProcessorParam_HeadRoom, 0);} - bool SetExpansionRatio(Float32 ratio) {return SetFloatParam(kDynamicsProcessorParam_ExpansionRatio, 0, ratio);} - Float32 GetExpansionRatio() {return GetFloatParam(kDynamicsProcessorParam_ExpansionRatio, 0);} - bool SetExpansionThreshold(Float32 ratio) {return SetFloatParam(kDynamicsProcessorParam_ExpansionThreshold, 0, ratio);} - Float32 GetExpansionThreshold() {return GetFloatParam(kDynamicsProcessorParam_ExpansionThreshold, 0);} - bool SetAttackTime(Float32 time) {return SetFloatParam(kDynamicsProcessorParam_AttackTime, 0, time);} - Float32 GetAttackTime() {return GetFloatParam(kDynamicsProcessorParam_AttackTime, 0);} - bool SetReleaseTime(Float32 time) {return SetFloatParam(kDynamicsProcessorParam_ReleaseTime, 0, time);} - Float32 GetReleaseTime() {return GetFloatParam(kDynamicsProcessorParam_ReleaseTime, 0);} - bool SetMasterGain(Float32 gain) {return SetFloatParam(kDynamicsProcessorParam_MasterGain, 0, gain);} - Float32 GetMasterGain() {return GetFloatParam(kDynamicsProcessorParam_MasterGain, 0);} - -protected: - bool SetFloatParam(UInt32 param, UInt32 element, Float32 val); - Float32 GetFloatParam(UInt32 param, UInt32 element); -}; - -// Helper Functions -char* UInt32ToFourCC(UInt32* val); -const char* StreamDescriptionToString(AudioStreamBasicDescription desc, CStdString& str); - -#define CONVERT_OSSTATUS(x) UInt32ToFourCC((UInt32*)&ret) - -#endif // __arm__ -#endif // __COREAUDIO_H__ diff --git a/xbmc/osx/CoreAudioSoundManager.cpp b/xbmc/osx/CoreAudioSoundManager.cpp deleted file mode 100644 index 64a312e8a2..0000000000 --- a/xbmc/osx/CoreAudioSoundManager.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (C) 2005-2009 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifdef __APPLE__ - -#include "CoreAudioSoundManager.h" -#include "PlatformDefs.h" -#include "Log.h" - -struct core_audio_sound -{ - UInt32 ref_count; - UInt32 play_count; - UInt32 total_frames; - AudioBufferList* buffer_list; -}; - -typedef clock_t core_audio_timestamp; - -struct core_audio_sound_event -{ - core_audio_sound* sound; - core_audio_timestamp play_time; // Don't play before - core_audio_timestamp expire_time; // Stop playing no later than - UInt32 offset; -}; - -CCoreAudioSoundManager::CCoreAudioSoundManager() : - m_pCurrentEvent(NULL), - m_RestartOutputUnit(false) -{ - -} - -CCoreAudioSoundManager::~CCoreAudioSoundManager() -{ - Stop(); -} - -bool CCoreAudioSoundManager::Initialize(CStdString deviceName) -{ - // Attempt to find the configured output device - AudioDeviceID outputDevice = CCoreAudioHardware::FindAudioDevice(deviceName); - if (!outputDevice) // Fall back to the default device if no match is found - { - CLog::Log(LOGWARNING, "CCoreAudioSoundManager::Initialize: Unable to locate configured device, falling-back to the system default."); - outputDevice = CCoreAudioHardware::GetDefaultOutputDevice(); - if (!outputDevice) // Not a lot to be done with no device. - { - CLog::Log(LOGERROR, "CCoreAudioSoundManager::Initialize: No default device found. Unable to initialize."); - return false; - } - } - - // Attach our output object to the device - if (!m_OutputDevice.Open(outputDevice)) - return false; - - // Create the Output AudioUnit Component - if (!m_OutputUnit.Open(kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple)) - return false; - - // Hook the Ouput AudioUnit to the selected device - if (!m_OutputUnit.SetCurrentDevice(outputDevice)) - return false; - - // Set up output format (32-bit float, 2-channel, non-interleaved) - m_OutputFormat.mSampleRate = 44100.0; - m_OutputFormat.mChannelsPerFrame = 2; - m_OutputFormat.mFormatID = kAudioFormatLinearPCM; - m_OutputFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved; - m_OutputFormat.mBitsPerChannel = 8 * sizeof(float); - m_OutputFormat.mBytesPerFrame = sizeof(float); - m_OutputFormat.mFramesPerPacket = 1; - m_OutputFormat.mBytesPerPacket = m_OutputFormat.mBytesPerFrame * m_OutputFormat.mFramesPerPacket; - if (!m_OutputUnit.SetInputFormat(&m_OutputFormat)) - return false; - - // Configure the maximum number of frames that the AudioUnit will ask to process at one time. - // If this is not called, there is no guarantee that the callback will ever be called. - UInt32 bufferFrames = m_OutputUnit.GetBufferFrameSize(); // Size of the output buffer, in Frames - if (!m_OutputUnit.SetMaxFramesPerSlice(bufferFrames)) - return false; - - // Setup the callback function that the AudioUnit will use to request data - if (!m_OutputUnit.SetRenderProc(RenderCallback, this)) - return false; - - // Initialize the Output AudioUnit - if (!m_OutputUnit.Initialize()) - return false; - - // All went as planned - return true; -} - -void CCoreAudioSoundManager::Run() -{ - AudioDeviceAddPropertyListener(m_OutputDevice.GetId(), 0, false, kAudioDevicePropertyHogMode, PropertyChangeCallback, this); // If this fails, there is not a whole lot to be done - m_OutputUnit.Start(); - CLog::Log(LOGDEBUG, "CCoreAudioSoundManager::Run: SoundManager is now running."); -} - -void CCoreAudioSoundManager::Stop() -{ - if (!m_OutputUnit.IsRunning()) - return; - - m_OutputUnit.Stop(); - AudioDeviceRemovePropertyListener(m_OutputDevice.GetId(), 0, false, kAudioDevicePropertyHogMode, PropertyChangeCallback); // No longer need to know if the device is hogged - // TODO: Clean up leftover event(s) - CLog::Log(LOGDEBUG, "CCoreAudioSoundManager::Stop: SoundManager has been stopped."); -} - -CoreAudioSoundRef CCoreAudioSoundManager::RegisterSound(const CStdString& fileName) -{ - return LoadSoundFromFile(fileName); -} - -void CCoreAudioSoundManager::UnregisterSound(CoreAudioSoundRef soundRef) -{ - if (!soundRef) - return; - - core_audio_sound* pSound = soundRef; - if (!--pSound->ref_count && !pSound->play_count) // Release the caller's reference and see if the object is ready to be freed - { - delete pSound->buffer_list; - delete pSound; - } -} - -void CCoreAudioSoundManager::PlaySound(CoreAudioSoundRef soundRef) -{ - if (!soundRef) - return; - - // Restart the output AudioUnit if necessary - if (m_RestartOutputUnit) // This flag is set by the property change notification handler to work around an OSX 10.4 quirk/bug. - { // It will re-init the callback thread for the AudioUnit after hog-mode has been released. - m_OutputUnit.Stop(); - m_OutputUnit.Start(); - m_RestartOutputUnit = false; - } - - if (!m_pCurrentEvent) - { - // TODO: Build queue and/or mix parallel sounds. For now just boot the currently playing sound and replace it. - // TODO: Not thread-safe. Going to cause trouble. - - // Create a new 'event' object to hold playback info - core_audio_sound_event* pEvent = new core_audio_sound_event; - pEvent->sound = soundRef; - pEvent->offset = 0; // Start at the beginning - - pEvent->sound->play_count++; - m_pCurrentEvent = pEvent; // TODO: This can create a memory leak if we already had one - } -} - -////////////////////////////////////////////////////////////////////////////////////////////// -// Private Methods -////////////////////////////////////////////////////////////////////////////////////////////// -OSStatus CCoreAudioSoundManager::OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - if (m_pCurrentEvent) // Do we have a sound event queued to play? - { - core_audio_sound_event* pEvent = m_pCurrentEvent; // Grab reference in case the event gets changed while we work - UInt32 framesAvailable = pEvent->sound->total_frames - pEvent->offset; - // TODO: Find a better way to manage time references - if (pEvent->offset < pEvent->sound->total_frames) // Do we have any (unexpired) data left to give. - { - if (framesAvailable < inNumberFrames) // Do we have enough data to fill the complete request - inNumberFrames = framesAvailable; // Truncate request to available data length - for (int i = 0; i < ioData->mNumberBuffers; i++) - { - UInt32 frameLen = m_OutputFormat.mBytesPerFrame; - unsigned char* pIn = (unsigned char*)pEvent->sound->buffer_list->mBuffers[i].mData; - memcpy(ioData->mBuffers[i].mData, &pIn[pEvent->offset * frameLen], inNumberFrames * frameLen); // Copy out the requested number of frames - ioData->mBuffers[i].mDataByteSize = inNumberFrames * frameLen; // Update to reflect actual date - } - pEvent->offset += inNumberFrames; // Update position in current buffer - if (m_pCurrentEvent != pEvent) // This sound has been canceled - delete pEvent; - } - else // No (unexpired) data left in this buffer. Free it. - { - // TODO: reference counting needs work - pEvent->sound->play_count--; // Allow the sound to be deleted. We are done with it. - if (!pEvent->sound->play_count && !m_pCurrentEvent->sound->ref_count) // Try and help out if all references have been released - UnregisterSound(pEvent->sound); - delete pEvent; - if (pEvent == m_pCurrentEvent) - m_pCurrentEvent = NULL; - } - } - else // No current buffer. notify caller and return. - { - ioData->mBuffers[0].mDataByteSize = ioData->mBuffers[0].mDataByteSize = 0; - } - return noErr; -} - -OSStatus CCoreAudioSoundManager::RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) -{ - return ((CCoreAudioSoundManager*)inRefCon)->OnRender(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); // Hand over to instance memeber -} - -OSStatus CCoreAudioSoundManager::PropertyChangeCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) -{ - CCoreAudioSoundManager* pThis = (CCoreAudioSoundManager*)inClientData; - pid_t hogPid = pThis->m_OutputDevice.GetHogStatus(); - if (hogPid > -1) // Device is hogged. - { - CLog::Log(LOGWARNING, "CCoreAudioSoundManager: Someone has hogged the output device. Stopping until it is released."); - pThis->m_OutputUnit.Stop(); - } - else // Device has been released. - { - CLog::Log(LOGWARNING, "CCoreAudioSoundManager: The output device has been released. Resuming."); - pThis->m_RestartOutputUnit = true; // This will cause the PlaySound method to restart the AudioUnit before queuing up the next sound. - // It is needed to work around a bug in the OSX 10.4 AudioUnit code that incorrectly reports a successful start. - } - return noErr; -} - -core_audio_sound* CCoreAudioSoundManager::LoadSoundFromFile(const CStdString& fileName) -{ - FSRef fileRef; - UInt32 size = 0; - ExtAudioFileRef audioFile; - OSStatus ret = FSPathMakeRef((const UInt8*) fileName.c_str(), &fileRef, false); - ret = ExtAudioFileOpen(&fileRef, &audioFile); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioSoundManager::LoadSoundFromFile: Unable to open source file (%s). Error = 0x%08x (%4.4s)", fileName.c_str(), ret, CONVERT_OSSTATUS(ret)); - return NULL; - } - - core_audio_sound* pSound = new core_audio_sound; - - // Retrieve the format of the source file - AudioStreamBasicDescription inputFormat; - size = sizeof(inputFormat); - ret = ExtAudioFileGetProperty(audioFile, kExtAudioFileProperty_FileDataFormat, &size, &inputFormat); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioSoundManager::LoadSoundFromFile: Unable to fetch source file format. Error = 0x%08x (%4.4s)", ret, CONVERT_OSSTATUS(ret)); - delete pSound; - return NULL; - } - - // Set up format conversion. This is the format that will be produced by Read/Write calls. - // Here we use the same format provided to the output AudioUnit - ret = ExtAudioFileSetProperty(audioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &m_OutputFormat); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioSoundManager::LoadSoundFromFile: Unable to set conversion format. Error = 0x%08x (%4.4s)", ret, CONVERT_OSSTATUS(ret)); - delete pSound; - return NULL; - } - - // Retrieve the file size (in terms of the file's sample-rate, not the output sample-rate) - UInt64 totalFrames; - size = sizeof(totalFrames); - ret = ExtAudioFileGetProperty(audioFile, kExtAudioFileProperty_FileLengthFrames, &size, &totalFrames); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioSoundManager::LoadSoundFromFile: Unable to fetch source file size. Error = 0x%08x (%4.4s)", ret, CONVERT_OSSTATUS(ret)); - delete pSound; - return NULL; - } - - // Calculate the total number of converted frames to be read - totalFrames *= (float)m_OutputFormat.mSampleRate / (float)inputFormat.mSampleRate; // TODO: Verify the accuracy of this - - // Allocate AudioBuffers - UInt32 channelCount = m_OutputFormat.mChannelsPerFrame; - pSound->buffer_list = (AudioBufferList*)calloc(1, sizeof(AudioBufferList) + sizeof(AudioBuffer) * (channelCount - kVariableLengthArray)); - pSound->buffer_list->mNumberBuffers = channelCount; // One buffer per channel for deinterlaced pcm - float* buffers = (float*)calloc(1, sizeof(float) * totalFrames * channelCount); - for(int i = 0; i < channelCount; i++) - { - pSound->buffer_list->mBuffers[i].mNumberChannels = 1; // One channel per buffer for deinterlaced pcm - pSound->buffer_list->mBuffers[i].mData = buffers + (totalFrames * i); - pSound->buffer_list->mBuffers[i].mDataByteSize = totalFrames * sizeof(float); - } - - // Read the entire file - // TODO: Should we limit the total file length? - UInt32 readFrames = totalFrames; - ret = ExtAudioFileRead(audioFile, &readFrames, pSound->buffer_list); - if (ret) - { - CLog::Log(LOGERROR, "CCoreAudioSoundManager::LoadSoundFromFile: Unable to read from file (%s). Error = 0x%08x (%4.4s)", fileName.c_str(), ret, CONVERT_OSSTATUS(ret)); - delete pSound; - return NULL; - } - pSound->total_frames = readFrames; // Store the actual number of frames read from the file. Rounding errors in calcuating the converted number of frames can truncate the read. - - // TODO: What do we do with files with more than 2 channels. Currently we just copy the first two and dump the rest. - if (inputFormat.mChannelsPerFrame == 1) // Copy Left channel into Right if the source file is Mono - memcpy(pSound->buffer_list->mBuffers[1].mData, pSound->buffer_list->mBuffers[0].mData, pSound->buffer_list->mBuffers[0].mDataByteSize); - - ret = ExtAudioFileDispose(audioFile); // Close the file. We have what we need. Not a lot to be done on failure. - if (ret) - CLog::Log(LOGERROR, "CCoreAudioSoundManager::LoadSoundFromFile: Unable to close file (%s). Error = 0x%08x (%4.4s)", fileName.c_str(), ret, CONVERT_OSSTATUS(ret)); - - pSound->ref_count = 1; // The caller holds a reference to this object now - pSound->play_count = 0; - - return pSound; -} - -#endif
\ No newline at end of file diff --git a/xbmc/osx/CoreAudioSoundManager.h b/xbmc/osx/CoreAudioSoundManager.h deleted file mode 100644 index 8455b10495..0000000000 --- a/xbmc/osx/CoreAudioSoundManager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2005-2009 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef __CORE_AUDIO_SOUND_MANAGER_H__ -#define __CORE_AUDIO_SOUND_MANAGER_H__ - -#include "CoreAudio.h" - -struct core_audio_sound; -struct core_audio_sound_event; - -typedef core_audio_sound* CoreAudioSoundRef; // Opaque reference for clients - -class CCoreAudioSoundManager -{ -public: - CCoreAudioSoundManager(); - ~CCoreAudioSoundManager(); - bool Initialize(CStdString deviceName); - void Run(); - void Stop(); - CoreAudioSoundRef RegisterSound(const CStdString& fileName); - void UnregisterSound(CoreAudioSoundRef soundRef); - void PlaySound(CoreAudioSoundRef soundRef); -protected: - core_audio_sound_event* m_pCurrentEvent; - - CCoreAudioDevice m_OutputDevice; - CCoreAudioUnit m_OutputUnit; - AudioStreamBasicDescription m_OutputFormat; - bool m_RestartOutputUnit; - - core_audio_sound* LoadSoundFromFile(const CStdString& fileName); - static OSStatus RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - OSStatus OnRender(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); - static OSStatus PropertyChangeCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData); -}; - -#endif // __CORE_AUDIO_SOUND_MANAGER_H__ diff --git a/xbmc/osx/IOSCoreAudio.cpp b/xbmc/osx/IOSCoreAudio.cpp deleted file mode 100644 index 7106a9e82f..0000000000 --- a/xbmc/osx/IOSCoreAudio.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright (C) 2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#if defined(__APPLE__) && defined(__arm__) -#include <math.h> - -#include "IOSCoreAudio.h" -#include "PlatformDefs.h" -#include "utils/log.h" - -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -char* IOSUInt32ToFourCC(UInt32* pVal) // NOT NULL TERMINATED! Modifies input value. -{ - UInt32 inVal = *pVal; - char* pIn = (char*)&inVal; - char* fourCC = (char*)pVal; - fourCC[3] = pIn[0]; - fourCC[2] = pIn[1]; - fourCC[1] = pIn[2]; - fourCC[0] = pIn[3]; - return fourCC; -} - -const char* IOSStreamDescriptionToString(AudioStreamBasicDescription desc, CStdString& str) -{ - UInt32 formatId = desc.mFormatID; - char* fourCC = IOSUInt32ToFourCC(&formatId); - - switch (desc.mFormatID) - { - case kAudioFormatLinearPCM: - str.Format("[%4.4s] %s%u Channel %u-bit %s (%uHz)", - fourCC, - (desc.mFormatFlags & kAudioFormatFlagIsNonMixable) ? "" : "Mixable ", - desc.mChannelsPerFrame, - desc.mBitsPerChannel, - (desc.mFormatFlags & kAudioFormatFlagIsFloat) ? "Floating Point" : "Signed Integer", - (UInt32)desc.mSampleRate); - break; - case kAudioFormatAC3: - str.Format("[%4.4s] AC-3/DTS (%uHz)", fourCC, (UInt32)desc.mSampleRate); - break; - case kAudioFormat60958AC3: - str.Format("[%4.4s] AC-3/DTS for S/PDIF (%uHz)", fourCC, (UInt32)desc.mSampleRate); - break; - default: - str.Format("[%4.4s]", fourCC); - break; - } - return str.c_str(); -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CIOSCoreAudioHardware -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -AudioComponentInstance CIOSCoreAudioHardware::FindAudioDevice(CStdString searchName) -{ - if (!searchName.length()) - return 0; - - AudioComponentInstance defaultDevice = GetDefaultOutputDevice(); - CLog::Log(LOGDEBUG, "CIOSCoreAudioHardware::FindAudioDevice: Returning default device [0x%04x].", (uint32_t)defaultDevice); - - return defaultDevice; -} - -AudioComponentInstance CIOSCoreAudioHardware::GetDefaultOutputDevice() -{ - AudioComponentInstance ret = (AudioComponentInstance)1; - - return ret; - - /* - OSStatus ret; - AudioComponentInstance audioUnit; - - // Describe audio component - AudioComponentDescription desc; - desc.componentType = kAudioUnitType_Output; - desc.componentSubType = kAudioUnitSubType_RemoteIO; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - - // Get component - AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc); - - // Get audio units - ret = AudioComponentInstanceNew(inputComponent, &audioUnit); - - if (ret) { - CLog::Log(LOGERROR, "CIOSCoreAudioHardware::GetDefaultOutputDevice: Unable to identify default output device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return 0; - } - - return audioUnit; - */ -} - -UInt32 CIOSCoreAudioHardware::GetOutputDevices(IOSCoreAudioDeviceList* pList) -{ - if (!pList) - return 0; - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// CIOSCoreAudioDevice -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -CIOSCoreAudioDevice::CIOSCoreAudioDevice() : - m_AudioUnit(0), - m_MixerUnit(0) -{ - -} - -CIOSCoreAudioDevice::CIOSCoreAudioDevice(AudioComponentInstance deviceId) -{ -} - -CIOSCoreAudioDevice::~CIOSCoreAudioDevice() -{ - Stop(); -} - -void CIOSCoreAudioDevice::SetupInfo() -{ - AudioStreamBasicDescription pDesc; - CStdString formatString; - - if(m_AudioUnit) - { - if(!GetFormat(m_AudioUnit, kAudioUnitScope_Output, kInputBus, &pDesc)) - return; - - CLog::Log(LOGDEBUG, "CIOSCoreAudioDevice::SetupInfo: Remote/IO Output Stream Bus %d Format %s", - kInputBus, (char*)IOSStreamDescriptionToString(pDesc, formatString)); - - if(!GetFormat(m_AudioUnit, kAudioUnitScope_Input, kOutputBus, &pDesc)) - return; - - CLog::Log(LOGDEBUG, "CIOSCoreAudioDevice::SetupInfo: Remote/IO Input Stream Bus %d Format %s", - kInputBus, (char*)IOSStreamDescriptionToString(pDesc, formatString)); - } - - if(m_MixerUnit) - { - if(!GetFormat(m_AudioUnit, kAudioUnitScope_Input, kOutputBus, &pDesc)) - return; - - CLog::Log(LOGDEBUG, "CIOSCoreAudioDevice::SetupInfo: Remote/IO Output Stream Bus %d Format %s", - kInputBus, (char*)IOSStreamDescriptionToString(pDesc, formatString)); - - if(!GetFormat(m_MixerUnit, kAudioUnitScope_Input, kOutputBus, &pDesc)) - return; - - CLog::Log(LOGDEBUG, "CIOSCoreAudioDevice::SetupInfo: Mixer Input Stream Bus %d Format %s", - kOutputBus, (char*)IOSStreamDescriptionToString(pDesc, formatString)); - - if(!GetFormat(m_MixerUnit, kAudioUnitScope_Input, kInputBus, &pDesc)) - return; - - CLog::Log(LOGDEBUG, "CIOSCoreAudioDevice::SetupInfo: Mixer Input Stream Bus %d Format %s", - kInputBus, (char*)IOSStreamDescriptionToString(pDesc, formatString)); - } - -} - -bool CIOSCoreAudioDevice::Init(bool bPassthrough, AudioStreamBasicDescription* pDesc, AURenderCallback renderCallback, void *pClientData) -{ - OSStatus ret; - AudioComponent audioComponent; - AudioComponentDescription desc; - - m_AudioUnit = 0; - m_MixerUnit = 0; - m_Passthrough = bPassthrough; - - /* - ret = AudioSessionInitialize(NULL, NULL, NULL, NULL); - if (ret) { - CLog::Log(LOGERROR, "CIOSCoreAudioHardware::Init: Unable to initialize session. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - ret = AudioSessionSetActive(true); - if (ret) { - CLog::Log(LOGERROR, "CIOSCoreAudioHardware::Init: Unable to set session active. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - */ - - // Describe audio component - desc.componentType = kAudioUnitType_Output; - desc.componentSubType = kAudioUnitSubType_RemoteIO; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - - // Get component - audioComponent = AudioComponentFindNext(NULL, &desc); - - // Get audio unit - ret = AudioComponentInstanceNew(audioComponent, &m_AudioUnit); - - if (ret) { - CLog::Log(LOGERROR, "CIOSCoreAudioHardware::Init: Unable to open Remote/IO device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - if(!EnableOutput(m_AudioUnit, kOutputBus)) - return false; - - if(!SetFormat(m_AudioUnit, kAudioUnitScope_Input, kOutputBus, pDesc)) - return false; - - if(!SetFormat(m_AudioUnit, kAudioUnitScope_Output, kInputBus, pDesc)) - return false; - - if(!m_Passthrough) { - // Describe audio component - desc.componentType = kAudioUnitType_Mixer; - desc.componentSubType = kAudioUnitSubType_AU3DMixerEmbedded; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - - // Get component - audioComponent = AudioComponentFindNext(NULL, &desc); - - // Get mixer unit - ret = AudioComponentInstanceNew(audioComponent, &m_MixerUnit); - if (ret) { - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Init: Unable to open Mixer device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - if(!SetFormat(m_MixerUnit, kAudioUnitScope_Input, kOutputBus, pDesc)) - return false; - - if(!SetFormat(m_MixerUnit, kAudioUnitScope_Input, kInputBus, pDesc)) - return false; - - if(!SetRenderProc(m_MixerUnit, kOutputBus, renderCallback, pClientData)) - return false; - - // Connect mixer to output - AudioUnitConnection connection; - connection.sourceAudioUnit = m_MixerUnit; - connection.sourceOutputNumber = kOutputBus; - connection.destInputNumber = kOutputBus; - - ret = AudioUnitSetProperty(m_AudioUnit, kAudioUnitProperty_MakeConnection, - kAudioUnitScope_Input, kOutputBus, &connection, sizeof(connection)); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Init: Unable to make IO connections. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - } else { - if(!SetRenderProc(m_AudioUnit, kOutputBus, renderCallback, pClientData)) - return false; - } - - SetupInfo(); - - return true; -} - -bool CIOSCoreAudioDevice::Open() -{ - if(!m_AudioUnit) - return false; - - OSStatus ret; - - if(!m_Passthrough) { - ret = AudioUnitInitialize(m_MixerUnit); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::Open: Unable to Open Mixer device. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - } - - ret = AudioUnitInitialize(m_AudioUnit); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::Open: Unable to Open AudioUnit. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - return true; -} - -void CIOSCoreAudioDevice::Close() -{ - if (!m_AudioUnit) - return; - - Stop(); - - OSStatus ret = AudioUnitUninitialize(m_AudioUnit); - - if (ret) - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Close: Unable to close Audio device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - - ret = AudioComponentInstanceDispose(m_AudioUnit); - - if (ret) - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Close: Unable to dispose Audio device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - - m_AudioUnit = 0; - - if(!m_Passthrough) { - ret = AudioUnitUninitialize(m_MixerUnit); - if (ret) - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Close: Unable to close Mixer device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - - ret = AudioComponentInstanceDispose(m_MixerUnit); - - if (ret) - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Close: Unable to dispose Mixer device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - - m_MixerUnit = 0; - } -} - -void CIOSCoreAudioDevice::Start() -{ - if (!m_AudioUnit) - return; - - OSStatus ret ; - - ret = AudioOutputUnitStart(m_AudioUnit); - if (ret) - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Start: Unable to start device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - -} - -void CIOSCoreAudioDevice::Stop() -{ - if (!m_AudioUnit) - return; - - OSStatus ret = AudioOutputUnitStop(m_AudioUnit); - if (ret) - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::Stop: Unable to stop device. Error = 0x%08x (%4.4s).", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - -} - -const char* CIOSCoreAudioDevice::GetName(CStdString& name) -{ - if (!m_AudioUnit) - return NULL; - - return name.c_str(); -} - -bool CIOSCoreAudioDevice::EnableInput(AudioComponentInstance componentInstance, AudioUnitElement bus) -{ - if (!componentInstance) - return false; - - UInt32 flag = 0; - OSStatus ret = AudioUnitSetProperty(componentInstance, kAudioOutputUnitProperty_EnableIO, - kAudioUnitScope_Input, bus, &flag, sizeof(flag)); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::EnableInput: Failed to enable input. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CIOSCoreAudioDevice::EnableOutput(AudioComponentInstance componentInstance, AudioUnitElement bus) -{ - if (!componentInstance) - return false; - - UInt32 flag = 1; - OSStatus ret = AudioUnitSetProperty(componentInstance, kAudioOutputUnitProperty_EnableIO, - kAudioUnitScope_Output, bus, &flag, sizeof(flag)); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::EnableInput: Failed to enable output. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -Float32 CIOSCoreAudioDevice::GetCurrentVolume() -{ - - if (!m_MixerUnit) - return false; - - Float32 volPct = 0.0f; - OSStatus ret = AudioUnitGetParameter(m_MixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, kInputBus, &volPct); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::GetCurrentVolume: Unable to get Mixer volume. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return 0.0f; - } - return volPct; - -} - -bool CIOSCoreAudioDevice::SetCurrentVolume(Float32 vol) -{ - - if (!m_MixerUnit && m_Passthrough) - return false; - - OSStatus ret = AudioUnitSetParameter(m_MixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, kInputBus, vol, 0); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::SetCurrentVolume: Unable to set Mixer volume. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - ret = AudioUnitSetParameter(m_MixerUnit, kMultiChannelMixerParam_Volume, kAudioUnitScope_Input, kInputBus, vol, 0); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::SetCurrentVolume: Unable to set Mixer volume. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CIOSCoreAudioDevice::GetFormat(AudioComponentInstance componentInstance, AudioUnitScope scope, - AudioUnitElement bus, AudioStreamBasicDescription* pDesc) -{ - if (!componentInstance || !pDesc) - return false; - - UInt32 size = sizeof(AudioStreamBasicDescription); - OSStatus ret = AudioUnitGetProperty(componentInstance, kAudioUnitProperty_StreamFormat, - scope, bus, pDesc, &size); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::GetFormat: Unable to get Audio Unit format bus %d. Error = 0x%08x (%4.4s)", - (int)bus, (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -bool CIOSCoreAudioDevice::SetFormat(AudioComponentInstance componentInstance, AudioUnitScope scope, - AudioUnitElement bus, AudioStreamBasicDescription* pDesc) -{ - if (!componentInstance || !pDesc) - return false; - - UInt32 size = sizeof(AudioStreamBasicDescription); - OSStatus ret = AudioUnitSetProperty(componentInstance, kAudioUnitProperty_StreamFormat, - scope, bus, pDesc, size); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioDevice::SetFormat: Unable to set Audio Unit format bus %d. Error = 0x%08x (%4.4s)", - (int)bus, (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return true; -} - -int CIOSCoreAudioDevice::FramesPerSlice(int nSlices) -{ - if (!m_AudioUnit) - return false; - - UInt32 maximumFramesPerSlice = nSlices; - OSStatus ret = AudioUnitSetProperty(m_AudioUnit, kAudioUnitProperty_MaximumFramesPerSlice, - kAudioUnitScope_Global, kOutputBus, &maximumFramesPerSlice, sizeof (maximumFramesPerSlice)); - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::FramesPerSlice: Unable to setFramesPerSlice. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - return maximumFramesPerSlice; - - -} - -void CIOSCoreAudioDevice::AudioChannelLayout(int layoutTag) -{ - if (!m_AudioUnit) - return; - - struct AudioChannelLayout layout; - layout.mChannelBitmap = 0; - layout.mNumberChannelDescriptions = 0; - layout.mChannelLayoutTag = layoutTag; - - OSStatus ret = AudioUnitSetProperty(m_AudioUnit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, kOutputBus, &layout, sizeof (layout)); - if (ret) - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::AudioUnitSetProperty: Unable to set property kAudioUnitProperty_AudioChannelLayout. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); -} - -bool CIOSCoreAudioDevice::SetRenderProc(AudioComponentInstance componentInstance, AudioUnitElement bus, - AURenderCallback callback, void* pClientData) -{ - if (!componentInstance) - return false; - - AURenderCallbackStruct callbackInfo; - callbackInfo.inputProc = callback; // Function to be called each time the AudioUnit needs data - callbackInfo.inputProcRefCon = pClientData; // Pointer to be returned in the callback proc - OSStatus ret = AudioUnitSetProperty(componentInstance, kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Global, bus, &callbackInfo, - sizeof(AURenderCallbackStruct)); - - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::SetRenderProc: Unable to set AudioUnit render callback. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - return true; -} - -bool CIOSCoreAudioDevice::SetSessionListener(AudioSessionPropertyID inID, - AudioSessionPropertyListener inProc, void* pClientData) -{ - OSStatus ret = AudioSessionAddPropertyListener(inID, inProc, pClientData); - - if (ret) - { - CLog::Log(LOGERROR, "CIOSCoreAudioUnit::SetSessionListener: Unable to set Session Listener Callback. Error = 0x%08x (%4.4s)", (uint32_t)ret, CONVERT_OSSTATUS(ret)); - return false; - } - - return true; -} - -#endif diff --git a/xbmc/osx/IOSCoreAudio.h b/xbmc/osx/IOSCoreAudio.h deleted file mode 100644 index 1c6f6b4775..0000000000 --- a/xbmc/osx/IOSCoreAudio.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#ifndef __COREAUDIO_H__ -#define __COREAUDIO_H__ - -#if defined(__APPLE__) -#include <AudioUnit/AudioUnit.h> -#include <AudioToolbox/AudioToolbox.h> -#include <AudioToolbox/AudioServices.h> -#include <CoreAudio/CoreAudioTypes.h> -#include <list> -#include <vector> - -#include "utils/StdString.h" - -#define kOutputBus 0 -#define kInputBus 1 - -// Forward declarations -class CIOSCoreAudioHardware; -class CIOSCoreAudioDevice; -class CIOSCoreAudioUnit; - -typedef std::list<AudioComponentInstance> IOSCoreAudioDeviceList; - -// There is only one AudioSystemObject instance system-side. -// Therefore, all CIOSCoreAudioHardware methods are static -class CIOSCoreAudioHardware -{ -public: - static AudioComponentInstance FindAudioDevice(CStdString deviceName); - static AudioComponentInstance GetDefaultOutputDevice(); - static UInt32 GetOutputDevices(IOSCoreAudioDeviceList* pList); -}; - -class CIOSCoreAudioDevice -{ -public: - CIOSCoreAudioDevice(); - virtual ~CIOSCoreAudioDevice(); - - AudioComponentInstance GetId() {return m_AudioUnit;} - const char* GetName(CStdString& name); - CIOSCoreAudioDevice(AudioComponentInstance deviceId); - UInt32 GetTotalOutputChannels(); - - void Attach(AudioUnit audioUnit) {m_AudioUnit = audioUnit;} - AudioComponentInstance GetComponent(){return m_AudioUnit;} - - void SetupInfo(); - bool Init(bool bPassthrough, AudioStreamBasicDescription* pDesc, AURenderCallback renderCallback, void *pClientData); - bool Open(); - void Close(); - void Start(); - void Stop(); - - bool EnableInput(AudioComponentInstance componentInstance, AudioUnitElement bus); - bool EnableOutput(AudioComponentInstance componentInstance, AudioUnitElement bus); - bool GetFormat(AudioComponentInstance componentInstance, AudioUnitScope scope, - AudioUnitElement bus, AudioStreamBasicDescription* pDesc); - bool SetFormat(AudioComponentInstance componentInstance, AudioUnitScope scope, - AudioUnitElement bus, AudioStreamBasicDescription* pDesc); - Float32 GetCurrentVolume(); - bool SetCurrentVolume(Float32 vol); - int FramesPerSlice(int nSlices); - void AudioChannelLayout(int layoutTag); - bool SetRenderProc(AudioComponentInstance componentInstance, AudioUnitElement bus, - AURenderCallback callback, void* pClientData); - bool SetSessionListener(AudioSessionPropertyID inID, - AudioSessionPropertyListener inProc, void* pClientData); - - AudioComponentInstance m_AudioUnit; - AudioComponentInstance m_MixerUnit; - bool m_Passthrough; -}; - -// Helper Functions -char* IOSUInt32ToFourCC(UInt32* val); -const char* IOSStreamDescriptionToString(AudioStreamBasicDescription desc, CStdString& str); - -#define CONVERT_OSSTATUS(x) IOSUInt32ToFourCC((UInt32*)&ret) - -#endif -#endif // __COREAUDIO_H__ diff --git a/xbmc/utils/Makefile b/xbmc/utils/Makefile index e707a03ca1..79da051ef3 100644 --- a/xbmc/utils/Makefile +++ b/xbmc/utils/Makefile @@ -35,8 +35,6 @@ SRCS=AlarmClock.cpp \ log.cpp \ md5.cpp \ Mime.cpp \ - PCMAmplifier.cpp \ - PCMRemap.cpp \ PerformanceSample.cpp \ PerformanceStats.cpp \ POUtils.cpp \ diff --git a/xbmc/utils/PCMAmplifier.cpp b/xbmc/utils/PCMAmplifier.cpp deleted file mode 100644 index e8fe832715..0000000000 --- a/xbmc/utils/PCMAmplifier.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "PCMAmplifier.h" -#include "settings/Settings.h" - -#include <math.h> - -CPCMAmplifier::CPCMAmplifier() : m_nVolume(VOLUME_MAXIMUM), m_dFactor(0) -{ -} - -CPCMAmplifier::~CPCMAmplifier() -{ -} - -void CPCMAmplifier::SetVolume(int nVolume) -{ - m_nVolume = nVolume; - if (nVolume > VOLUME_MAXIMUM) - nVolume = VOLUME_MAXIMUM; - - if (nVolume < VOLUME_MINIMUM) - nVolume = VOLUME_MINIMUM; - - if( nVolume == VOLUME_MINIMUM) - m_dFactor = 0; - else - m_dFactor = pow(10,nVolume/2000.f); -} - -int CPCMAmplifier::GetVolume() -{ - return m_nVolume; -} - - // only works on 16bit samples -void CPCMAmplifier::DeAmplify(short *pcm, int nSamples) -{ - if (m_dFactor >= 1.0) - { - // no process required. using >= to make sure no amp is ever done (only de-amp) - return; - } - - for (int nSample=0; nSample<nSamples; nSample++) - { - int nSampleValue = pcm[nSample]; // must be int. so that we can check over/under flow - nSampleValue = (int)((double)nSampleValue * m_dFactor); - - pcm[nSample] = (short)nSampleValue; - } -} diff --git a/xbmc/utils/PCMAmplifier.h b/xbmc/utils/PCMAmplifier.h deleted file mode 100644 index e5d4689949..0000000000 --- a/xbmc/utils/PCMAmplifier.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __PCM_AMPLIFY__H__ -#define __PCM_AMPLIFY__H__ - -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -class CPCMAmplifier { -public: - CPCMAmplifier(); - virtual ~CPCMAmplifier(); - - void SetVolume(int nVolume); - int GetVolume(); - - // only works on 16bit samples - void DeAmplify(short *pcm, int nSamples); - -protected: - int m_nVolume; - double m_dFactor; - -}; - -#endif - diff --git a/xbmc/utils/PCMRemap.cpp b/xbmc/utils/PCMRemap.cpp deleted file mode 100644 index bd1884bf0b..0000000000 --- a/xbmc/utils/PCMRemap.cpp +++ /dev/null @@ -1,804 +0,0 @@ -/* - * Copyright (C) 2005-2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#define __STDC_LIMIT_MACROS - -#include <cstdlib> -#include <string.h> -#include <stdio.h> -#include <math.h> - -#include "MathUtils.h" -#include "PCMRemap.h" -#include "utils/log.h" -#include "settings/GUISettings.h" -#include "settings/AdvancedSettings.h" -#ifdef _WIN32 -#include "../win32/PlatformDefs.h" -#endif - -static enum PCMChannels PCMLayoutMap[PCM_MAX_LAYOUT][PCM_MAX_CH + 1] = -{ - /* 2.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_INVALID}, - /* 2.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID}, - /* 3.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_INVALID}, - /* 3.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_INVALID}, - /* 4.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_INVALID}, - /* 4.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID}, - /* 5.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_INVALID}, - /* 5.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID}, - /* 7.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_SIDE_LEFT, PCM_SIDE_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_INVALID}, - /* 7.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_SIDE_LEFT, PCM_SIDE_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID} -}; - -/* - map missing output into channel @ volume level - the order of this table is important, mix tables can not depend on channels that have not been defined yet - eg, FC can only be mixed into FL, FR as they are the only channels that have been defined -*/ -#define PCM_MAX_MIX 3 -static struct PCMMapInfo PCMDownmixTable[PCM_MAX_CH][PCM_MAX_MIX] = -{ - /* PCM_FRONT_LEFT */ - { - {PCM_INVALID} - }, - /* PCM_FRONT_RIGHT */ - { - {PCM_INVALID} - }, - /* PCM_FRONT_CENTER */ - { - {PCM_FRONT_LEFT_OF_CENTER , 1.0}, - {PCM_FRONT_RIGHT_OF_CENTER, 1.0}, - {PCM_INVALID} - }, - /* PCM_LOW_FREQUENCY */ - { - /* - A/52B 7.8 paragraph 2 recomends +10db - but due to horrible clipping when normalize - is disabled we set this to 1.0 - */ - {PCM_FRONT_LEFT , 1.0},//3.5}, - {PCM_FRONT_RIGHT , 1.0},//3.5}, - {PCM_INVALID} - }, - /* PCM_BACK_LEFT */ - { - {PCM_FRONT_LEFT , 1.0}, - {PCM_INVALID} - }, - /* PCM_BACK_RIGHT */ - { - {PCM_FRONT_RIGHT , 1.0}, - {PCM_INVALID} - }, - /* PCM_FRONT_LEFT_OF_CENTER */ - { - {PCM_FRONT_LEFT , 1.0}, - {PCM_FRONT_CENTER , 1.0, true}, - {PCM_INVALID} - }, - /* PCM_FRONT_RIGHT_OF_CENTER */ - { - {PCM_FRONT_RIGHT , 1.0}, - {PCM_FRONT_CENTER , 1.0, true}, - {PCM_INVALID} - }, - /* PCM_BACK_CENTER */ - { - {PCM_BACK_LEFT , 1.0}, - {PCM_BACK_RIGHT , 1.0}, - {PCM_INVALID} - }, - /* PCM_SIDE_LEFT */ - { - {PCM_FRONT_LEFT , 1.0}, - {PCM_BACK_LEFT , 1.0}, - {PCM_INVALID} - }, - /* PCM_SIDE_RIGHT */ - { - {PCM_FRONT_RIGHT , 1.0}, - {PCM_BACK_RIGHT , 1.0}, - {PCM_INVALID} - }, - /* PCM_TOP_FRONT_LEFT */ - { - {PCM_FRONT_LEFT , 1.0}, - {PCM_INVALID} - }, - /* PCM_TOP_FRONT_RIGHT */ - { - {PCM_FRONT_RIGHT , 1.0}, - {PCM_INVALID} - }, - /* PCM_TOP_FRONT_CENTER */ - { - {PCM_TOP_FRONT_LEFT , 1.0}, - {PCM_TOP_FRONT_RIGHT , 1.0}, - {PCM_INVALID} - }, - /* PCM_TOP_CENTER */ - { - {PCM_TOP_FRONT_LEFT , 1.0}, - {PCM_TOP_FRONT_RIGHT , 1.0}, - {PCM_INVALID} - }, - /* PCM_TOP_BACK_LEFT */ - { - {PCM_BACK_LEFT , 1.0}, - {PCM_INVALID} - }, - /* PCM_TOP_BACK_RIGHT */ - { - {PCM_BACK_RIGHT , 1.0}, - {PCM_INVALID} - }, - /* PCM_TOP_BACK_CENTER */ - { - {PCM_TOP_BACK_LEFT , 1.0}, - {PCM_TOP_BACK_RIGHT , 1.0}, - {PCM_INVALID} - } -}; - -CPCMRemap::CPCMRemap() : - m_inSet (false), - m_outSet (false), - m_inChannels (0), - m_outChannels (0), - m_inSampleSize(0), - m_ignoreLayout(false), - m_buf(NULL), - m_bufsize(0), - m_attenuation (1.0), - m_attenuationInc(0.0), - m_attenuationMin(1.0), - m_sampleRate (48000.0), //safe default - m_holdCounter (0), - m_limiterEnabled(false) -{ - Dispose(); -} - -CPCMRemap::~CPCMRemap() -{ - Dispose(); -} - -void CPCMRemap::Dispose() -{ - free(m_buf); - m_buf = NULL; - m_bufsize = 0; -} - -/* resolves the channels recursively and returns the new index of tablePtr */ -struct PCMMapInfo* CPCMRemap::ResolveChannel(enum PCMChannels channel, float level, bool ifExists, std::vector<enum PCMChannels> path, struct PCMMapInfo *tablePtr) -{ - if (channel == PCM_INVALID) return tablePtr; - - /* if its a 1 to 1 mapping, return */ - if (m_useable[channel]) - { - tablePtr->channel = channel; - tablePtr->level = level; - - ++tablePtr; - tablePtr->channel = PCM_INVALID; - return tablePtr; - } else - if (ifExists) - level /= 2; - - struct PCMMapInfo *info; - std::vector<enum PCMChannels>::iterator itt; - - for(info = PCMDownmixTable[channel]; info->channel != PCM_INVALID; ++info) - { - /* make sure we are not about to recurse into ourself */ - bool found = false; - for(itt = path.begin(); itt != path.end(); ++itt) - if (*itt == info->channel) - { - found = true; - break; - } - - if (found) - continue; - - path.push_back(channel); - float l = (info->level * (level / 100)) * 100; - tablePtr = ResolveChannel(info->channel, l, info->ifExists, path, tablePtr); - path.pop_back(); - } - - return tablePtr; -} - -/* - Builds a lookup table without extra adjustments, useful if we simply - want to find out which channels are active. - For final adjustments, BuildMap() is used. -*/ -void CPCMRemap::ResolveChannels() -{ - unsigned int in_ch, out_ch; - bool hasSide = false; - bool hasBack = false; - - memset(m_useable, 0, sizeof(m_useable)); - - if (!m_outSet) - { - /* Output format is not known yet, assume the full configured map. - * Note that m_ignoreLayout-using callers normally ignore the result of - * this function when !m_outSet, when it is called only for an advice for - * the caller of SetInputFormat about the best possible output map, and - * they can still set their output format arbitrarily in their call to - * SetOutputFormat. */ - for (enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan) - m_useable[*chan] = true; - } - else if (m_ignoreLayout) - { - for(out_ch = 0; out_ch < m_outChannels; ++out_ch) - m_useable[m_outMap[out_ch]] = true; - } - else - { - /* figure out what channels we have and can use */ - for(enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan) - { - for(out_ch = 0; out_ch < m_outChannels; ++out_ch) - if (m_outMap[out_ch] == *chan) - { - m_useable[*chan] = true; - break; - } - } - } - - /* force mono audio to front left and front right */ - if (!m_ignoreLayout && m_inChannels == 1 && m_inMap[0] == PCM_FRONT_CENTER - && m_useable[PCM_FRONT_LEFT] && m_useable[PCM_FRONT_RIGHT]) - { - CLog::Log(LOGDEBUG, "CPCMRemap: Mapping mono audio to front left and front right"); - m_useable[PCM_FRONT_CENTER] = false; - m_useable[PCM_FRONT_LEFT_OF_CENTER] = false; - m_useable[PCM_FRONT_RIGHT_OF_CENTER] = false; - } - - /* see if our input has side/back channels */ - for(in_ch = 0; in_ch < m_inChannels; ++in_ch) - switch(m_inMap[in_ch]) - { - case PCM_SIDE_LEFT: - case PCM_SIDE_RIGHT: - hasSide = true; - break; - - case PCM_BACK_LEFT: - case PCM_BACK_RIGHT: - hasBack = true; - break; - - default:; - } - - /* if our input has side, and not back channels, and our output doesnt have side channels */ - if (hasSide && !hasBack && (!m_useable[PCM_SIDE_LEFT] || !m_useable[PCM_SIDE_RIGHT])) - { - CLog::Log(LOGDEBUG, "CPCMRemap: Forcing side channel map to back channels"); - for(in_ch = 0; in_ch < m_inChannels; ++in_ch) - if (m_inMap[in_ch] == PCM_SIDE_LEFT ) m_inMap[in_ch] = PCM_BACK_LEFT; - else if (m_inMap[in_ch] == PCM_SIDE_RIGHT) m_inMap[in_ch] = PCM_BACK_RIGHT; - } - - /* resolve all the channels */ - struct PCMMapInfo table[PCM_MAX_CH + 1], *info, *dst; - std::vector<enum PCMChannels> path; - - for (int i = 0; i < PCM_MAX_CH + 1; i++) - { - for (int j = 0; j < PCM_MAX_CH + 1; j++) - m_lookupMap[i][j].channel = PCM_INVALID; - } - - memset(m_counts, 0, sizeof(m_counts)); - for(in_ch = 0; in_ch < m_inChannels; ++in_ch) { - - for (int i = 0; i < PCM_MAX_CH + 1; i++) - table[i].channel = PCM_INVALID; - - ResolveChannel(m_inMap[in_ch], 1.0f, false, path, table); - for(info = table; info->channel != PCM_INVALID; ++info) - { - /* find the end of the table */ - for(dst = m_lookupMap[info->channel]; dst->channel != PCM_INVALID; ++dst); - - /* append it to the table and set its input offset */ - dst->channel = m_inMap[in_ch]; - dst->in_offset = in_ch * 2; - dst->level = info->level; - m_counts[dst->channel]++; - } - } -} - -/* - builds a lookup table to convert from the input mapping to the output - mapping, this decreases the amount of work per sample to remap it. -*/ -void CPCMRemap::BuildMap() -{ - struct PCMMapInfo *dst; - unsigned int out_ch; - - if (!m_inSet || !m_outSet) return; - - m_inStride = m_inSampleSize * m_inChannels ; - m_outStride = m_inSampleSize * m_outChannels; - - /* see if we need to normalize the levels */ - bool dontnormalize = g_guiSettings.GetBool("audiooutput.dontnormalizelevels"); - CLog::Log(LOGDEBUG, "CPCMRemap: Downmix normalization is %s", (dontnormalize ? "disabled" : "enabled")); - - ResolveChannels(); - - /* convert the levels into RMS values */ - float loudest = 0.0; - bool hasLoudest = false; - - for(out_ch = 0; out_ch < m_outChannels; ++out_ch) - { - float scale = 0; - int count = 0; - for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst) - { - dst->copy = false; - dst->level = dst->level / sqrt((float)m_counts[dst->channel]); - scale += dst->level; - ++count; - } - - /* if there is only 1 channel to mix, and the level is 1.0, then just copy the channel */ - dst = m_lookupMap[m_outMap[out_ch]]; - if (count == 1 && dst->level > 0.99 && dst->level < 1.01) - dst->copy = true; - - /* normalize the levels if it is turned on */ - if (!dontnormalize) - for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst) - { - dst->level /= scale; - /* find the loudest output level we have that is not 1-1 */ - if (dst->level < 1.0 && loudest < dst->level) - { - loudest = dst->level; - hasLoudest = true; - } - } - } - - /* adjust the channels that are too loud */ - for(out_ch = 0; out_ch < m_outChannels; ++out_ch) - { - CStdString s = "", f; - for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst) - { - if (hasLoudest && dst->copy) - { - dst->level = loudest; - dst->copy = false; - } - - f.Format("%s(%f%s) ", PCMChannelStr(dst->channel).c_str(), dst->level, dst->copy ? "*" : ""); - s += f; - } - CLog::Log(LOGDEBUG, "CPCMRemap: %s = %s\n", PCMChannelStr(m_outMap[out_ch]).c_str(), s.c_str()); - } -} - -void CPCMRemap::DumpMap(CStdString info, unsigned int channels, enum PCMChannels *channelMap) -{ - if (channelMap == NULL) - { - CLog::Log(LOGINFO, "CPCMRemap: %s channel map: NULL", info.c_str()); - return; - } - - CStdString mapping; - for(unsigned int i = 0; i < channels; ++i) - mapping += ((i == 0) ? "" : ",") + PCMChannelStr(channelMap[i]); - - CLog::Log(LOGINFO, "CPCMRemap: %s channel map: %s\n", info.c_str(), mapping.c_str()); -} - -void CPCMRemap::Reset() -{ - m_inSet = false; - m_outSet = false; - Dispose(); -} - -/* sets the input format, and returns the requested channel layout */ -enum PCMChannels *CPCMRemap::SetInputFormat(unsigned int channels, enum PCMChannels *channelMap, unsigned int sampleSize, unsigned int sampleRate) -{ - m_inChannels = channels; - m_inSampleSize = sampleSize; - m_sampleRate = (float)sampleRate; - m_inSet = channelMap != NULL; - if (channelMap) - memcpy(m_inMap, channelMap, sizeof(enum PCMChannels) * channels); - - /* fix me later */ - assert(sampleSize == 2); - - /* get the audio layout, and count the channels in it */ - m_channelLayout = (enum PCMLayout)g_guiSettings.GetInt("audiooutput.channellayout"); - if (m_channelLayout >= PCM_MAX_LAYOUT) m_channelLayout = PCM_LAYOUT_2_0; - - //spdif only has 2 pcm channels, so don't try to use more - if (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_IEC958) - { - CLog::Log(LOGINFO, "CPCMRemap: Configured speaker layout: %s (iec958)\n", PCMLayoutStr(m_channelLayout).c_str()); - m_channelLayout = PCM_LAYOUT_2_0; - } - else - CLog::Log(LOGINFO, "CPCMRemap: Configured speaker layout: %s\n", PCMLayoutStr(m_channelLayout).c_str()); - - - DumpMap("I", channels, channelMap); - BuildMap(); - - /* now remove the empty channels from PCMLayoutMap; - * we don't perform upmixing so we want the minimum amount of those */ - if (channelMap) { - if (!m_outSet) - ResolveChannels(); /* Do basic channel resolving to find out the empty channels; - * If m_outSet == true, this was done already by BuildMap() above */ - int i = 0; - for (enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan) - if (m_lookupMap[*chan][0].channel != PCM_INVALID) { - /* something is mapped here, so add the channel */ - m_layoutMap[i++] = *chan; - } - m_layoutMap[i] = PCM_INVALID; - } else - memcpy(m_layoutMap, PCMLayoutMap[m_channelLayout], sizeof(PCMLayoutMap[m_channelLayout])); - - m_attenuation = 1.0; - m_attenuationInc = 1.0; - m_holdCounter = 0; - - return m_layoutMap; -} - -/* sets the output format supported by the audio renderer */ -void CPCMRemap::SetOutputFormat(unsigned int channels, enum PCMChannels *channelMap, bool ignoreLayout/* = false */) -{ - m_outChannels = channels; - m_outSet = channelMap != NULL; - m_ignoreLayout = ignoreLayout; - if (channelMap) - memcpy(m_outMap, channelMap, sizeof(enum PCMChannels) * channels); - - DumpMap("O", channels, channelMap); - BuildMap(); - - m_attenuation = 1.0; - m_attenuationInc = 1.0; - m_holdCounter = 0; -} - -void CPCMRemap::Remap(void *data, void *out, unsigned int samples, long drc) -{ - float gain = 1.0f; - if (drc > 0) - gain = pow(10.0f, (float)drc / 2000.0f); - - Remap(data, out, samples, gain); -} - -/* remap the supplied data into out, which must be pre-allocated */ -void CPCMRemap::Remap(void *data, void *out, unsigned int samples, float gain /*= 1.0f*/) -{ - CheckBufferSize(samples * m_outChannels * sizeof(float)); - - //set output buffer to 0 - memset(out, 0, samples * m_outChannels * m_inSampleSize); - - //set intermediate buffer to 0 - memset(m_buf, 0, m_bufsize); - - ProcessInput(data, out, samples, gain); - AddGain(m_buf, samples * m_outChannels, gain); - ProcessLimiter(samples, gain); - ProcessOutput(out, samples, gain); -} - -void CPCMRemap::CheckBufferSize(int size) -{ - if (m_bufsize < size) - { - m_bufsize = size; - m_buf = (float*)realloc(m_buf, m_bufsize); - } -} - -void CPCMRemap::ProcessInput(void* data, void* out, unsigned int samples, float gain) -{ - for (unsigned int ch = 0; ch < m_outChannels; ch++) - { - struct PCMMapInfo *info = m_lookupMap[m_outMap[ch]]; - if (info->channel == PCM_INVALID) - continue; - - if (info->copy && gain == 1.0f) //do direct copy - { - uint8_t* src = (uint8_t*)data + info->in_offset; - uint8_t* dst = (uint8_t*)out + ch * m_inSampleSize; - uint8_t* dstend = dst + samples * m_outStride; - while (dst != dstend) - { - *(int16_t*)dst = *(int16_t*)src; - src += m_inStride; - dst += m_outStride; - } - } - else //needs some volume change or mixing, put into intermediate buffer - { - for(; info->channel != PCM_INVALID; info++) - { - uint8_t* src = (uint8_t*)data + info->in_offset; - float* dst = m_buf + ch; - float* dstend = dst + samples * m_outChannels; - while (dst != dstend) - { - *dst += (float)(*(int16_t*)src) * info->level; - src += m_inStride; - dst += m_outChannels; - } - } - } - } -} - -void CPCMRemap::AddGain(float* buf, unsigned int samples, float gain) -{ - if (gain != 1.0f) //needs a gain change - { - float* ptr = m_buf; - float* end = m_buf + samples; - while (ptr != end) - *(ptr++) *= gain; - } -} - -void CPCMRemap::ProcessLimiter(unsigned int samples, float gain) -{ - //check total gain for each output channel - float highestgain = 1.0f; - for (unsigned int ch = 0; ch < m_outChannels; ch++) - { - struct PCMMapInfo *info = m_lookupMap[m_outMap[ch]]; - if (info->channel == PCM_INVALID) - continue; - - float chgain = 0.0f; - for(; info->channel != PCM_INVALID; info++) - chgain += info->level * gain; - - if (chgain > highestgain) - highestgain = chgain; - } - - m_attenuationMin = 1.0f; - - //if one of the channels can clip, enable a limiter - if (highestgain > 1.0001f) - { - m_attenuationMin = m_attenuation; - - if (!m_limiterEnabled) - { - CLog::Log(LOGDEBUG, "CPCMRemap:: max gain: %f, enabling limiter", highestgain); - m_limiterEnabled = true; - } - - for (unsigned int i = 0; i < samples; i++) - { - //for each collection of samples, get the highest absolute value - float maxAbs = 0.0f; - for (unsigned int outch = 0; outch < m_outChannels; outch++) - { - float absval = fabs(m_buf[i * m_outChannels + outch]) / 32768.0f; - if (maxAbs < absval) - maxAbs = absval; - } - - //if attenuatedAbs is higher than 1.0f, audio is clipping - float attenuatedAbs = maxAbs * m_attenuation; - if (attenuatedAbs > 1.0f) - { - //set m_attenuation so that m_attenuation * sample is the maximum output value - m_attenuation = 1.0f / maxAbs; - if (m_attenuation < m_attenuationMin) - m_attenuationMin = m_attenuation; - //value to add to m_attenuation to make it 1.0f - m_attenuationInc = 1.0f - m_attenuation; - //amount of samples to hold m_attenuation - m_holdCounter = MathUtils::round_int(m_sampleRate * g_advancedSettings.m_limiterHold); - } - else if (m_attenuation < 1.0f && attenuatedAbs > 0.95f) - { - //if we're attenuating and we get within 5% of clipping, hold m_attenuation - m_attenuationInc = 1.0f - m_attenuation; - m_holdCounter = MathUtils::round_int(m_sampleRate * g_advancedSettings.m_limiterHold); - } - - //apply attenuation - for (unsigned int outch = 0; outch < m_outChannels; outch++) - m_buf[i * m_outChannels + outch] *= m_attenuation; - - if (m_holdCounter) - { - //hold m_attenuation - m_holdCounter--; - } - else if (m_attenuationInc > 0.0f) - { - //move m_attenuation to 1.0 in g_advancedSettings.m_limiterRelease seconds - m_attenuation += m_attenuationInc / m_sampleRate / g_advancedSettings.m_limiterRelease; - if (m_attenuation > 1.0f) - { - m_attenuation = 1.0f; - m_attenuationInc = 0.0f; - } - } - } - } - else - { - if (m_limiterEnabled) - { - CLog::Log(LOGDEBUG, "CPCMRemap:: max gain: %f, disabling limiter", highestgain); - m_limiterEnabled = false; - } - - //reset the limiter - m_attenuation = 1.0f; - m_attenuationInc = 0.0f; - m_holdCounter = 0; - } -} - -void CPCMRemap::ProcessOutput(void* out, unsigned int samples, float gain) -{ - //copy from intermediate buffer to output - for (unsigned int ch = 0; ch < m_outChannels; ch++) - { - struct PCMMapInfo *info = m_lookupMap[m_outMap[ch]]; - if (info->channel == PCM_INVALID) - continue; - - if (!info->copy || gain != 1.0f) - { - float* src = m_buf + ch; - uint8_t* dst = (uint8_t*)out + ch * m_inSampleSize; - uint8_t* dstend = dst + samples * m_outStride; - - while(dst != dstend) - { - *(int16_t*)dst = MathUtils::round_int(std::min(std::max(*src, (float)INT16_MIN), (float)INT16_MAX)); - src += m_outChannels; - dst += m_outStride; - } - } - } -} - -bool CPCMRemap::CanRemap() -{ - return (m_inSet && m_outSet); -} - -int CPCMRemap::InBytesToFrames(int bytes) -{ - return bytes / m_inSampleSize / m_inChannels; -} - -int CPCMRemap::FramesToOutBytes(int frames) -{ - return frames * m_inSampleSize * m_outChannels; -} - -int CPCMRemap::FramesToInBytes(int frames) -{ - return frames * m_inSampleSize * m_inChannels; -} - -CStdString CPCMRemap::PCMChannelStr(enum PCMChannels ename) -{ - const char* PCMChannelName[] = - { - "FL", - "FR", - "CE", - "LFE", - "BL", - "BR", - "FLOC", - "FROC", - "BC", - "SL", - "SR", - "TFL", - "TFR", - "TFC", - "TC", - "TBL", - "TBR", - "TBC" - }; - - int namepos = (int)ename; - CStdString namestr; - - if (namepos < 0 || namepos >= (int)(sizeof(PCMChannelName) / sizeof(const char*))) - namestr.Format("UNKNOWN CHANNEL:%i", namepos); - else - namestr = PCMChannelName[namepos]; - - return namestr; -} - -CStdString CPCMRemap::PCMLayoutStr(enum PCMLayout ename) -{ - const char* PCMLayoutName[] = - { - "2.0", - "2.1", - "3.0", - "3.1", - "4.0", - "4.1", - "5.0", - "5.1", - "7.0", - "7.1" - }; - - int namepos = (int)ename; - CStdString namestr; - - if (namepos < 0 || namepos >= (int)(sizeof(PCMLayoutName) / sizeof(const char*))) - namestr.Format("UNKNOWN LAYOUT:%i", namepos); - else - namestr = PCMLayoutName[namepos]; - - return namestr; -} - diff --git a/xbmc/utils/PCMRemap.h b/xbmc/utils/PCMRemap.h deleted file mode 100644 index a70292e596..0000000000 --- a/xbmc/utils/PCMRemap.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef __PCM_REMAP__H__ -#define __PCM_REMAP__H__ - -/* - * Copyright (C) 2005-2010 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include <stdint.h> -#include <vector> -#include "StdString.h" - -#define PCM_MAX_CH 18 -enum PCMChannels -{ - PCM_INVALID = -1, - PCM_FRONT_LEFT, - PCM_FRONT_RIGHT, - PCM_FRONT_CENTER, - PCM_LOW_FREQUENCY, - PCM_BACK_LEFT, - PCM_BACK_RIGHT, - PCM_FRONT_LEFT_OF_CENTER, - PCM_FRONT_RIGHT_OF_CENTER, - PCM_BACK_CENTER, - PCM_SIDE_LEFT, - PCM_SIDE_RIGHT, - PCM_TOP_FRONT_LEFT, - PCM_TOP_FRONT_RIGHT, - PCM_TOP_FRONT_CENTER, - PCM_TOP_CENTER, - PCM_TOP_BACK_LEFT, - PCM_TOP_BACK_RIGHT, - PCM_TOP_BACK_CENTER -}; - -#define PCM_MAX_LAYOUT 10 -enum PCMLayout -{ - PCM_LAYOUT_2_0 = 0, - PCM_LAYOUT_2_1, - PCM_LAYOUT_3_0, - PCM_LAYOUT_3_1, - PCM_LAYOUT_4_0, - PCM_LAYOUT_4_1, - PCM_LAYOUT_5_0, - PCM_LAYOUT_5_1, - PCM_LAYOUT_7_0, - PCM_LAYOUT_7_1 -}; - -struct PCMMapInfo -{ - enum PCMChannels channel; - float level; - bool ifExists; - int in_offset; - bool copy; -}; - -//! Channels remapper class -/*! - The usual set-up process: - - user calls SetInputFormat with the input channels information - - SetInputFormat responds with a channelmap corresponding to the speaker - layout that the user has configured, with empty (according to information - calculated from the input channelmap) channels removed - - user uses this information to create the desired output channelmap, - and calls SetOutputFormat to set it (if the channelmap contains channels - that do not exist in the configured speaker layout, they will contain - only silence unless ignoreLayout is true) - */ - -class CPCMRemap -{ -protected: - bool m_inSet, m_outSet; - enum PCMLayout m_channelLayout; - unsigned int m_inChannels, m_outChannels; - unsigned int m_inSampleSize; - enum PCMChannels m_inMap [PCM_MAX_CH]; - enum PCMChannels m_outMap[PCM_MAX_CH]; - enum PCMChannels m_layoutMap[PCM_MAX_CH + 1]; - - bool m_ignoreLayout; - bool m_useable [PCM_MAX_CH]; - int m_inStride, m_outStride; - struct PCMMapInfo m_lookupMap[PCM_MAX_CH + 1][PCM_MAX_CH + 1]; - int m_counts[PCM_MAX_CH]; - - float* m_buf; - int m_bufsize; - float m_attenuation; - float m_attenuationInc; - float m_attenuationMin; //lowest attenuation value during a call of Remap(), used for the codec info - float m_sampleRate; - unsigned int m_holdCounter; - bool m_limiterEnabled; - - struct PCMMapInfo* ResolveChannel(enum PCMChannels channel, float level, bool ifExists, std::vector<enum PCMChannels> path, struct PCMMapInfo *tablePtr); - void ResolveChannels(); //!< Partial BuildMap(), just enough to see which output channels are active - void BuildMap(); - void DumpMap(CStdString info, int unsigned channels, enum PCMChannels *channelMap); - void Dispose(); - CStdString PCMChannelStr(enum PCMChannels ename); - CStdString PCMLayoutStr(enum PCMLayout ename); - - void CheckBufferSize(int size); - void ProcessInput(void* data, void* out, unsigned int samples, float gain); - void AddGain(float* buf, unsigned int samples, float gain); - void ProcessLimiter(unsigned int samples, float gain); - void ProcessOutput(void* out, unsigned int samples, float gain); - -public: - - CPCMRemap(); - ~CPCMRemap(); - - void Reset(); - enum PCMChannels *SetInputFormat (unsigned int channels, enum PCMChannels *channelMap, unsigned int sampleSize, unsigned int sampleRate); - void SetOutputFormat(unsigned int channels, enum PCMChannels *channelMap, bool ignoreLayout = false); - void Remap(void *data, void *out, unsigned int samples, long drc); - void Remap(void *data, void *out, unsigned int samples, float gain = 1.0f); - bool CanRemap(); - int InBytesToFrames (int bytes ); - int FramesToOutBytes(int frames); - int FramesToInBytes (int frames); - float GetCurrentAttenuation() { return m_attenuationMin; } -}; - -#endif |