diff --git a/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj b/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj index 01de0f5a2..9f3947a42 100644 --- a/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj +++ b/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj @@ -343,6 +343,59 @@ 838490991807BC9C00E7332D /* dtsdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490971807BC9C00E7332D /* dtsdec.c */; }; 8384909C1807BE1300E7332D /* synth_filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384909A1807BE1300E7332D /* synth_filter.c */; }; 8384909D1807BE1300E7332D /* synth_filter.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384909B1807BE1300E7332D /* synth_filter.h */; }; + 838490A31807C12300E7332D /* adpcm_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384909E1807C12300E7332D /* adpcm_data.c */; }; + 838490A41807C12300E7332D /* adpcm_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384909F1807C12300E7332D /* adpcm_data.h */; }; + 838490A51807C12300E7332D /* adpcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490A01807C12300E7332D /* adpcm.c */; }; + 838490A61807C12300E7332D /* adpcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490A11807C12300E7332D /* adpcm.h */; }; + 838490A71807C12300E7332D /* pcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490A21807C12300E7332D /* pcm.c */; }; + 838490B11807C1C300E7332D /* gsm_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490A81807C1C300E7332D /* gsm_parser.c */; }; + 838490B21807C1C300E7332D /* gsm.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490A91807C1C300E7332D /* gsm.h */; }; + 838490B31807C1C300E7332D /* gsmdec_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490AA1807C1C300E7332D /* gsmdec_data.c */; }; + 838490B41807C1C300E7332D /* gsmdec_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490AB1807C1C300E7332D /* gsmdec_data.h */; }; + 838490B51807C1C300E7332D /* gsmdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490AC1807C1C300E7332D /* gsmdec.c */; }; + 838490B61807C1C300E7332D /* msgsmdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490AD1807C1C300E7332D /* msgsmdec.c */; }; + 838490B71807C1C300E7332D /* msgsmdec.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490AE1807C1C300E7332D /* msgsmdec.h */; }; + 838490B81807C1C300E7332D /* truespeech_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490AF1807C1C300E7332D /* truespeech_data.h */; }; + 838490B91807C1C300E7332D /* truespeech.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490B01807C1C300E7332D /* truespeech.c */; }; + 838490BB1807C30900E7332D /* pcm_tablegen.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490BA1807C30900E7332D /* pcm_tablegen.h */; }; + 838490BE1807C34900E7332D /* atrac3.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490BC1807C34900E7332D /* atrac3.c */; }; + 838490BF1807C34900E7332D /* atrac3data.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490BD1807C34900E7332D /* atrac3data.h */; }; + 838490C21807C37300E7332D /* atrac.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490C01807C37300E7332D /* atrac.c */; }; + 838490C31807C37300E7332D /* atrac.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490C11807C37300E7332D /* atrac.h */; }; + 838490D51807C47E00E7332D /* g729.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490CA1807C47E00E7332D /* g729.h */; }; + 838490D61807C47E00E7332D /* g729data.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490CB1807C47E00E7332D /* g729data.h */; }; + 838490D71807C47E00E7332D /* g729dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490CC1807C47E00E7332D /* g729dec.c */; }; + 838490D81807C47E00E7332D /* g729postfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490CD1807C47E00E7332D /* g729postfilter.c */; }; + 838490D91807C47E00E7332D /* g729postfilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490CE1807C47E00E7332D /* g729postfilter.h */; }; + 838490DA1807C47E00E7332D /* g726.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490CF1807C47E00E7332D /* g726.c */; }; + 838490DB1807C47E00E7332D /* g723_1_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490D01807C47E00E7332D /* g723_1_data.h */; }; + 838490DC1807C47E00E7332D /* g723_1.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490D11807C47E00E7332D /* g723_1.c */; }; + 838490DD1807C47E00E7332D /* g722dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490D21807C47E00E7332D /* g722dec.c */; }; + 838490DE1807C47E00E7332D /* g722.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490D31807C47E00E7332D /* g722.c */; }; + 838490DF1807C47E00E7332D /* g722.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490D41807C47E00E7332D /* g722.h */; }; + 838490EF1807C57B00E7332D /* aac_adtstoasc_bsf.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490E01807C57B00E7332D /* aac_adtstoasc_bsf.c */; }; + 838490F01807C57B00E7332D /* aac_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490E11807C57B00E7332D /* aac_parser.c */; }; + 838490F11807C57B00E7332D /* aacadtsdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490E21807C57B00E7332D /* aacadtsdec.c */; }; + 838490F21807C57B00E7332D /* aacadtsdec.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490E31807C57B00E7332D /* aacadtsdec.h */; }; + 838490F41807C57B00E7332D /* aacdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490E51807C57B00E7332D /* aacdec.c */; }; + 838490F51807C57B00E7332D /* aacdectab.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490E61807C57B00E7332D /* aacdectab.h */; }; + 838490F61807C57B00E7332D /* aacps_tablegen.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490E71807C57B00E7332D /* aacps_tablegen.h */; }; + 838490F71807C57B00E7332D /* aacps.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490E81807C57B00E7332D /* aacps.c */; }; + 838490F91807C57B00E7332D /* aacpsdsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490EA1807C57B00E7332D /* aacpsdsp.c */; }; + 838490FB1807C57B00E7332D /* aacsbr.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490EC1807C57B00E7332D /* aacsbr.c */; }; + 838490FC1807C57B00E7332D /* aacsbr.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490ED1807C57B00E7332D /* aacsbr.h */; }; + 838490FD1807C57B00E7332D /* aacsbrdata.h in Headers */ = {isa = PBXBuildFile; fileRef = 838490EE1807C57B00E7332D /* aacsbrdata.h */; }; + 838490FF1807C58500E7332D /* aacdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838490FE1807C58500E7332D /* aacdec.c */; }; + 838491021807CDC000E7332D /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 838491001807CDC000E7332D /* lpc.c */; }; + 838491031807CDC000E7332D /* lpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 838491011807CDC000E7332D /* lpc.h */; }; + 838491051807CDEC00E7332D /* cbrt_tablegen.h in Headers */ = {isa = PBXBuildFile; fileRef = 838491041807CDEC00E7332D /* cbrt_tablegen.h */; }; + 838491081807CDF400E7332D /* lls.c in Sources */ = {isa = PBXBuildFile; fileRef = 838491061807CDF400E7332D /* lls.c */; }; + 838491091807CDF400E7332D /* lls.h in Headers */ = {isa = PBXBuildFile; fileRef = 838491071807CDF400E7332D /* lls.h */; }; + 8384910B1807CE2A00E7332D /* lls_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384910A1807CE2A00E7332D /* lls_init.c */; }; + 8384910D1807CEB600E7332D /* sbrdsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384910C1807CEB600E7332D /* sbrdsp.c */; }; + 8384910F1807CEC400E7332D /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384910E1807CEC400E7332D /* lpc.c */; }; + 838491111807CEF400E7332D /* sbrdsp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 838491101807CEF400E7332D /* sbrdsp_init.c */; }; + 838491131807D06100E7332D /* spdifdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 838491121807D06100E7332D /* spdifdec.c */; }; 8393B7E218052BB000913C76 /* mp3dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7DF18052BB000913C76 /* mp3dec.c */; }; 8393B7E318052BB000913C76 /* mpeg.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7E018052BB000913C76 /* mpeg.c */; }; 8393B7E418052BB000913C76 /* mpeg.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7E118052BB000913C76 /* mpeg.h */; }; @@ -717,6 +770,59 @@ 838490971807BC9C00E7332D /* dtsdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dtsdec.c; sourceTree = ""; }; 8384909A1807BE1300E7332D /* synth_filter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = synth_filter.c; sourceTree = ""; }; 8384909B1807BE1300E7332D /* synth_filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = synth_filter.h; sourceTree = ""; }; + 8384909E1807C12300E7332D /* adpcm_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm_data.c; sourceTree = ""; }; + 8384909F1807C12300E7332D /* adpcm_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm_data.h; sourceTree = ""; }; + 838490A01807C12300E7332D /* adpcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm.c; sourceTree = ""; }; + 838490A11807C12300E7332D /* adpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm.h; sourceTree = ""; }; + 838490A21807C12300E7332D /* pcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pcm.c; sourceTree = ""; }; + 838490A81807C1C300E7332D /* gsm_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gsm_parser.c; sourceTree = ""; }; + 838490A91807C1C300E7332D /* gsm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gsm.h; sourceTree = ""; }; + 838490AA1807C1C300E7332D /* gsmdec_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gsmdec_data.c; sourceTree = ""; }; + 838490AB1807C1C300E7332D /* gsmdec_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gsmdec_data.h; sourceTree = ""; }; + 838490AC1807C1C300E7332D /* gsmdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gsmdec.c; sourceTree = ""; }; + 838490AD1807C1C300E7332D /* msgsmdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = msgsmdec.c; sourceTree = ""; }; + 838490AE1807C1C300E7332D /* msgsmdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgsmdec.h; sourceTree = ""; }; + 838490AF1807C1C300E7332D /* truespeech_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = truespeech_data.h; sourceTree = ""; }; + 838490B01807C1C300E7332D /* truespeech.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = truespeech.c; sourceTree = ""; }; + 838490BA1807C30900E7332D /* pcm_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pcm_tablegen.h; sourceTree = ""; }; + 838490BC1807C34900E7332D /* atrac3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac3.c; sourceTree = ""; }; + 838490BD1807C34900E7332D /* atrac3data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atrac3data.h; sourceTree = ""; }; + 838490C01807C37300E7332D /* atrac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac.c; sourceTree = ""; }; + 838490C11807C37300E7332D /* atrac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atrac.h; sourceTree = ""; }; + 838490CA1807C47E00E7332D /* g729.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g729.h; sourceTree = ""; }; + 838490CB1807C47E00E7332D /* g729data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g729data.h; sourceTree = ""; }; + 838490CC1807C47E00E7332D /* g729dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g729dec.c; sourceTree = ""; }; + 838490CD1807C47E00E7332D /* g729postfilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g729postfilter.c; sourceTree = ""; }; + 838490CE1807C47E00E7332D /* g729postfilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g729postfilter.h; sourceTree = ""; }; + 838490CF1807C47E00E7332D /* g726.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g726.c; sourceTree = ""; }; + 838490D01807C47E00E7332D /* g723_1_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g723_1_data.h; sourceTree = ""; }; + 838490D11807C47E00E7332D /* g723_1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g723_1.c; sourceTree = ""; }; + 838490D21807C47E00E7332D /* g722dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g722dec.c; sourceTree = ""; }; + 838490D31807C47E00E7332D /* g722.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g722.c; sourceTree = ""; }; + 838490D41807C47E00E7332D /* g722.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g722.h; sourceTree = ""; }; + 838490E01807C57B00E7332D /* aac_adtstoasc_bsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aac_adtstoasc_bsf.c; sourceTree = ""; }; + 838490E11807C57B00E7332D /* aac_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aac_parser.c; sourceTree = ""; }; + 838490E21807C57B00E7332D /* aacadtsdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacadtsdec.c; sourceTree = ""; }; + 838490E31807C57B00E7332D /* aacadtsdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacadtsdec.h; sourceTree = ""; }; + 838490E51807C57B00E7332D /* aacdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacdec.c; sourceTree = ""; }; + 838490E61807C57B00E7332D /* aacdectab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacdectab.h; sourceTree = ""; }; + 838490E71807C57B00E7332D /* aacps_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacps_tablegen.h; sourceTree = ""; }; + 838490E81807C57B00E7332D /* aacps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacps.c; sourceTree = ""; }; + 838490EA1807C57B00E7332D /* aacpsdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacpsdsp.c; sourceTree = ""; }; + 838490EC1807C57B00E7332D /* aacsbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacsbr.c; sourceTree = ""; }; + 838490ED1807C57B00E7332D /* aacsbr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacsbr.h; sourceTree = ""; }; + 838490EE1807C57B00E7332D /* aacsbrdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacsbrdata.h; sourceTree = ""; }; + 838490FE1807C58500E7332D /* aacdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacdec.c; sourceTree = ""; }; + 838491001807CDC000E7332D /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = ""; }; + 838491011807CDC000E7332D /* lpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lpc.h; sourceTree = ""; }; + 838491041807CDEC00E7332D /* cbrt_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cbrt_tablegen.h; sourceTree = ""; }; + 838491061807CDF400E7332D /* lls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lls.c; sourceTree = ""; }; + 838491071807CDF400E7332D /* lls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lls.h; sourceTree = ""; }; + 8384910A1807CE2A00E7332D /* lls_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lls_init.c; sourceTree = ""; }; + 8384910C1807CEB600E7332D /* sbrdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbrdsp.c; sourceTree = ""; }; + 8384910E1807CEC400E7332D /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = ""; }; + 838491101807CEF400E7332D /* sbrdsp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbrdsp_init.c; sourceTree = ""; }; + 838491121807D06100E7332D /* spdifdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spdifdec.c; sourceTree = ""; }; 8393B7DF18052BB000913C76 /* mp3dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3dec.c; sourceTree = ""; }; 8393B7E018052BB000913C76 /* mpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg.c; sourceTree = ""; }; 8393B7E118052BB000913C76 /* mpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpeg.h; sourceTree = ""; }; @@ -829,6 +935,52 @@ 830F0B8E17FC4FB900042E8F /* libavcodec */ = { isa = PBXGroup; children = ( + 8384910C1807CEB600E7332D /* sbrdsp.c */, + 838491041807CDEC00E7332D /* cbrt_tablegen.h */, + 838491001807CDC000E7332D /* lpc.c */, + 838491011807CDC000E7332D /* lpc.h */, + 838490E01807C57B00E7332D /* aac_adtstoasc_bsf.c */, + 838490E11807C57B00E7332D /* aac_parser.c */, + 838490E21807C57B00E7332D /* aacadtsdec.c */, + 838490E31807C57B00E7332D /* aacadtsdec.h */, + 838490E51807C57B00E7332D /* aacdec.c */, + 838490E61807C57B00E7332D /* aacdectab.h */, + 838490E71807C57B00E7332D /* aacps_tablegen.h */, + 838490E81807C57B00E7332D /* aacps.c */, + 838490EA1807C57B00E7332D /* aacpsdsp.c */, + 838490EC1807C57B00E7332D /* aacsbr.c */, + 838490ED1807C57B00E7332D /* aacsbr.h */, + 838490EE1807C57B00E7332D /* aacsbrdata.h */, + 838490CA1807C47E00E7332D /* g729.h */, + 838490CB1807C47E00E7332D /* g729data.h */, + 838490CC1807C47E00E7332D /* g729dec.c */, + 838490CD1807C47E00E7332D /* g729postfilter.c */, + 838490CE1807C47E00E7332D /* g729postfilter.h */, + 838490CF1807C47E00E7332D /* g726.c */, + 838490D01807C47E00E7332D /* g723_1_data.h */, + 838490D11807C47E00E7332D /* g723_1.c */, + 838490D21807C47E00E7332D /* g722dec.c */, + 838490D31807C47E00E7332D /* g722.c */, + 838490D41807C47E00E7332D /* g722.h */, + 838490C01807C37300E7332D /* atrac.c */, + 838490C11807C37300E7332D /* atrac.h */, + 838490BC1807C34900E7332D /* atrac3.c */, + 838490BD1807C34900E7332D /* atrac3data.h */, + 838490BA1807C30900E7332D /* pcm_tablegen.h */, + 838490A81807C1C300E7332D /* gsm_parser.c */, + 838490A91807C1C300E7332D /* gsm.h */, + 838490AA1807C1C300E7332D /* gsmdec_data.c */, + 838490AB1807C1C300E7332D /* gsmdec_data.h */, + 838490AC1807C1C300E7332D /* gsmdec.c */, + 838490AD1807C1C300E7332D /* msgsmdec.c */, + 838490AE1807C1C300E7332D /* msgsmdec.h */, + 838490AF1807C1C300E7332D /* truespeech_data.h */, + 838490B01807C1C300E7332D /* truespeech.c */, + 8384909E1807C12300E7332D /* adpcm_data.c */, + 8384909F1807C12300E7332D /* adpcm_data.h */, + 838490A01807C12300E7332D /* adpcm.c */, + 838490A11807C12300E7332D /* adpcm.h */, + 838490A21807C12300E7332D /* pcm.c */, 8384909A1807BE1300E7332D /* synth_filter.c */, 8384909B1807BE1300E7332D /* synth_filter.h */, 838490861807BC9400E7332D /* dca_parser.c */, @@ -1032,6 +1184,8 @@ 830F0BAD17FC4FB900042E8F /* libavformat */ = { isa = PBXGroup; children = ( + 838491121807D06100E7332D /* spdifdec.c */, + 838490FE1807C58500E7332D /* aacdec.c */, 838490961807BC9C00E7332D /* dtshddec.c */, 838490971807BC9C00E7332D /* dtsdec.c */, 838490681807AF5800E7332D /* ac3dec.c */, @@ -1107,6 +1261,8 @@ 830F0BBA17FC4FB900042E8F /* libavutil */ = { isa = PBXGroup; children = ( + 838491061807CDF400E7332D /* lls.c */, + 838491071807CDF400E7332D /* lls.h */, 838490721807B07000E7332D /* md5.c */, 838490731807B07000E7332D /* md5.h */, 8384906E1807B04200E7332D /* lfg.c */, @@ -1211,6 +1367,7 @@ 830F0C2017FC527400042E8F /* x86 */ = { isa = PBXGroup; children = ( + 8384910A1807CE2A00E7332D /* lls_init.c */, 830F0DBF17FC927D00042E8F /* float_dsp_init.c */, 830F0DB317FC921D00042E8F /* asm.h */, 830F0DB417FC921D00042E8F /* cpu.c */, @@ -1233,6 +1390,8 @@ 830F0D0717FC80B400042E8F /* x86 */ = { isa = PBXGroup; children = ( + 838491101807CEF400E7332D /* sbrdsp_init.c */, + 8384910E1807CEC400E7332D /* lpc.c */, 838490841807B17C00E7332D /* ac3dsp_init.c */, 8393B80D18052BD500913C76 /* mpegaudiodsp.c */, 833C37D618032EA500CBA602 /* idct_xvid.h */, @@ -1278,9 +1437,11 @@ 830F0C0517FC4FB900042E8F /* intfloat_readwrite.h in Headers */, 830F0C0417FC4FB900042E8F /* intfloat.h in Headers */, 830F0C0717FC4FB900042E8F /* mathematics.h in Headers */, + 838491031807CDC000E7332D /* lpc.h in Headers */, 830F0BF317FC4FB900042E8F /* avio.h in Headers */, 830F0C0C17FC4FB900042E8F /* rational.h in Headers */, 830F0C0617FC4FB900042E8F /* log.h in Headers */, + 838490DB1807C47E00E7332D /* g723_1_data.h in Headers */, 830F0C0317FC4FB900042E8F /* frame.h in Headers */, 830F0C0117FC4FB900042E8F /* dict.h in Headers */, 8393B80418052BC200913C76 /* mpegaudiodectab.h in Headers */, @@ -1288,6 +1449,7 @@ 830F0C0017FC4FB900042E8F /* cpu.h in Headers */, 830F0C0217FC4FB900042E8F /* error.h in Headers */, 830F0C0917FC4FB900042E8F /* mem.h in Headers */, + 838490BB1807C30900E7332D /* pcm_tablegen.h in Headers */, 830F0BE317FC4FB900042E8F /* version.h in Headers */, 830F0BFA17FC4FB900042E8F /* attributes.h in Headers */, 830F0BFF17FC4FB900042E8F /* common.h in Headers */, @@ -1296,6 +1458,7 @@ 830F0BFD17FC4FB900042E8F /* buffer.h in Headers */, 838490911807BC9400E7332D /* dcadata.h in Headers */, 8393B80A18052BC200913C76 /* mpegaudiodsp.h in Headers */, + 838490B71807C1C300E7332D /* msgsmdec.h in Headers */, 830F0C1217FC4FF400042E8F /* avfft.h in Headers */, 830F0BF017FC4FB900042E8F /* avformat.h in Headers */, B09E94940D74834B0064F138 /* config.h in Headers */, @@ -1305,6 +1468,7 @@ 830F0D8917FC8E8B00042E8F /* aac_tablegen.h in Headers */, 830F0D3117FC841B00042E8F /* imgutils.h in Headers */, 830F0C6C17FC7DB100042E8F /* bprint.h in Headers */, + 838490D51807C47E00E7332D /* g729.h in Headers */, 830F0CE117FC7F1E00042E8F /* fmtconvert.h in Headers */, 830F0D7717FC8C7300042E8F /* aac.h in Headers */, 8393B7FF18052BC200913C76 /* mpegaudiodata.h in Headers */, @@ -1322,20 +1486,25 @@ 830F0BF917FC4FB900042E8F /* os_support.h in Headers */, 8384906D1807AFB800E7332D /* aac_ac3_parser.h in Headers */, 838490611807AF0100E7332D /* ac3dec_data.h in Headers */, + 838490FD1807C57B00E7332D /* aacsbrdata.h in Headers */, 830F0D2217FC82AB00042E8F /* eval.h in Headers */, 8384909D1807BE1300E7332D /* synth_filter.h in Headers */, 830F0C2A17FC54F800042E8F /* rtpdec.h in Headers */, 830F0CFF17FC7F1E00042E8F /* wma.h in Headers */, 830F0C4E17FC7CA300042E8F /* metadata.h in Headers */, 830F0C4B17FC7CA300042E8F /* id3v2.h in Headers */, + 838490A41807C12300E7332D /* adpcm_data.h in Headers */, + 838490B81807C1C300E7332D /* truespeech_data.h in Headers */, 830F0CFB17FC7F1E00042E8F /* thread.h in Headers */, 830F0D6617FC8A3300042E8F /* options_table.h in Headers */, 830F0CF317FC7F1E00042E8F /* raw.h in Headers */, + 838490D61807C47E00E7332D /* g729data.h in Headers */, 833C37B618032AEF00CBA602 /* diracdsp_mmx.h in Headers */, 833C37B418032AEF00CBA602 /* dsputil.h in Headers */, 830F0C3F17FC554D00042E8F /* timer.h in Headers */, 830F0D1E17FC82AB00042E8F /* colorspace.h in Headers */, 830F0DBA17FC921D00042E8F /* cpu.h in Headers */, + 838491051807CDEC00E7332D /* cbrt_tablegen.h in Headers */, 830F0C7317FC7DB100042E8F /* version.h in Headers */, 830F0BDF17FC4FB900042E8F /* put_bits.h in Headers */, 830F0C7217FC7DB100042E8F /* rc4.h in Headers */, @@ -1349,6 +1518,7 @@ 830F0CEC17FC7F1E00042E8F /* lsp.h in Headers */, 830F0D6517FC8A3300042E8F /* audiointerleave.h in Headers */, 833C37A318032A2F00CBA602 /* rawdec.h in Headers */, + 838490DF1807C47E00E7332D /* g722.h in Headers */, 830F0D3D17FC846C00042E8F /* random_seed.h in Headers */, 830F0CCA17FC7F1E00042E8F /* bytestream.h in Headers */, 830F0D0317FC7F4000042E8F /* sinewin_tablegen.h in Headers */, @@ -1382,6 +1552,7 @@ 830F0C2417FC527400042E8F /* atomic.h in Headers */, 830F0C5D17FC7CEA00042E8F /* id3v1.h in Headers */, 838490631807AF0100E7332D /* ac3dec.h in Headers */, + 838490C31807C37300E7332D /* atrac.h in Headers */, 830F0C6A17FC7DB100042E8F /* avassert.h in Headers */, 830F0D6D17FC8C0700042E8F /* aactab.h in Headers */, 830F0BEC17FC4FB900042E8F /* wmavoice_data.h in Headers */, @@ -1396,6 +1567,8 @@ 830F0C6D17FC7DB100042E8F /* buffer_internal.h in Headers */, 830F0DBB17FC921D00042E8F /* emms.h in Headers */, 830F0C2217FC527400042E8F /* atomic_gcc.h in Headers */, + 838491091807CDF400E7332D /* lls.h in Headers */, + 838490F21807C57B00E7332D /* aacadtsdec.h in Headers */, 830F0CD117FC7F1E00042E8F /* dct.h in Headers */, 830F0DBC17FC921D00042E8F /* timer.h in Headers */, 830F0CE617FC7F1E00042E8F /* h264chroma.h in Headers */, @@ -1411,10 +1584,12 @@ 830F0CE817FC7F1E00042E8F /* hpeldsp.h in Headers */, 830F0D8B17FC8E8B00042E8F /* aacpsdsp.h in Headers */, 830F0CD617FC7F1E00042E8F /* dctref.h in Headers */, + 838490F61807C57B00E7332D /* aacps_tablegen.h in Headers */, 830F0C1917FC523000042E8F /* rdt.h in Headers */, 838490941807BC9400E7332D /* dcadsp.h in Headers */, 8393B80C18052BC200913C76 /* mpegaudiotab.h in Headers */, 838490951807BC9400E7332D /* dcahuff.h in Headers */, + 838490A61807C12300E7332D /* adpcm.h in Headers */, 830F0CF117FC7F1E00042E8F /* ratecontrol.h in Headers */, 830F0C1417FC500B00042E8F /* fft-internal.h in Headers */, 830F0D8E17FC8E8B00042E8F /* sbr.h in Headers */, @@ -1428,16 +1603,21 @@ 83BCB8E417FCA64400760340 /* timecode.h in Headers */, 830F0DCE17FC933100042E8F /* w64.h in Headers */, 830F0C3E17FC554D00042E8F /* libm.h in Headers */, + 838490FC1807C57B00E7332D /* aacsbr.h in Headers */, 830F0C4C17FC7CA300042E8F /* internal.h in Headers */, + 838490BF1807C34900E7332D /* atrac3data.h in Headers */, 830F0BFC17FC4FB900042E8F /* bswap.h in Headers */, 830F0D8A17FC8E8B00042E8F /* aacps.h in Headers */, 833C37C818032CF600CBA602 /* dirac.h in Headers */, 830F0BD617FC4FB900042E8F /* fft.h in Headers */, + 838490F51807C57B00E7332D /* aacdectab.h in Headers */, 838490791807B13000E7332D /* kbdwin.h in Headers */, 830F0CE317FC7F1E00042E8F /* frame_thread_encoder.h in Headers */, 830F0BE617FC4FB900042E8F /* wmadata.h in Headers */, 830F0C5717FC7CC300042E8F /* avlanguage.h in Headers */, 830F0D2417FC82AB00042E8F /* fifo.h in Headers */, + 838490B21807C1C300E7332D /* gsm.h in Headers */, + 838490B41807C1C300E7332D /* gsmdec_data.h in Headers */, 830F0BD917FC4FB900042E8F /* mathops.h in Headers */, 8393B7E418052BB000913C76 /* mpeg.h in Headers */, 830F0C3C17FC554D00042E8F /* float_dsp.h in Headers */, @@ -1446,6 +1626,7 @@ 833C379C180328B300CBA602 /* tak.h in Headers */, 830F0DB817FC921D00042E8F /* asm.h in Headers */, 830F0CC517FC7F1E00042E8F /* acelp_pitch_delay.h in Headers */, + 838490D91807C47E00E7332D /* g729postfilter.h in Headers */, 830F0D8F17FC8E8B00042E8F /* sbrdsp.h in Headers */, 830F0CCE17FC7F1E00042E8F /* celp_math.h in Headers */, 8384905D1807AF0100E7332D /* ac3_parser.h in Headers */, @@ -1518,10 +1699,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 838490DA1807C47E00E7332D /* g726.c in Sources */, + 838491081807CDF400E7332D /* lls.c in Sources */, 833C37A918032AAD00CBA602 /* img2.c in Sources */, 838490701807B04200E7332D /* lfg.c in Sources */, 838490981807BC9C00E7332D /* dtshddec.c in Sources */, 830F0D6717FC8A3300042E8F /* options.c in Sources */, + 838490FB1807C57B00E7332D /* aacsbr.c in Sources */, 830F0DAF17FC8FBD00042E8F /* fmtconvert_init.c in Sources */, 830F0DD617FC93E400042E8F /* xwma.c in Sources */, 830F0DAD17FC8FBD00042E8F /* dct_init.c in Sources */, @@ -1547,6 +1731,7 @@ 838490741807B07000E7332D /* md5.c in Sources */, 8393B80E18052BD500913C76 /* mpegaudiodsp.c in Sources */, 8384909C1807BE1300E7332D /* synth_filter.c in Sources */, + 8384910B1807CE2A00E7332D /* lls_init.c in Sources */, 8393B81418052E7400913C76 /* mpegaudiodsp.c in Sources */, 830F0CF917FC7F1E00042E8F /* sinewin.c in Sources */, 833C37C418032CF600CBA602 /* dirac_dwt.c in Sources */, @@ -1561,6 +1746,7 @@ 830F0D5917FC893E00042E8F /* codec_desc.c in Sources */, 830F0DBE17FC922C00042E8F /* h264chroma_init.c in Sources */, 830F0BF217FC4FB900042E8F /* avio.c in Sources */, + 838490DC1807C47E00E7332D /* g723_1.c in Sources */, 830F0CE217FC7F1E00042E8F /* frame_thread_encoder.c in Sources */, 8393B80118052BC200913C76 /* mpegaudiodec.c in Sources */, 830F0C3817FC554D00042E8F /* buffer.c in Sources */, @@ -1571,8 +1757,11 @@ 830F0D6917FC8A3D00042E8F /* avpicture.c in Sources */, 8393B80518052BC200913C76 /* mpegaudiodsp_data.c in Sources */, 830F0CDA17FC7F1E00042E8F /* error_resilience.c in Sources */, + 838490A51807C12300E7332D /* adpcm.c in Sources */, 830F0D3317FC841B00042E8F /* opt.c in Sources */, + 838490BE1807C34900E7332D /* atrac3.c in Sources */, 838490921807BC9400E7332D /* dcadec.c in Sources */, + 838490F71807C57B00E7332D /* aacps.c in Sources */, 830F0D7317FC8C1300042E8F /* astdec.c in Sources */, 8384905E1807AF0100E7332D /* ac3.c in Sources */, 830F0D5317FC891800042E8F /* file_open.c in Sources */, @@ -1581,21 +1770,27 @@ 830F0D4F17FC862400042E8F /* utils.c in Sources */, 8393B81218052DB700913C76 /* mp3_header_decompress_bsf.c in Sources */, 830F0BEB17FC4FB900042E8F /* wmavoice.c in Sources */, + 838490D71807C47E00E7332D /* g729dec.c in Sources */, 833C37B318032AEF00CBA602 /* dsputil.c in Sources */, 830F0CC217FC7F1E00042E8F /* acelp_filters.c in Sources */, 830F0DB017FC8FBD00042E8F /* hpeldsp_init.c in Sources */, 830F0C1B17FC523000042E8F /* url.c in Sources */, 830F0CC417FC7F1E00042E8F /* acelp_pitch_delay.c in Sources */, 8393B80218052BC200913C76 /* mpegaudiodecheader.c in Sources */, + 838490A31807C12300E7332D /* adpcm_data.c in Sources */, 8384908E1807BC9400E7332D /* dca_parser.c in Sources */, 8384908F1807BC9400E7332D /* dca.c in Sources */, 833C37C218032CF600CBA602 /* dirac_arith.c in Sources */, + 838490F01807C57B00E7332D /* aac_parser.c in Sources */, 830F0CEB17FC7F1E00042E8F /* lsp.c in Sources */, 830F0D1317FC815000042E8F /* constants.c in Sources */, + 8384910F1807CEC400E7332D /* lpc.c in Sources */, 830F0BE417FC4FB900042E8F /* wma_common.c in Sources */, 8393B7FA18052BC200913C76 /* mpegaudio_tablegen.c in Sources */, 838490601807AF0100E7332D /* ac3dec_data.c in Sources */, 8384907F1807B17500E7332D /* eac3_data.c in Sources */, + 838490B11807C1C300E7332D /* gsm_parser.c in Sources */, + 838490DD1807C47E00E7332D /* g722dec.c in Sources */, 830F0C5617FC7CC300042E8F /* avlanguage.c in Sources */, 830F0C5117FC7CA300042E8F /* riffdec.c in Sources */, 830F0D4617FC85ED00042E8F /* integer.c in Sources */, @@ -1603,7 +1798,10 @@ 830F0CE917FC7F1E00042E8F /* imgconvert.c in Sources */, 830F0CE717FC7F1E00042E8F /* hpeldsp.c in Sources */, 830F0CCB17FC7F1E00042E8F /* celp_filters.c in Sources */, + 838491131807D06100E7332D /* spdifdec.c in Sources */, 833C37B518032AEF00CBA602 /* diracdsp_mmx.c in Sources */, + 838490B61807C1C300E7332D /* msgsmdec.c in Sources */, + 838490B31807C1C300E7332D /* gsmdec_data.c in Sources */, 830F0BF717FC4FB900042E8F /* format.c in Sources */, 830F0CC817FC7F1E00042E8F /* avpacket.c in Sources */, 833C37CE18032D4800CBA602 /* golomb.c in Sources */, @@ -1611,6 +1809,7 @@ 833C37C918032CF600CBA602 /* diracdec.c in Sources */, 830F0CD217FC7F1E00042E8F /* dct32_float.c in Sources */, 830F0D3217FC841B00042E8F /* intfloat_readwrite.c in Sources */, + 838490C21807C37300E7332D /* atrac.c in Sources */, 830F0DC917FC931700042E8F /* pcm.c in Sources */, 830F0CD317FC7F1E00042E8F /* dct32.c in Sources */, 830F0D2517FC82AB00042E8F /* frame.c in Sources */, @@ -1624,10 +1823,14 @@ 830F0CC917FC7F1E00042E8F /* bit_depth_template.c in Sources */, 8384906C1807AFB800E7332D /* aac_ac3_parser.c in Sources */, 8393B7E318052BB000913C76 /* mpeg.c in Sources */, + 838491111807CEF400E7332D /* sbrdsp_init.c in Sources */, 830F0D4017FC848D00042E8F /* sha.c in Sources */, + 838490EF1807C57B00E7332D /* aac_adtstoasc_bsf.c in Sources */, 830F0BF417FC4FB900042E8F /* aviobuf.c in Sources */, 830F0C1117FC4FF400042E8F /* avfft.c in Sources */, 830F0DC617FC92FA00042E8F /* wavdec.c in Sources */, + 838490DE1807C47E00E7332D /* g722.c in Sources */, + 838490F91807C57B00E7332D /* aacpsdsp.c in Sources */, 830F0BDA17FC4FB900042E8F /* mathtables.c in Sources */, 830F0C5917FC7CC300042E8F /* utils.c in Sources */, 838490641807AF0100E7332D /* ac3dsp.c in Sources */, @@ -1654,6 +1857,7 @@ 830F0CFC17FC7F1E00042E8F /* videodsp.c in Sources */, 830F0D8C17FC8E8B00042E8F /* dv_profile.c in Sources */, 833C37B118032AEF00CBA602 /* diracdsp.c in Sources */, + 838490A71807C12300E7332D /* pcm.c in Sources */, 838490691807AF5800E7332D /* ac3dec.c in Sources */, 830F0CD017FC7F1E00042E8F /* dct.c in Sources */, 833C3795180328A300CBA602 /* takdec.c in Sources */, @@ -1665,10 +1869,12 @@ 830F0CE517FC7F1E00042E8F /* h264chroma.c in Sources */, 830F0BE717FC4FB900042E8F /* wmadec.c in Sources */, 838490931807BC9400E7332D /* dcadsp.c in Sources */, + 838490FF1807C58500E7332D /* aacdec.c in Sources */, 830F0CC617FC7F1E00042E8F /* acelp_vectors.c in Sources */, 830F0DC417FC92EE00042E8F /* videodsp_init.c in Sources */, 833C379A180328B300CBA602 /* tak_parser.c in Sources */, 830F0C2E17FC551F00042E8F /* asfcrypt.c in Sources */, + 838490B51807C1C300E7332D /* gsmdec.c in Sources */, 830F0D6C17FC8C0700042E8F /* aactab.c in Sources */, 830F0D9217FC8EAC00042E8F /* dvdata.c in Sources */, 833C37D018032D4800CBA602 /* dirac_dwt.c in Sources */, @@ -1676,6 +1882,7 @@ 830F0D3817FC844E00042E8F /* parseutils.c in Sources */, 830F0D2017FC82AB00042E8F /* cpu.c in Sources */, 8393B7FC18052BC200913C76 /* mpegaudio.c in Sources */, + 838490D81807C47E00E7332D /* g729postfilter.c in Sources */, 833C37C618032CF600CBA602 /* dirac_parser.c in Sources */, 830F0CED17FC7F1E00042E8F /* mpeg12data.c in Sources */, 838490811807B17500E7332D /* eac3dec.c in Sources */, @@ -1686,6 +1893,8 @@ 838490621807AF0100E7332D /* ac3dec.c in Sources */, 83BCB8E317FCA64400760340 /* timecode.c in Sources */, 8393B80B18052BC200913C76 /* mpegaudioenc.c in Sources */, + 8384910D1807CEB600E7332D /* sbrdsp.c in Sources */, + 838490B91807C1C300E7332D /* truespeech.c in Sources */, 830F0D3517FC841B00042E8F /* samplefmt.c in Sources */, 830F0BEA17FC4FB900042E8F /* wmaprodec.c in Sources */, 830F0CCD17FC7F1E00042E8F /* celp_math.c in Sources */, @@ -1693,11 +1902,14 @@ 830F0C8317FC7ED100042E8F /* rational.c in Sources */, 830F0CD517FC7F1E00042E8F /* dctref.c in Sources */, 8393B81118052DB700913C76 /* bitstream_filter.c in Sources */, + 838490F11807C57B00E7332D /* aacadtsdec.c in Sources */, 830F0D2317FC82AB00042E8F /* fifo.c in Sources */, 830F0D3C17FC846C00042E8F /* random_seed.c in Sources */, 830F0C4F17FC7CA300042E8F /* riff.c in Sources */, + 838490F41807C57B00E7332D /* aacdec.c in Sources */, 830F0C4D17FC7CA300042E8F /* metadata.c in Sources */, 8393B80018052BC200913C76 /* mpegaudiodec_float.c in Sources */, + 838491021807CDC000E7332D /* lpc.c in Sources */, 830F0C7C17FC7E4E00042E8F /* log.c in Sources */, 830F0D6417FC8A3300042E8F /* audiointerleave.c in Sources */, ); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/config.h b/Frameworks/FFMPEG/ffmpeg-minimal/config.h index 7f4b69d2b..a4fd40d8e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/config.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/config.h @@ -385,7 +385,7 @@ #define CONFIG_ZMBV_DECODER 0 #define CONFIG_AAC_ENCODER 0 -#define CONFIG_AAC_DECODER 0 +#define CONFIG_AAC_DECODER 1 #define CONFIG_AAC_LATM_DECODER 0 #define CONFIG_AC3_ENCODER 0 #define CONFIG_AC3_DECODER 1 @@ -397,7 +397,7 @@ #define CONFIG_AMRWB_DECODER 0 #define CONFIG_APE_DECODER 1 #define CONFIG_ATRAC1_DECODER 0 -#define CONFIG_ATRAC3_DECODER 0 +#define CONFIG_ATRAC3_DECODER 1 #define CONFIG_BINKAUDIO_DCT_DECODER 0 #define CONFIG_BINKAUDIO_RDFT_DECODER 0 #define CONFIG_BMV_AUDIO_DECODER 0 @@ -412,10 +412,10 @@ #define CONFIG_FLAC_ENCODER 0 #define CONFIG_FLAC_DECODER 0 #define CONFIG_G723_1_ENCODER 0 -#define CONFIG_G723_1_DECODER 0 -#define CONFIG_G729_DECODER 0 -#define CONFIG_GSM_DECODER 0 -#define CONFIG_GSM_MS_DECODER 0 +#define CONFIG_G723_1_DECODER 1 +#define CONFIG_G729_DECODER 1 +#define CONFIG_GSM_DECODER 1 +#define CONFIG_GSM_MS_DECODER 1 #define CONFIG_IAC_DECODER 0 #define CONFIG_IMC_DECODER 0 #define CONFIG_MACE3_DECODER 0 @@ -472,61 +472,61 @@ #define CONFIG_WS_SND1_DECODER 0 #define CONFIG_PCM_ALAW_ENCODER 0 -#define CONFIG_PCM_ALAW_DECODER 0 +#define CONFIG_PCM_ALAW_DECODER 1 #define CONFIG_PCM_BLURAY_DECODER 0 #define CONFIG_PCM_DVD_DECODER 0 #define CONFIG_PCM_F32BE_ENCODER 0 -#define CONFIG_PCM_F32BE_DECODER 0 +#define CONFIG_PCM_F32BE_DECODER 1 #define CONFIG_PCM_F32LE_ENCODER 0 -#define CONFIG_PCM_F32LE_DECODER 0 +#define CONFIG_PCM_F32LE_DECODER 1 #define CONFIG_PCM_F64BE_ENCODER 0 -#define CONFIG_PCM_F64BE_DECODER 0 +#define CONFIG_PCM_F64BE_DECODER 1 #define CONFIG_PCM_F64LE_ENCODER 0 -#define CONFIG_PCM_F64LE_DECODER 0 +#define CONFIG_PCM_F64LE_DECODER 1 #define CONFIG_PCM_LXF_DECODER 0 #define CONFIG_PCM_MULAW_ENCODER 0 -#define CONFIG_PCM_MULAW_DECODER 0 +#define CONFIG_PCM_MULAW_DECODER 1 #define CONFIG_PCM_S8_ENCODER 0 -#define CONFIG_PCM_S8_DECODER 0 +#define CONFIG_PCM_S8_DECODER 1 #define CONFIG_PCM_S8_PLANAR_ENCODER 0 -#define CONFIG_PCM_S8_PLANAR_DECODER 0 +#define CONFIG_PCM_S8_PLANAR_DECODER 1 #define CONFIG_PCM_S16BE_ENCODER 0 -#define CONFIG_PCM_S16BE_DECODER 0 +#define CONFIG_PCM_S16BE_DECODER 1 #define CONFIG_PCM_S16BE_PLANAR_ENCODER 0 -#define CONFIG_PCM_S16BE_PLANAR_DECODER 0 +#define CONFIG_PCM_S16BE_PLANAR_DECODER 1 #define CONFIG_PCM_S16LE_ENCODER 0 -#define CONFIG_PCM_S16LE_DECODER 0 +#define CONFIG_PCM_S16LE_DECODER 1 #define CONFIG_PCM_S16LE_PLANAR_ENCODER 0 -#define CONFIG_PCM_S16LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S16LE_PLANAR_DECODER 1 #define CONFIG_PCM_S24BE_ENCODER 0 -#define CONFIG_PCM_S24BE_DECODER 0 +#define CONFIG_PCM_S24BE_DECODER 1 #define CONFIG_PCM_S24DAUD_ENCODER 0 -#define CONFIG_PCM_S24DAUD_DECODER 0 +#define CONFIG_PCM_S24DAUD_DECODER 1 #define CONFIG_PCM_S24LE_ENCODER 0 -#define CONFIG_PCM_S24LE_DECODER 0 +#define CONFIG_PCM_S24LE_DECODER 1 #define CONFIG_PCM_S24LE_PLANAR_ENCODER 0 -#define CONFIG_PCM_S24LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S24LE_PLANAR_DECODER 1 #define CONFIG_PCM_S32BE_ENCODER 0 -#define CONFIG_PCM_S32BE_DECODER 0 +#define CONFIG_PCM_S32BE_DECODER 1 #define CONFIG_PCM_S32LE_ENCODER 0 -#define CONFIG_PCM_S32LE_DECODER 0 +#define CONFIG_PCM_S32LE_DECODER 1 #define CONFIG_PCM_S32LE_PLANAR_ENCODER 0 -#define CONFIG_PCM_S32LE_PLANAR_DECODER 0 +#define CONFIG_PCM_S32LE_PLANAR_DECODER 1 #define CONFIG_PCM_U8_ENCODER 0 -#define CONFIG_PCM_U8_DECODER 0 +#define CONFIG_PCM_U8_DECODER 1 #define CONFIG_PCM_U16BE_ENCODER 0 -#define CONFIG_PCM_U16BE_DECODER 0 +#define CONFIG_PCM_U16BE_DECODER 1 #define CONFIG_PCM_U16LE_ENCODER 0 -#define CONFIG_PCM_U16LE_DECODER 0 +#define CONFIG_PCM_U16LE_DECODER 1 #define CONFIG_PCM_U24BE_ENCODER 0 -#define CONFIG_PCM_U24BE_DECODER 0 +#define CONFIG_PCM_U24BE_DECODER 1 #define CONFIG_PCM_U24LE_ENCODER 0 -#define CONFIG_PCM_U24LE_DECODER 0 +#define CONFIG_PCM_U24LE_DECODER 1 #define CONFIG_PCM_U32BE_ENCODER 0 -#define CONFIG_PCM_U32BE_DECODER 0 +#define CONFIG_PCM_U32BE_DECODER 1 #define CONFIG_PCM_U32LE_ENCODER 0 -#define CONFIG_PCM_U32LE_DECODER 0 -#define CONFIG_PCM_ZORK_DECODER 0 +#define CONFIG_PCM_U32LE_DECODER 1 +#define CONFIG_PCM_ZORK_DECODER 1 #define CONFIG_INTERPLAY_DPCM_DECODER 0 #define CONFIG_ROQ_DPCM_ENCODER 0 @@ -538,7 +538,7 @@ #define CONFIG_ADPCM_ADX_ENCODER 0 #define CONFIG_ADPCM_ADX_DECODER 0 #define CONFIG_ADPCM_AFC_DECODER 0 -#define CONFIG_ADPCM_CT_DECODER 0 +#define CONFIG_ADPCM_CT_DECODER 1 #define CONFIG_ADPCM_DTK_DECODER 0 #define CONFIG_ADPCM_EA_DECODER 0 #define CONFIG_ADPCM_EA_MAXIS_XA_DECODER 0 @@ -547,13 +547,13 @@ #define CONFIG_ADPCM_EA_R3_DECODER 0 #define CONFIG_ADPCM_EA_XAS_DECODER 0 #define CONFIG_ADPCM_G722_ENCODER 0 -#define CONFIG_ADPCM_G722_DECODER 0 +#define CONFIG_ADPCM_G722_DECODER 1 #define CONFIG_ADPCM_G726_ENCODER 0 -#define CONFIG_ADPCM_G726_DECODER 0 +#define CONFIG_ADPCM_G726_DECODER 1 #define CONFIG_ADPCM_IMA_AMV_DECODER 0 #define CONFIG_ADPCM_IMA_APC_DECODER 0 -#define CONFIG_ADPCM_IMA_DK3_DECODER 0 -#define CONFIG_ADPCM_IMA_DK4_DECODER 0 +#define CONFIG_ADPCM_IMA_DK3_DECODER 1 +#define CONFIG_ADPCM_IMA_DK4_DECODER 1 #define CONFIG_ADPCM_IMA_EA_EACS_DECODER 0 #define CONFIG_ADPCM_IMA_EA_SEAD_DECODER 0 #define CONFIG_ADPCM_IMA_ISS_DECODER 0 @@ -655,7 +655,7 @@ #define CONFIG_XBIN_DECODER 0 #define CONFIG_IDF_DECODER 0 -#define CONFIG_AAC_PARSER 0 +#define CONFIG_AAC_PARSER 1 #define CONFIG_AAC_LATM_PARSER 0 #define CONFIG_AC3_PARSER 1 #define CONFIG_ADX_PARSER 0 @@ -688,7 +688,7 @@ #define CONFIG_VP3_PARSER 0 #define CONFIG_VP8_PARSER 0 -#define CONFIG_AAC_ADTSTOASC_BSF 0 +#define CONFIG_AAC_ADTSTOASC_BSF 1 #define CONFIG_CHOMP_BSF 0 #define CONFIG_DUMP_EXTRADATA_BSF 0 #define CONFIG_H264_MP4TOANNEXB_BSF 0 @@ -704,7 +704,7 @@ #define CONFIG_A64_MUXER 0 -#define CONFIG_AAC_DEMUXER 0 +#define CONFIG_AAC_DEMUXER 1 #define CONFIG_AC3_MUXER 0 #define CONFIG_AC3_DEMUXER 1 #define CONFIG_ACT_DEMUXER 0 @@ -983,7 +983,7 @@ #define CONFIG_SOX_MUXER 0 #define CONFIG_SOX_DEMUXER 0 #define CONFIG_SPDIF_MUXER 0 -#define CONFIG_SPDIF_DEMUXER 0 +#define CONFIG_SPDIF_DEMUXER 1 #define CONFIG_SRT_MUXER 0 #define CONFIG_SRT_DEMUXER 0 #define CONFIG_STR_DEMUXER 0 diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c index 6f1e188c2..618463fa0 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c @@ -83,6 +83,7 @@ get_next: avctx->sample_rate = s->sample_rate; /* allow downmixing to stereo (or mono for AC-3) */ + AV_NOWARN_DEPRECATED( if(avctx->request_channels > 0 && avctx->request_channels < s->channels && (avctx->request_channels <= 2 || @@ -94,6 +95,7 @@ get_next: avctx->channels = s->channels; avctx->channel_layout = s->channel_layout; } + ); s1->duration = s->samples; avctx->audio_service_type = s->service_type; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_adtstoasc_bsf.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_adtstoasc_bsf.c new file mode 100644 index 000000000..54cd68706 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_adtstoasc_bsf.c @@ -0,0 +1,119 @@ +/* + * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter + * Copyright (c) 2009 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "aacadtsdec.h" +#include "put_bits.h" +#include "get_bits.h" +#include "mpeg4audio.h" +#include "internal.h" +#include "libavutil/internal.h" + +typedef struct AACBSFContext { + int first_frame_done; +} AACBSFContext; + +/** + * This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4 + * ADTS header and removes the ADTS header. + */ +static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int keyframe) +{ + GetBitContext gb; + PutBitContext pb; + AACADTSHeaderInfo hdr; + + AACBSFContext *ctx = bsfc->priv_data; + + init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8); + + *poutbuf = (uint8_t*) buf; + *poutbuf_size = buf_size; + + if (avctx->extradata) + if (show_bits(&gb, 12) != 0xfff) + return 0; + + if (avpriv_aac_parse_header(&gb, &hdr) < 0) { + av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); + return -1; + } + + if (!hdr.crc_absent && hdr.num_aac_frames > 1) { + avpriv_report_missing_feature(avctx, + "Multiple RDBs per frame with CRC"); + return AVERROR_PATCHWELCOME; + } + + buf += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; + buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; + + if (!ctx->first_frame_done) { + int pce_size = 0; + uint8_t pce_data[MAX_PCE_SIZE]; + if (!hdr.chan_config) { + init_get_bits(&gb, buf, buf_size * 8); + if (get_bits(&gb, 3) != 5) { + avpriv_report_missing_feature(avctx, + "PCE-based channel configuration " + "without PCE as first syntax " + "element"); + return AVERROR_PATCHWELCOME; + } + init_put_bits(&pb, pce_data, MAX_PCE_SIZE); + pce_size = avpriv_copy_pce_data(&pb, &gb)/8; + flush_put_bits(&pb); + buf_size -= get_bits_count(&gb)/8; + buf += get_bits_count(&gb)/8; + } + avctx->extradata_size = 2 + pce_size; + avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + + init_put_bits(&pb, avctx->extradata, avctx->extradata_size); + put_bits(&pb, 5, hdr.object_type); + put_bits(&pb, 4, hdr.sampling_index); + put_bits(&pb, 4, hdr.chan_config); + put_bits(&pb, 1, 0); //frame length - 1024 samples + put_bits(&pb, 1, 0); //does not depend on core coder + put_bits(&pb, 1, 0); //is not extension + flush_put_bits(&pb); + if (pce_size) { + memcpy(avctx->extradata + 2, pce_data, pce_size); + } + + ctx->first_frame_done = 1; + } + + *poutbuf = (uint8_t*) buf; + *poutbuf_size = buf_size; + + return 0; +} + +AVBitStreamFilter ff_aac_adtstoasc_bsf = { + .name = "aac_adtstoasc", + .priv_data_size = sizeof(AACBSFContext), + .filter = aac_adtstoasc_filter, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_parser.c new file mode 100644 index 000000000..ab6ca4e26 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_parser.c @@ -0,0 +1,69 @@ +/* + * Audio and Video frame extraction + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "parser.h" +#include "aac_ac3_parser.h" +#include "aacadtsdec.h" +#include "get_bits.h" +#include "mpeg4audio.h" + +static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info, + int *need_next_header, int *new_frame_start) +{ + GetBitContext bits; + AACADTSHeaderInfo hdr; + int size; + union { + uint64_t u64; + uint8_t u8[8]; + } tmp; + + tmp.u64 = av_be2ne64(state); + init_get_bits(&bits, tmp.u8+8-AAC_ADTS_HEADER_SIZE, AAC_ADTS_HEADER_SIZE * 8); + + if ((size = avpriv_aac_parse_header(&bits, &hdr)) < 0) + return 0; + *need_next_header = 0; + *new_frame_start = 1; + hdr_info->sample_rate = hdr.sample_rate; + hdr_info->channels = ff_mpeg4audio_channels[hdr.chan_config]; + hdr_info->samples = hdr.samples; + hdr_info->bit_rate = hdr.bit_rate; + return size; +} + +static av_cold int aac_parse_init(AVCodecParserContext *s1) +{ + AACAC3ParseContext *s = s1->priv_data; + s->header_size = AAC_ADTS_HEADER_SIZE; + s->sync = aac_sync; + return 0; +} + + +AVCodecParser ff_aac_parser = { + .codec_ids = { AV_CODEC_ID_AAC }, + .priv_data_size = sizeof(AACAC3ParseContext), + .parser_init = aac_parse_init, + .parser_parse = ff_aac_ac3_parse, + .parser_close = ff_parse_close, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacadtsdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacadtsdec.c new file mode 100644 index 000000000..c9718c459 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacadtsdec.c @@ -0,0 +1,70 @@ +/* + * Audio and Video frame extraction + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2009 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "aac_ac3_parser.h" +#include "aacadtsdec.h" +#include "get_bits.h" +#include "mpeg4audio.h" + +int avpriv_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr) +{ + int size, rdb, ch, sr; + int aot, crc_abs; + + if(get_bits(gbc, 12) != 0xfff) + return AAC_AC3_PARSE_ERROR_SYNC; + + skip_bits1(gbc); /* id */ + skip_bits(gbc, 2); /* layer */ + crc_abs = get_bits1(gbc); /* protection_absent */ + aot = get_bits(gbc, 2); /* profile_objecttype */ + sr = get_bits(gbc, 4); /* sample_frequency_index */ + if(!avpriv_mpeg4audio_sample_rates[sr]) + return AAC_AC3_PARSE_ERROR_SAMPLE_RATE; + skip_bits1(gbc); /* private_bit */ + ch = get_bits(gbc, 3); /* channel_configuration */ + + skip_bits1(gbc); /* original/copy */ + skip_bits1(gbc); /* home */ + + /* adts_variable_header */ + skip_bits1(gbc); /* copyright_identification_bit */ + skip_bits1(gbc); /* copyright_identification_start */ + size = get_bits(gbc, 13); /* aac_frame_length */ + if(size < AAC_ADTS_HEADER_SIZE) + return AAC_AC3_PARSE_ERROR_FRAME_SIZE; + + skip_bits(gbc, 11); /* adts_buffer_fullness */ + rdb = get_bits(gbc, 2); /* number_of_raw_data_blocks_in_frame */ + + hdr->object_type = aot + 1; + hdr->chan_config = ch; + hdr->crc_absent = crc_abs; + hdr->num_aac_frames = rdb + 1; + hdr->sampling_index = sr; + hdr->sample_rate = avpriv_mpeg4audio_sample_rates[sr]; + hdr->samples = (rdb + 1) * 1024; + hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples; + + return size; +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacadtsdec.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacadtsdec.h new file mode 100644 index 000000000..d0584ef36 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacadtsdec.h @@ -0,0 +1,54 @@ +/* + * AAC ADTS header decoding prototypes and structures + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AACADTSDEC_H +#define AVCODEC_AACADTSDEC_H + +#include +#include "get_bits.h" + +#define AAC_ADTS_HEADER_SIZE 7 + +typedef struct AACADTSHeaderInfo { + uint32_t sample_rate; + uint32_t samples; + uint32_t bit_rate; + uint8_t crc_absent; + uint8_t object_type; + uint8_t sampling_index; + uint8_t chan_config; + uint8_t num_aac_frames; +} AACADTSHeaderInfo; + +/** + * Parse AAC frame header. + * Parse the ADTS frame header to the end of the variable header, which is + * the first 54 bits. + * @param[in] gbc BitContext containing the first 54 bits of the frame. + * @param[out] hdr Pointer to struct where header info is written. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the version element is invalid, -3 if the sample rate + * element is invalid, or -4 if the bit rate element is invalid. + */ +int avpriv_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr); + +#endif /* AVCODEC_AACADTSDEC_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdec.c new file mode 100644 index 000000000..63a7fd18d --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdec.c @@ -0,0 +1,3297 @@ +/* + * AAC decoder + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * AAC LATM decoder + * Copyright (c) 2008-2010 Paul Kendall + * Copyright (c) 2010 Janne Grunau + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC decoder + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + */ + +/* + * supported tools + * + * Support? Name + * N (code in SoC repo) gain control + * Y block switching + * Y window shapes - standard + * N window shapes - Low Delay + * Y filterbank - standard + * N (code in SoC repo) filterbank - Scalable Sample Rate + * Y Temporal Noise Shaping + * Y Long Term Prediction + * Y intensity stereo + * Y channel coupling + * Y frequency domain prediction + * Y Perceptual Noise Substitution + * Y Mid/Side stereo + * N Scalable Inverse AAC Quantization + * N Frequency Selective Switch + * N upsampling filter + * Y quantization & coding - AAC + * N quantization & coding - TwinVQ + * N quantization & coding - BSAC + * N AAC Error Resilience tools + * N Error Resilience payload syntax + * N Error Protection tool + * N CELP + * N Silence Compression + * N HVXC + * N HVXC 4kbits/s VR + * N Structured Audio tools + * N Structured Audio Sample Bank Format + * N MIDI + * N Harmonic and Individual Lines plus Noise + * N Text-To-Speech Interface + * Y Spectral Band Replication + * Y (not in this code) Layer-1 + * Y (not in this code) Layer-2 + * Y (not in this code) Layer-3 + * N SinuSoidal Coding (Transient, Sinusoid, Noise) + * Y Parametric Stereo + * N Direct Stream Transfer + * + * Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication. + * - HE AAC v2 comprises LC AAC with Spectral Band Replication and + Parametric Stereo. + */ + +#include "libavutil/float_dsp.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "internal.h" +#include "get_bits.h" +#include "fft.h" +#include "fmtconvert.h" +#include "lpc.h" +#include "kbdwin.h" +#include "sinewin.h" + +#include "aac.h" +#include "aactab.h" +#include "aacdectab.h" +#include "cbrt_tablegen.h" +#include "sbr.h" +#include "aacsbr.h" +#include "mpeg4audio.h" +#include "aacadtsdec.h" +#include "libavutil/intfloat.h" + +#include +#include +#include +#include + +#if ARCH_ARM +# include "arm/aac.h" +#elif ARCH_MIPS +# include "mips/aacdec_mips.h" +#endif + +static VLC vlc_scalefactors; +static VLC vlc_spectral[11]; + +static int output_configure(AACContext *ac, + uint8_t layout_map[MAX_ELEM_ID*4][3], int tags, + enum OCStatus oc_type, int get_new_frame); + +#define overread_err "Input buffer exhausted before END element found\n" + +static int count_channels(uint8_t (*layout)[3], int tags) +{ + int i, sum = 0; + for (i = 0; i < tags; i++) { + int syn_ele = layout[i][0]; + int pos = layout[i][2]; + sum += (1 + (syn_ele == TYPE_CPE)) * + (pos != AAC_CHANNEL_OFF && pos != AAC_CHANNEL_CC); + } + return sum; +} + +/** + * Check for the channel element in the current channel position configuration. + * If it exists, make sure the appropriate element is allocated and map the + * channel order to match the internal FFmpeg channel layout. + * + * @param che_pos current channel position configuration + * @param type channel element type + * @param id channel element id + * @param channels count of the number of channels in the configuration + * + * @return Returns error status. 0 - OK, !0 - error + */ +static av_cold int che_configure(AACContext *ac, + enum ChannelPosition che_pos, + int type, int id, int *channels) +{ + if (*channels >= MAX_CHANNELS) + return AVERROR_INVALIDDATA; + if (che_pos) { + if (!ac->che[type][id]) { + if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) + return AVERROR(ENOMEM); + ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr); + } + if (type != TYPE_CCE) { + if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) { + av_log(ac->avctx, AV_LOG_ERROR, "Too many channels\n"); + return AVERROR_INVALIDDATA; + } + ac->output_element[(*channels)++] = &ac->che[type][id]->ch[0]; + if (type == TYPE_CPE || + (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1)) { + ac->output_element[(*channels)++] = &ac->che[type][id]->ch[1]; + } + } + } else { + if (ac->che[type][id]) + ff_aac_sbr_ctx_close(&ac->che[type][id]->sbr); + av_freep(&ac->che[type][id]); + } + return 0; +} + +static int frame_configure_elements(AVCodecContext *avctx) +{ + AACContext *ac = avctx->priv_data; + int type, id, ch, ret; + + /* set channel pointers to internal buffers by default */ + for (type = 0; type < 4; type++) { + for (id = 0; id < MAX_ELEM_ID; id++) { + ChannelElement *che = ac->che[type][id]; + if (che) { + che->ch[0].ret = che->ch[0].ret_buf; + che->ch[1].ret = che->ch[1].ret_buf; + } + } + } + + /* get output buffer */ + av_frame_unref(ac->frame); + ac->frame->nb_samples = 2048; + if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) + return ret; + + /* map output channel pointers to AVFrame data */ + for (ch = 0; ch < avctx->channels; ch++) { + if (ac->output_element[ch]) + ac->output_element[ch]->ret = (float *)ac->frame->extended_data[ch]; + } + + return 0; +} + +struct elem_to_channel { + uint64_t av_position; + uint8_t syn_ele; + uint8_t elem_id; + uint8_t aac_position; +}; + +static int assign_pair(struct elem_to_channel e2c_vec[MAX_ELEM_ID], + uint8_t (*layout_map)[3], int offset, uint64_t left, + uint64_t right, int pos) +{ + if (layout_map[offset][0] == TYPE_CPE) { + e2c_vec[offset] = (struct elem_to_channel) { + .av_position = left | right, + .syn_ele = TYPE_CPE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; + return 1; + } else { + e2c_vec[offset] = (struct elem_to_channel) { + .av_position = left, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset][1], + .aac_position = pos + }; + e2c_vec[offset + 1] = (struct elem_to_channel) { + .av_position = right, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[offset + 1][1], + .aac_position = pos + }; + return 2; + } +} + +static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, + int *current) +{ + int num_pos_channels = 0; + int first_cpe = 0; + int sce_parity = 0; + int i; + for (i = *current; i < tags; i++) { + if (layout_map[i][2] != pos) + break; + if (layout_map[i][0] == TYPE_CPE) { + if (sce_parity) { + if (pos == AAC_CHANNEL_FRONT && !first_cpe) { + sce_parity = 0; + } else { + return -1; + } + } + num_pos_channels += 2; + first_cpe = 1; + } else { + num_pos_channels++; + sce_parity ^= 1; + } + } + if (sce_parity && + ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE)) + return -1; + *current = i; + return num_pos_channels; +} + +static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) +{ + int i, n, total_non_cc_elements; + struct elem_to_channel e2c_vec[4 * MAX_ELEM_ID] = { { 0 } }; + int num_front_channels, num_side_channels, num_back_channels; + uint64_t layout; + + if (FF_ARRAY_ELEMS(e2c_vec) < tags) + return 0; + + i = 0; + num_front_channels = + count_paired_channels(layout_map, tags, AAC_CHANNEL_FRONT, &i); + if (num_front_channels < 0) + return 0; + num_side_channels = + count_paired_channels(layout_map, tags, AAC_CHANNEL_SIDE, &i); + if (num_side_channels < 0) + return 0; + num_back_channels = + count_paired_channels(layout_map, tags, AAC_CHANNEL_BACK, &i); + if (num_back_channels < 0) + return 0; + + i = 0; + if (num_front_channels & 1) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_FRONT_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_FRONT + }; + i++; + num_front_channels--; + } + if (num_front_channels >= 4) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_FRONT_LEFT_OF_CENTER, + AV_CH_FRONT_RIGHT_OF_CENTER, + AAC_CHANNEL_FRONT); + num_front_channels -= 2; + } + if (num_front_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_FRONT_LEFT, + AV_CH_FRONT_RIGHT, + AAC_CHANNEL_FRONT); + num_front_channels -= 2; + } + while (num_front_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + UINT64_MAX, + UINT64_MAX, + AAC_CHANNEL_FRONT); + num_front_channels -= 2; + } + + if (num_side_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_SIDE_LEFT, + AV_CH_SIDE_RIGHT, + AAC_CHANNEL_FRONT); + num_side_channels -= 2; + } + while (num_side_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + UINT64_MAX, + UINT64_MAX, + AAC_CHANNEL_SIDE); + num_side_channels -= 2; + } + + while (num_back_channels >= 4) { + i += assign_pair(e2c_vec, layout_map, i, + UINT64_MAX, + UINT64_MAX, + AAC_CHANNEL_BACK); + num_back_channels -= 2; + } + if (num_back_channels >= 2) { + i += assign_pair(e2c_vec, layout_map, i, + AV_CH_BACK_LEFT, + AV_CH_BACK_RIGHT, + AAC_CHANNEL_BACK); + num_back_channels -= 2; + } + if (num_back_channels) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_BACK_CENTER, + .syn_ele = TYPE_SCE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_BACK + }; + i++; + num_back_channels--; + } + + if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = AV_CH_LOW_FREQUENCY, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; + i++; + } + while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) { + e2c_vec[i] = (struct elem_to_channel) { + .av_position = UINT64_MAX, + .syn_ele = TYPE_LFE, + .elem_id = layout_map[i][1], + .aac_position = AAC_CHANNEL_LFE + }; + i++; + } + + // Must choose a stable sort + total_non_cc_elements = n = i; + do { + int next_n = 0; + for (i = 1; i < n; i++) + if (e2c_vec[i - 1].av_position > e2c_vec[i].av_position) { + FFSWAP(struct elem_to_channel, e2c_vec[i - 1], e2c_vec[i]); + next_n = i; + } + n = next_n; + } while (n > 0); + + layout = 0; + for (i = 0; i < total_non_cc_elements; i++) { + layout_map[i][0] = e2c_vec[i].syn_ele; + layout_map[i][1] = e2c_vec[i].elem_id; + layout_map[i][2] = e2c_vec[i].aac_position; + if (e2c_vec[i].av_position != UINT64_MAX) { + layout |= e2c_vec[i].av_position; + } + } + + return layout; +} + +/** + * Save current output configuration if and only if it has been locked. + */ +static void push_output_configuration(AACContext *ac) { + if (ac->oc[1].status == OC_LOCKED) { + ac->oc[0] = ac->oc[1]; + } + ac->oc[1].status = OC_NONE; +} + +/** + * Restore the previous output configuration if and only if the current + * configuration is unlocked. + */ +static void pop_output_configuration(AACContext *ac) { + if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) { + ac->oc[1] = ac->oc[0]; + ac->avctx->channels = ac->oc[1].channels; + ac->avctx->channel_layout = ac->oc[1].channel_layout; + output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags, + ac->oc[1].status, 0); + } +} + +/** + * Configure output channel order based on the current program + * configuration element. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int output_configure(AACContext *ac, + uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags, + enum OCStatus oc_type, int get_new_frame) +{ + AVCodecContext *avctx = ac->avctx; + int i, channels = 0, ret; + uint64_t layout = 0; + + if (ac->oc[1].layout_map != layout_map) { + memcpy(ac->oc[1].layout_map, layout_map, tags * sizeof(layout_map[0])); + ac->oc[1].layout_map_tags = tags; + } + + // Try to sniff a reasonable channel order, otherwise output the + // channels in the order the PCE declared them. + if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) + layout = sniff_channel_order(layout_map, tags); + for (i = 0; i < tags; i++) { + int type = layout_map[i][0]; + int id = layout_map[i][1]; + int position = layout_map[i][2]; + // Allocate or free elements depending on if they are in the + // current program configuration. + ret = che_configure(ac, position, type, id, &channels); + if (ret < 0) + return ret; + } + if (ac->oc[1].m4ac.ps == 1 && channels == 2) { + if (layout == AV_CH_FRONT_CENTER) { + layout = AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT; + } else { + layout = 0; + } + } + + memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); + if (layout) avctx->channel_layout = layout; + ac->oc[1].channel_layout = layout; + avctx->channels = ac->oc[1].channels = channels; + ac->oc[1].status = oc_type; + + if (get_new_frame) { + if ((ret = frame_configure_elements(ac->avctx)) < 0) + return ret; + } + + return 0; +} + +static void flush(AVCodecContext *avctx) +{ + AACContext *ac= avctx->priv_data; + int type, i, j; + + for (type = 3; type >= 0; type--) { + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *che = ac->che[type][i]; + if (che) { + for (j = 0; j <= 1; j++) { + memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved)); + } + } + } + } +} + +/** + * Set up channel positions based on a default channel configuration + * as specified in table 1.17. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int set_default_channel_config(AVCodecContext *avctx, + uint8_t (*layout_map)[3], + int *tags, + int channel_config) +{ + if (channel_config < 1 || channel_config > 7) { + av_log(avctx, AV_LOG_ERROR, + "invalid default channel configuration (%d)\n", + channel_config); + return AVERROR_INVALIDDATA; + } + *tags = tags_per_config[channel_config]; + memcpy(layout_map, aac_channel_layout_map[channel_config - 1], + *tags * sizeof(*layout_map)); + return 0; +} + +static ChannelElement *get_che(AACContext *ac, int type, int elem_id) +{ + /* For PCE based channel configurations map the channels solely based + * on tags. */ + if (!ac->oc[1].m4ac.chan_config) { + return ac->tag_che_map[type][elem_id]; + } + // Allow single CPE stereo files to be signalled with mono configuration. + if (!ac->tags_mapped && type == TYPE_CPE && + ac->oc[1].m4ac.chan_config == 1) { + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int layout_map_tags; + push_output_configuration(ac); + + av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n"); + + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 2) < 0) + return NULL; + if (output_configure(ac, layout_map, layout_map_tags, + OC_TRIAL_FRAME, 1) < 0) + return NULL; + + ac->oc[1].m4ac.chan_config = 2; + ac->oc[1].m4ac.ps = 0; + } + // And vice-versa + if (!ac->tags_mapped && type == TYPE_SCE && + ac->oc[1].m4ac.chan_config == 2) { + uint8_t layout_map[MAX_ELEM_ID * 4][3]; + int layout_map_tags; + push_output_configuration(ac); + + av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n"); + + if (set_default_channel_config(ac->avctx, layout_map, + &layout_map_tags, 1) < 0) + return NULL; + if (output_configure(ac, layout_map, layout_map_tags, + OC_TRIAL_FRAME, 1) < 0) + return NULL; + + ac->oc[1].m4ac.chan_config = 1; + if (ac->oc[1].m4ac.sbr) + ac->oc[1].m4ac.ps = -1; + } + /* For indexed channel configurations map the channels solely based + * on position. */ + switch (ac->oc[1].m4ac.chan_config) { + case 7: + if (ac->tags_mapped == 3 && type == TYPE_CPE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2]; + } + case 6: + /* Some streams incorrectly code 5.1 audio as + * SCE[0] CPE[0] CPE[1] SCE[1] + * instead of + * SCE[0] CPE[0] CPE[1] LFE[0]. + * If we seem to have encountered such a stream, transfer + * the LFE[0] element to the SCE[1]'s mapping */ + if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) { + ac->tags_mapped++; + return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0]; + } + case 5: + if (ac->tags_mapped == 2 && type == TYPE_CPE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1]; + } + case 4: + if (ac->tags_mapped == 2 && + ac->oc[1].m4ac.chan_config == 4 && + type == TYPE_SCE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1]; + } + case 3: + case 2: + if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && + type == TYPE_CPE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0]; + } else if (ac->oc[1].m4ac.chan_config == 2) { + return NULL; + } + case 1: + if (!ac->tags_mapped && type == TYPE_SCE) { + ac->tags_mapped++; + return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][0]; + } + default: + return NULL; + } +} + +/** + * Decode an array of 4 bit element IDs, optionally interleaved with a + * stereo/mono switching bit. + * + * @param type speaker type/position for these channels + */ +static void decode_channel_map(uint8_t layout_map[][3], + enum ChannelPosition type, + GetBitContext *gb, int n) +{ + while (n--) { + enum RawDataBlockType syn_ele; + switch (type) { + case AAC_CHANNEL_FRONT: + case AAC_CHANNEL_BACK: + case AAC_CHANNEL_SIDE: + syn_ele = get_bits1(gb); + break; + case AAC_CHANNEL_CC: + skip_bits1(gb); + syn_ele = TYPE_CCE; + break; + case AAC_CHANNEL_LFE: + syn_ele = TYPE_LFE; + break; + default: + av_assert0(0); + } + layout_map[0][0] = syn_ele; + layout_map[0][1] = get_bits(gb, 4); + layout_map[0][2] = type; + layout_map++; + } +} + +/** + * Decode program configuration element; reference: table 4.2. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, + uint8_t (*layout_map)[3], + GetBitContext *gb) +{ + int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc; + int sampling_index; + int comment_len; + int tags; + + skip_bits(gb, 2); // object_type + + sampling_index = get_bits(gb, 4); + if (m4ac->sampling_index != sampling_index) + av_log(avctx, AV_LOG_WARNING, + "Sample rate index in program config element does not " + "match the sample rate index configured by the container.\n"); + + num_front = get_bits(gb, 4); + num_side = get_bits(gb, 4); + num_back = get_bits(gb, 4); + num_lfe = get_bits(gb, 2); + num_assoc_data = get_bits(gb, 3); + num_cc = get_bits(gb, 4); + + if (get_bits1(gb)) + skip_bits(gb, 4); // mono_mixdown_tag + if (get_bits1(gb)) + skip_bits(gb, 4); // stereo_mixdown_tag + + if (get_bits1(gb)) + skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround + + if (get_bits_left(gb) < 4 * (num_front + num_side + num_back + num_lfe + num_assoc_data + num_cc)) { + av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); + return -1; + } + decode_channel_map(layout_map , AAC_CHANNEL_FRONT, gb, num_front); + tags = num_front; + decode_channel_map(layout_map + tags, AAC_CHANNEL_SIDE, gb, num_side); + tags += num_side; + decode_channel_map(layout_map + tags, AAC_CHANNEL_BACK, gb, num_back); + tags += num_back; + decode_channel_map(layout_map + tags, AAC_CHANNEL_LFE, gb, num_lfe); + tags += num_lfe; + + skip_bits_long(gb, 4 * num_assoc_data); + + decode_channel_map(layout_map + tags, AAC_CHANNEL_CC, gb, num_cc); + tags += num_cc; + + align_get_bits(gb); + + /* comment field, first byte is length */ + comment_len = get_bits(gb, 8) * 8; + if (get_bits_left(gb) < comment_len) { + av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, comment_len); + return tags; +} + +/** + * Decode GA "General Audio" specific configuration; reference: table 4.1. + * + * @param ac pointer to AACContext, may be null + * @param avctx pointer to AVCCodecContext, used for logging + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, + GetBitContext *gb, + MPEG4AudioConfig *m4ac, + int channel_config) +{ + int extension_flag, ret, ep_config, res_flags; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int tags = 0; + + if (get_bits1(gb)) { // frameLengthFlag + avpriv_request_sample(avctx, "960/120 MDCT window"); + return AVERROR_PATCHWELCOME; + } + + if (get_bits1(gb)) // dependsOnCoreCoder + skip_bits(gb, 14); // coreCoderDelay + extension_flag = get_bits1(gb); + + if (m4ac->object_type == AOT_AAC_SCALABLE || + m4ac->object_type == AOT_ER_AAC_SCALABLE) + skip_bits(gb, 3); // layerNr + + if (channel_config == 0) { + skip_bits(gb, 4); // element_instance_tag + tags = decode_pce(avctx, m4ac, layout_map, gb); + if (tags < 0) + return tags; + } else { + if ((ret = set_default_channel_config(avctx, layout_map, + &tags, channel_config))) + return ret; + } + + if (count_channels(layout_map, tags) > 1) { + m4ac->ps = 0; + } else if (m4ac->sbr == 1 && m4ac->ps == -1) + m4ac->ps = 1; + + if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0))) + return ret; + + if (extension_flag) { + switch (m4ac->object_type) { + case AOT_ER_BSAC: + skip_bits(gb, 5); // numOfSubFrame + skip_bits(gb, 11); // layer_length + break; + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_SCALABLE: + case AOT_ER_AAC_LD: + res_flags = get_bits(gb, 3); + if (res_flags) { + av_log(avctx, AV_LOG_ERROR, + "AAC data resilience not supported (flags %x)\n", + res_flags); + return AVERROR_PATCHWELCOME; + } + break; + } + skip_bits1(gb); // extensionFlag3 (TBD in version 3) + } + switch (m4ac->object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_SCALABLE: + case AOT_ER_AAC_LD: + ep_config = get_bits(gb, 2); + if (ep_config) { + av_log(avctx, AV_LOG_ERROR, + "epConfig %d is not supported.\n", + ep_config); + return AVERROR_PATCHWELCOME; + } + } + return 0; +} + +/** + * Decode audio specific configuration; reference: table 1.13. + * + * @param ac pointer to AACContext, may be null + * @param avctx pointer to AVCCodecContext, used for logging + * @param m4ac pointer to MPEG4AudioConfig, used for parsing + * @param data pointer to buffer holding an audio specific config + * @param bit_size size of audio specific config or data in bits + * @param sync_extension look for an appended sync extension + * + * @return Returns error status or number of consumed bits. <0 - error + */ +static int decode_audio_specific_config(AACContext *ac, + AVCodecContext *avctx, + MPEG4AudioConfig *m4ac, + const uint8_t *data, int bit_size, + int sync_extension) +{ + GetBitContext gb; + int i, ret; + + av_dlog(avctx, "audio specific config size %d\n", bit_size >> 3); + for (i = 0; i < bit_size >> 3; i++) + av_dlog(avctx, "%02x ", data[i]); + av_dlog(avctx, "\n"); + + if ((ret = init_get_bits(&gb, data, bit_size)) < 0) + return ret; + + if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, + sync_extension)) < 0) + return AVERROR_INVALIDDATA; + if (m4ac->sampling_index > 12) { + av_log(avctx, AV_LOG_ERROR, + "invalid sampling rate index %d\n", + m4ac->sampling_index); + return AVERROR_INVALIDDATA; + } + if (m4ac->object_type == AOT_ER_AAC_LD && + (m4ac->sampling_index < 3 || m4ac->sampling_index > 7)) { + av_log(avctx, AV_LOG_ERROR, + "invalid low delay sampling rate index %d\n", + m4ac->sampling_index); + return AVERROR_INVALIDDATA; + } + + skip_bits_long(&gb, i); + + switch (m4ac->object_type) { + case AOT_AAC_MAIN: + case AOT_AAC_LC: + case AOT_AAC_LTP: + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LD: + if ((ret = decode_ga_specific_config(ac, avctx, &gb, + m4ac, m4ac->chan_config)) < 0) + return ret; + break; + default: + av_log(avctx, AV_LOG_ERROR, + "Audio object type %s%d is not supported.\n", + m4ac->sbr == 1 ? "SBR+" : "", + m4ac->object_type); + return AVERROR(ENOSYS); + } + + av_dlog(avctx, + "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n", + m4ac->object_type, m4ac->chan_config, m4ac->sampling_index, + m4ac->sample_rate, m4ac->sbr, + m4ac->ps); + + return get_bits_count(&gb); +} + +/** + * linear congruential pseudorandom number generator + * + * @param previous_val pointer to the current state of the generator + * + * @return Returns a 32-bit pseudorandom integer + */ +static av_always_inline int lcg_random(unsigned previous_val) +{ + union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 }; + return v.s; +} + +static av_always_inline void reset_predict_state(PredictorState *ps) +{ + ps->r0 = 0.0f; + ps->r1 = 0.0f; + ps->cor0 = 0.0f; + ps->cor1 = 0.0f; + ps->var0 = 1.0f; + ps->var1 = 1.0f; +} + +static void reset_all_predictors(PredictorState *ps) +{ + int i; + for (i = 0; i < MAX_PREDICTORS; i++) + reset_predict_state(&ps[i]); +} + +static int sample_rate_idx (int rate) +{ + if (92017 <= rate) return 0; + else if (75132 <= rate) return 1; + else if (55426 <= rate) return 2; + else if (46009 <= rate) return 3; + else if (37566 <= rate) return 4; + else if (27713 <= rate) return 5; + else if (23004 <= rate) return 6; + else if (18783 <= rate) return 7; + else if (13856 <= rate) return 8; + else if (11502 <= rate) return 9; + else if (9391 <= rate) return 10; + else return 11; +} + +static void reset_predictor_group(PredictorState *ps, int group_num) +{ + int i; + for (i = group_num - 1; i < MAX_PREDICTORS; i += 30) + reset_predict_state(&ps[i]); +} + +#define AAC_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_spectral[num], 8, ff_aac_spectral_sizes[num], \ + ff_aac_spectral_bits[num], sizeof(ff_aac_spectral_bits[num][0]), \ + sizeof(ff_aac_spectral_bits[num][0]), \ + ff_aac_spectral_codes[num], sizeof(ff_aac_spectral_codes[num][0]), \ + sizeof(ff_aac_spectral_codes[num][0]), \ + size); + +static void aacdec_init(AACContext *ac); + +static av_cold int aac_decode_init(AVCodecContext *avctx) +{ + AACContext *ac = avctx->priv_data; + int ret; + + ac->avctx = avctx; + ac->oc[1].m4ac.sample_rate = avctx->sample_rate; + + aacdec_init(ac); + + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + + if (avctx->extradata_size > 0) { + if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, + avctx->extradata, + avctx->extradata_size * 8, + 1)) < 0) + return ret; + } else { + int sr, i; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int layout_map_tags; + + sr = sample_rate_idx(avctx->sample_rate); + ac->oc[1].m4ac.sampling_index = sr; + ac->oc[1].m4ac.channels = avctx->channels; + ac->oc[1].m4ac.sbr = -1; + ac->oc[1].m4ac.ps = -1; + + for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++) + if (ff_mpeg4audio_channels[i] == avctx->channels) + break; + if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) { + i = 0; + } + ac->oc[1].m4ac.chan_config = i; + + if (ac->oc[1].m4ac.chan_config) { + int ret = set_default_channel_config(avctx, layout_map, + &layout_map_tags, ac->oc[1].m4ac.chan_config); + if (!ret) + output_configure(ac, layout_map, layout_map_tags, + OC_GLOBAL_HDR, 0); + else if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + } + } + + if (avctx->channels > MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "Too many channels\n"); + return AVERROR_INVALIDDATA; + } + + AAC_INIT_VLC_STATIC( 0, 304); + AAC_INIT_VLC_STATIC( 1, 270); + AAC_INIT_VLC_STATIC( 2, 550); + AAC_INIT_VLC_STATIC( 3, 300); + AAC_INIT_VLC_STATIC( 4, 328); + AAC_INIT_VLC_STATIC( 5, 294); + AAC_INIT_VLC_STATIC( 6, 306); + AAC_INIT_VLC_STATIC( 7, 268); + AAC_INIT_VLC_STATIC( 8, 510); + AAC_INIT_VLC_STATIC( 9, 366); + AAC_INIT_VLC_STATIC(10, 462); + + ff_aac_sbr_init(); + + ff_fmt_convert_init(&ac->fmt_conv, avctx); + avpriv_float_dsp_init(&ac->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); + + ac->random_state = 0x1f2e3d4c; + + ff_aac_tableinit(); + + INIT_VLC_STATIC(&vlc_scalefactors, 7, + FF_ARRAY_ELEMS(ff_aac_scalefactor_code), + ff_aac_scalefactor_bits, + sizeof(ff_aac_scalefactor_bits[0]), + sizeof(ff_aac_scalefactor_bits[0]), + ff_aac_scalefactor_code, + sizeof(ff_aac_scalefactor_code[0]), + sizeof(ff_aac_scalefactor_code[0]), + 352); + + ff_mdct_init(&ac->mdct, 11, 1, 1.0 / (32768.0 * 1024.0)); + ff_mdct_init(&ac->mdct_ld, 10, 1, 1.0 / (32768.0 * 512.0)); + ff_mdct_init(&ac->mdct_small, 8, 1, 1.0 / (32768.0 * 128.0)); + ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0 * 32768.0); + // window initialization + ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); + ff_kbd_window_init(ff_aac_kbd_long_512, 4.0, 512); + ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); + ff_init_ff_sine_windows(10); + ff_init_ff_sine_windows( 9); + ff_init_ff_sine_windows( 7); + + cbrt_tableinit(); + + return 0; +} + +/** + * Skip data_stream_element; reference: table 4.10. + */ +static int skip_data_stream_element(AACContext *ac, GetBitContext *gb) +{ + int byte_align = get_bits1(gb); + int count = get_bits(gb, 8); + if (count == 255) + count += get_bits(gb, 8); + if (byte_align) + align_get_bits(gb); + + if (get_bits_left(gb) < 8 * count) { + av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, 8 * count); + return 0; +} + +static int decode_prediction(AACContext *ac, IndividualChannelStream *ics, + GetBitContext *gb) +{ + int sfb; + if (get_bits1(gb)) { + ics->predictor_reset_group = get_bits(gb, 5); + if (ics->predictor_reset_group == 0 || + ics->predictor_reset_group > 30) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid Predictor Reset Group.\n"); + return AVERROR_INVALIDDATA; + } + } + for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]); sfb++) { + ics->prediction_used[sfb] = get_bits1(gb); + } + return 0; +} + +/** + * Decode Long Term Prediction data; reference: table 4.xx. + */ +static void decode_ltp(LongTermPrediction *ltp, + GetBitContext *gb, uint8_t max_sfb) +{ + int sfb; + + ltp->lag = get_bits(gb, 11); + ltp->coef = ltp_coef[get_bits(gb, 3)]; + for (sfb = 0; sfb < FFMIN(max_sfb, MAX_LTP_LONG_SFB); sfb++) + ltp->used[sfb] = get_bits1(gb); +} + +/** + * Decode Individual Channel Stream info; reference: table 4.6. + */ +static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, + GetBitContext *gb) +{ + if (get_bits1(gb)) { + av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n"); + return AVERROR_INVALIDDATA; + } + ics->window_sequence[1] = ics->window_sequence[0]; + ics->window_sequence[0] = get_bits(gb, 2); + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD && + ics->window_sequence[0] != ONLY_LONG_SEQUENCE) { + av_log(ac->avctx, AV_LOG_ERROR, + "AAC LD is only defined for ONLY_LONG_SEQUENCE but " + "window sequence %d found.\n", ics->window_sequence[0]); + ics->window_sequence[0] = ONLY_LONG_SEQUENCE; + return AVERROR_INVALIDDATA; + } + ics->use_kb_window[1] = ics->use_kb_window[0]; + ics->use_kb_window[0] = get_bits1(gb); + ics->num_window_groups = 1; + ics->group_len[0] = 1; + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + int i; + ics->max_sfb = get_bits(gb, 4); + for (i = 0; i < 7; i++) { + if (get_bits1(gb)) { + ics->group_len[ics->num_window_groups - 1]++; + } else { + ics->num_window_groups++; + ics->group_len[ics->num_window_groups - 1] = 1; + } + } + ics->num_windows = 8; + ics->swb_offset = ff_swb_offset_128[ac->oc[1].m4ac.sampling_index]; + ics->num_swb = ff_aac_num_swb_128[ac->oc[1].m4ac.sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_128[ac->oc[1].m4ac.sampling_index]; + ics->predictor_present = 0; + } else { + ics->max_sfb = get_bits(gb, 6); + ics->num_windows = 1; + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) { + ics->swb_offset = ff_swb_offset_512[ac->oc[1].m4ac.sampling_index]; + ics->num_swb = ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index]; + if (!ics->num_swb || !ics->swb_offset) + return AVERROR_BUG; + } else { + ics->swb_offset = ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index]; + ics->num_swb = ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index]; + } + ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index]; + ics->predictor_present = get_bits1(gb); + ics->predictor_reset_group = 0; + if (ics->predictor_present) { + if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) { + if (decode_prediction(ac, ics, gb)) { + goto fail; + } + } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC) { + av_log(ac->avctx, AV_LOG_ERROR, + "Prediction is not allowed in AAC-LC.\n"); + goto fail; + } else { + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) { + av_log(ac->avctx, AV_LOG_ERROR, + "LTP in ER AAC LD not yet implemented.\n"); + return AVERROR_PATCHWELCOME; + } + if ((ics->ltp.present = get_bits(gb, 1))) + decode_ltp(&ics->ltp, gb, ics->max_sfb); + } + } + } + + if (ics->max_sfb > ics->num_swb) { + av_log(ac->avctx, AV_LOG_ERROR, + "Number of scalefactor bands in group (%d) " + "exceeds limit (%d).\n", + ics->max_sfb, ics->num_swb); + goto fail; + } + + return 0; +fail: + ics->max_sfb = 0; + return AVERROR_INVALIDDATA; +} + +/** + * Decode band types (section_data payload); reference: table 4.46. + * + * @param band_type array of the used band type + * @param band_type_run_end array of the last scalefactor band of a band type run + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_band_types(AACContext *ac, enum BandType band_type[120], + int band_type_run_end[120], GetBitContext *gb, + IndividualChannelStream *ics) +{ + int g, idx = 0; + const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5; + for (g = 0; g < ics->num_window_groups; g++) { + int k = 0; + while (k < ics->max_sfb) { + uint8_t sect_end = k; + int sect_len_incr; + int sect_band_type = get_bits(gb, 4); + if (sect_band_type == 12) { + av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n"); + return AVERROR_INVALIDDATA; + } + do { + sect_len_incr = get_bits(gb, bits); + sect_end += sect_len_incr; + if (get_bits_left(gb) < 0) { + av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err); + return AVERROR_INVALIDDATA; + } + if (sect_end > ics->max_sfb) { + av_log(ac->avctx, AV_LOG_ERROR, + "Number of bands (%d) exceeds limit (%d).\n", + sect_end, ics->max_sfb); + return AVERROR_INVALIDDATA; + } + } while (sect_len_incr == (1 << bits) - 1); + for (; k < sect_end; k++) { + band_type [idx] = sect_band_type; + band_type_run_end[idx++] = sect_end; + } + } + } + return 0; +} + +/** + * Decode scalefactors; reference: table 4.47. + * + * @param global_gain first scalefactor value as scalefactors are differentially coded + * @param band_type array of the used band type + * @param band_type_run_end array of the last scalefactor band of a band type run + * @param sf array of scalefactors or intensity stereo positions + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, + unsigned int global_gain, + IndividualChannelStream *ics, + enum BandType band_type[120], + int band_type_run_end[120]) +{ + int g, i, idx = 0; + int offset[3] = { global_gain, global_gain - 90, 0 }; + int clipped_offset; + int noise_flag = 1; + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb;) { + int run_end = band_type_run_end[idx]; + if (band_type[idx] == ZERO_BT) { + for (; i < run_end; i++, idx++) + sf[idx] = 0.0; + } else if ((band_type[idx] == INTENSITY_BT) || + (band_type[idx] == INTENSITY_BT2)) { + for (; i < run_end; i++, idx++) { + offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; + clipped_offset = av_clip(offset[2], -155, 100); + if (offset[2] != clipped_offset) { + avpriv_request_sample(ac->avctx, + "If you heard an audible artifact, there may be a bug in the decoder. " + "Clipped intensity stereo position (%d -> %d)", + offset[2], clipped_offset); + } + sf[idx] = ff_aac_pow2sf_tab[-clipped_offset + POW_SF2_ZERO]; + } + } else if (band_type[idx] == NOISE_BT) { + for (; i < run_end; i++, idx++) { + if (noise_flag-- > 0) + offset[1] += get_bits(gb, 9) - 256; + else + offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; + clipped_offset = av_clip(offset[1], -100, 155); + if (offset[1] != clipped_offset) { + avpriv_request_sample(ac->avctx, + "If you heard an audible artifact, there may be a bug in the decoder. " + "Clipped noise gain (%d -> %d)", + offset[1], clipped_offset); + } + sf[idx] = -ff_aac_pow2sf_tab[clipped_offset + POW_SF2_ZERO]; + } + } else { + for (; i < run_end; i++, idx++) { + offset[0] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; + if (offset[0] > 255U) { + av_log(ac->avctx, AV_LOG_ERROR, + "Scalefactor (%d) out of range.\n", offset[0]); + return AVERROR_INVALIDDATA; + } + sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO]; + } + } + } + } + return 0; +} + +/** + * Decode pulse data; reference: table 4.7. + */ +static int decode_pulses(Pulse *pulse, GetBitContext *gb, + const uint16_t *swb_offset, int num_swb) +{ + int i, pulse_swb; + pulse->num_pulse = get_bits(gb, 2) + 1; + pulse_swb = get_bits(gb, 6); + if (pulse_swb >= num_swb) + return -1; + pulse->pos[0] = swb_offset[pulse_swb]; + pulse->pos[0] += get_bits(gb, 5); + if (pulse->pos[0] > 1023) + return -1; + pulse->amp[0] = get_bits(gb, 4); + for (i = 1; i < pulse->num_pulse; i++) { + pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1]; + if (pulse->pos[i] > 1023) + return -1; + pulse->amp[i] = get_bits(gb, 4); + } + return 0; +} + +/** + * Decode Temporal Noise Shaping data; reference: table 4.48. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns, + GetBitContext *gb, const IndividualChannelStream *ics) +{ + int w, filt, i, coef_len, coef_res, coef_compress; + const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE; + const int tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12; + for (w = 0; w < ics->num_windows; w++) { + if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) { + coef_res = get_bits1(gb); + + for (filt = 0; filt < tns->n_filt[w]; filt++) { + int tmp2_idx; + tns->length[w][filt] = get_bits(gb, 6 - 2 * is8); + + if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) { + av_log(ac->avctx, AV_LOG_ERROR, + "TNS filter order %d is greater than maximum %d.\n", + tns->order[w][filt], tns_max_order); + tns->order[w][filt] = 0; + return AVERROR_INVALIDDATA; + } + if (tns->order[w][filt]) { + tns->direction[w][filt] = get_bits1(gb); + coef_compress = get_bits1(gb); + coef_len = coef_res + 3 - coef_compress; + tmp2_idx = 2 * coef_compress + coef_res; + + for (i = 0; i < tns->order[w][filt]; i++) + tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)]; + } + } + } + } + return 0; +} + +/** + * Decode Mid/Side data; reference: table 4.54. + * + * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s; + * [1] mask is decoded from bitstream; [2] mask is all 1s; + * [3] reserved for scalable AAC + */ +static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb, + int ms_present) +{ + int idx; + if (ms_present == 1) { + for (idx = 0; + idx < cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb; + idx++) + cpe->ms_mask[idx] = get_bits1(gb); + } else if (ms_present == 2) { + memset(cpe->ms_mask, 1, sizeof(cpe->ms_mask[0]) * cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb); + } +} + +#ifndef VMUL2 +static inline float *VMUL2(float *dst, const float *v, unsigned idx, + const float *scale) +{ + float s = *scale; + *dst++ = v[idx & 15] * s; + *dst++ = v[idx>>4 & 15] * s; + return dst; +} +#endif + +#ifndef VMUL4 +static inline float *VMUL4(float *dst, const float *v, unsigned idx, + const float *scale) +{ + float s = *scale; + *dst++ = v[idx & 3] * s; + *dst++ = v[idx>>2 & 3] * s; + *dst++ = v[idx>>4 & 3] * s; + *dst++ = v[idx>>6 & 3] * s; + return dst; +} +#endif + +#ifndef VMUL2S +static inline float *VMUL2S(float *dst, const float *v, unsigned idx, + unsigned sign, const float *scale) +{ + union av_intfloat32 s0, s1; + + s0.f = s1.f = *scale; + s0.i ^= sign >> 1 << 31; + s1.i ^= sign << 31; + + *dst++ = v[idx & 15] * s0.f; + *dst++ = v[idx>>4 & 15] * s1.f; + + return dst; +} +#endif + +#ifndef VMUL4S +static inline float *VMUL4S(float *dst, const float *v, unsigned idx, + unsigned sign, const float *scale) +{ + unsigned nz = idx >> 12; + union av_intfloat32 s = { .f = *scale }; + union av_intfloat32 t; + + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx & 3] * t.f; + + sign <<= nz & 1; nz >>= 1; + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx>>2 & 3] * t.f; + + sign <<= nz & 1; nz >>= 1; + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx>>4 & 3] * t.f; + + sign <<= nz & 1; + t.i = s.i ^ (sign & 1U<<31); + *dst++ = v[idx>>6 & 3] * t.f; + + return dst; +} +#endif + +/** + * Decode spectral data; reference: table 4.50. + * Dequantize and scale spectral data; reference: 4.6.3.3. + * + * @param coef array of dequantized, scaled spectral data + * @param sf array of scalefactors or intensity stereo positions + * @param pulse_present set if pulses are present + * @param pulse pointer to pulse data struct + * @param band_type array of the used band type + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], + GetBitContext *gb, const float sf[120], + int pulse_present, const Pulse *pulse, + const IndividualChannelStream *ics, + enum BandType band_type[120]) +{ + int i, k, g, idx = 0; + const int c = 1024 / ics->num_windows; + const uint16_t *offsets = ics->swb_offset; + float *coef_base = coef; + + for (g = 0; g < ics->num_windows; g++) + memset(coef + g * 128 + offsets[ics->max_sfb], 0, + sizeof(float) * (c - offsets[ics->max_sfb])); + + for (g = 0; g < ics->num_window_groups; g++) { + unsigned g_len = ics->group_len[g]; + + for (i = 0; i < ics->max_sfb; i++, idx++) { + const unsigned cbt_m1 = band_type[idx] - 1; + float *cfo = coef + offsets[i]; + int off_len = offsets[i + 1] - offsets[i]; + int group; + + if (cbt_m1 >= INTENSITY_BT2 - 1) { + for (group = 0; group < g_len; group++, cfo+=128) { + memset(cfo, 0, off_len * sizeof(float)); + } + } else if (cbt_m1 == NOISE_BT - 1) { + for (group = 0; group < g_len; group++, cfo+=128) { + float scale; + float band_energy; + + for (k = 0; k < off_len; k++) { + ac->random_state = lcg_random(ac->random_state); + cfo[k] = ac->random_state; + } + + band_energy = ac->fdsp.scalarproduct_float(cfo, cfo, off_len); + scale = sf[idx] / sqrtf(band_energy); + ac->fdsp.vector_fmul_scalar(cfo, cfo, scale, off_len); + } + } else { + const float *vq = ff_aac_codebook_vector_vals[cbt_m1]; + const uint16_t *cb_vector_idx = ff_aac_codebook_vector_idx[cbt_m1]; + VLC_TYPE (*vlc_tab)[2] = vlc_spectral[cbt_m1].table; + OPEN_READER(re, gb); + + switch (cbt_m1 >> 1) { + case 0: + for (group = 0; group < g_len; group++, cfo+=128) { + float *cf = cfo; + int len = off_len; + + do { + int code; + unsigned cb_idx; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; + cf = VMUL4(cf, vq, cb_idx, sf + idx); + } while (len -= 4); + } + break; + + case 1: + for (group = 0; group < g_len; group++, cfo+=128) { + float *cf = cfo; + int len = off_len; + + do { + int code; + unsigned nnz; + unsigned cb_idx; + uint32_t bits; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; + nnz = cb_idx >> 8 & 15; + bits = nnz ? GET_CACHE(re, gb) : 0; + LAST_SKIP_BITS(re, gb, nnz); + cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx); + } while (len -= 4); + } + break; + + case 2: + for (group = 0; group < g_len; group++, cfo+=128) { + float *cf = cfo; + int len = off_len; + + do { + int code; + unsigned cb_idx; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; + cf = VMUL2(cf, vq, cb_idx, sf + idx); + } while (len -= 2); + } + break; + + case 3: + case 4: + for (group = 0; group < g_len; group++, cfo+=128) { + float *cf = cfo; + int len = off_len; + + do { + int code; + unsigned nnz; + unsigned cb_idx; + unsigned sign; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + cb_idx = cb_vector_idx[code]; + nnz = cb_idx >> 8 & 15; + sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0; + LAST_SKIP_BITS(re, gb, nnz); + cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx); + } while (len -= 2); + } + break; + + default: + for (group = 0; group < g_len; group++, cfo+=128) { + float *cf = cfo; + uint32_t *icf = (uint32_t *) cf; + int len = off_len; + + do { + int code; + unsigned nzt, nnz; + unsigned cb_idx; + uint32_t bits; + int j; + + UPDATE_CACHE(re, gb); + GET_VLC(code, re, gb, vlc_tab, 8, 2); + + if (!code) { + *icf++ = 0; + *icf++ = 0; + continue; + } + + cb_idx = cb_vector_idx[code]; + nnz = cb_idx >> 12; + nzt = cb_idx >> 8; + bits = SHOW_UBITS(re, gb, nnz) << (32-nnz); + LAST_SKIP_BITS(re, gb, nnz); + + for (j = 0; j < 2; j++) { + if (nzt & 1< 8) { + av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n"); + return AVERROR_INVALIDDATA; + } + + SKIP_BITS(re, gb, b + 1); + b += 4; + n = (1 << b) + SHOW_UBITS(re, gb, b); + LAST_SKIP_BITS(re, gb, b); + *icf++ = cbrt_tab[n] | (bits & 1U<<31); + bits <<= 1; + } else { + unsigned v = ((const uint32_t*)vq)[cb_idx & 15]; + *icf++ = (bits & 1U<<31) | v; + bits <<= !!v; + } + cb_idx >>= 4; + } + } while (len -= 2); + + ac->fdsp.vector_fmul_scalar(cfo, cfo, sf[idx], off_len); + } + } + + CLOSE_READER(re, gb); + } + } + coef += g_len << 7; + } + + if (pulse_present) { + idx = 0; + for (i = 0; i < pulse->num_pulse; i++) { + float co = coef_base[ pulse->pos[i] ]; + while (offsets[idx + 1] <= pulse->pos[i]) + idx++; + if (band_type[idx] != NOISE_BT && sf[idx]) { + float ico = -pulse->amp[i]; + if (co) { + co /= sf[idx]; + ico = co / sqrtf(sqrtf(fabsf(co))) + (co > 0 ? -ico : ico); + } + coef_base[ pulse->pos[i] ] = cbrtf(fabsf(ico)) * ico * sf[idx]; + } + } + } + return 0; +} + +static av_always_inline float flt16_round(float pf) +{ + union av_intfloat32 tmp; + tmp.f = pf; + tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U; + return tmp.f; +} + +static av_always_inline float flt16_even(float pf) +{ + union av_intfloat32 tmp; + tmp.f = pf; + tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U; + return tmp.f; +} + +static av_always_inline float flt16_trunc(float pf) +{ + union av_intfloat32 pun; + pun.f = pf; + pun.i &= 0xFFFF0000U; + return pun.f; +} + +static av_always_inline void predict(PredictorState *ps, float *coef, + int output_enable) +{ + const float a = 0.953125; // 61.0 / 64 + const float alpha = 0.90625; // 29.0 / 32 + float e0, e1; + float pv; + float k1, k2; + float r0 = ps->r0, r1 = ps->r1; + float cor0 = ps->cor0, cor1 = ps->cor1; + float var0 = ps->var0, var1 = ps->var1; + + k1 = var0 > 1 ? cor0 * flt16_even(a / var0) : 0; + k2 = var1 > 1 ? cor1 * flt16_even(a / var1) : 0; + + pv = flt16_round(k1 * r0 + k2 * r1); + if (output_enable) + *coef += pv; + + e0 = *coef; + e1 = e0 - k1 * r0; + + ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1); + ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1)); + ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0); + ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0)); + + ps->r1 = flt16_trunc(a * (r0 - k1 * e0)); + ps->r0 = flt16_trunc(a * e0); +} + +/** + * Apply AAC-Main style frequency domain prediction. + */ +static void apply_prediction(AACContext *ac, SingleChannelElement *sce) +{ + int sfb, k; + + if (!sce->ics.predictor_initialized) { + reset_all_predictors(sce->predictor_state); + sce->ics.predictor_initialized = 1; + } + + if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { + for (sfb = 0; + sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]; + sfb++) { + for (k = sce->ics.swb_offset[sfb]; + k < sce->ics.swb_offset[sfb + 1]; + k++) { + predict(&sce->predictor_state[k], &sce->coeffs[k], + sce->ics.predictor_present && + sce->ics.prediction_used[sfb]); + } + } + if (sce->ics.predictor_reset_group) + reset_predictor_group(sce->predictor_state, + sce->ics.predictor_reset_group); + } else + reset_all_predictors(sce->predictor_state); +} + +/** + * Decode an individual_channel_stream payload; reference: table 4.44. + * + * @param common_window Channels have independent [0], or shared [1], Individual Channel Stream information. + * @param scale_flag scalable [1] or non-scalable [0] AAC (Unused until scalable AAC is implemented.) + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_ics(AACContext *ac, SingleChannelElement *sce, + GetBitContext *gb, int common_window, int scale_flag) +{ + Pulse pulse; + TemporalNoiseShaping *tns = &sce->tns; + IndividualChannelStream *ics = &sce->ics; + float *out = sce->coeffs; + int global_gain, er_syntax, pulse_present = 0; + int ret; + + /* This assignment is to silence a GCC warning about the variable being used + * uninitialized when in fact it always is. + */ + pulse.num_pulse = 0; + + global_gain = get_bits(gb, 8); + + if (!common_window && !scale_flag) { + if (decode_ics_info(ac, ics, gb) < 0) + return AVERROR_INVALIDDATA; + } + + if ((ret = decode_band_types(ac, sce->band_type, + sce->band_type_run_end, gb, ics)) < 0) + return ret; + if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics, + sce->band_type, sce->band_type_run_end)) < 0) + return ret; + + pulse_present = 0; + er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD; + if (!scale_flag) { + if ((pulse_present = get_bits1(gb))) { + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse tool not allowed in eight short sequence.\n"); + return AVERROR_INVALIDDATA; + } + if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) { + av_log(ac->avctx, AV_LOG_ERROR, + "Pulse data corrupt or invalid.\n"); + return AVERROR_INVALIDDATA; + } + } + tns->present = get_bits1(gb); + if (tns->present && !er_syntax) + if (decode_tns(ac, tns, gb, ics) < 0) + return AVERROR_INVALIDDATA; + if (get_bits1(gb)) { + avpriv_request_sample(ac->avctx, "SSR"); + return AVERROR_PATCHWELCOME; + } + // I see no textual basis in the spec for this occuring after SSR gain + // control, but this is what both reference and real implmentations do + if (tns->present && er_syntax) + if (decode_tns(ac, tns, gb, ics) < 0) + return AVERROR_INVALIDDATA; + } + + if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, + &pulse, ics, sce->band_type) < 0) + return AVERROR_INVALIDDATA; + + if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window) + apply_prediction(ac, sce); + + return 0; +} + +/** + * Mid/Side stereo decoding; reference: 4.6.8.1.3. + */ +static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe) +{ + const IndividualChannelStream *ics = &cpe->ch[0].ics; + float *ch0 = cpe->ch[0].coeffs; + float *ch1 = cpe->ch[1].coeffs; + int g, i, group, idx = 0; + const uint16_t *offsets = ics->swb_offset; + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb; i++, idx++) { + if (cpe->ms_mask[idx] && + cpe->ch[0].band_type[idx] < NOISE_BT && + cpe->ch[1].band_type[idx] < NOISE_BT) { + for (group = 0; group < ics->group_len[g]; group++) { + ac->fdsp.butterflies_float(ch0 + group * 128 + offsets[i], + ch1 + group * 128 + offsets[i], + offsets[i+1] - offsets[i]); + } + } + } + ch0 += ics->group_len[g] * 128; + ch1 += ics->group_len[g] * 128; + } +} + +/** + * intensity stereo decoding; reference: 4.6.8.2.3 + * + * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s; + * [1] mask is decoded from bitstream; [2] mask is all 1s; + * [3] reserved for scalable AAC + */ +static void apply_intensity_stereo(AACContext *ac, + ChannelElement *cpe, int ms_present) +{ + const IndividualChannelStream *ics = &cpe->ch[1].ics; + SingleChannelElement *sce1 = &cpe->ch[1]; + float *coef0 = cpe->ch[0].coeffs, *coef1 = cpe->ch[1].coeffs; + const uint16_t *offsets = ics->swb_offset; + int g, group, i, idx = 0; + int c; + float scale; + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb;) { + if (sce1->band_type[idx] == INTENSITY_BT || + sce1->band_type[idx] == INTENSITY_BT2) { + const int bt_run_end = sce1->band_type_run_end[idx]; + for (; i < bt_run_end; i++, idx++) { + c = -1 + 2 * (sce1->band_type[idx] - 14); + if (ms_present) + c *= 1 - 2 * cpe->ms_mask[idx]; + scale = c * sce1->sf[idx]; + for (group = 0; group < ics->group_len[g]; group++) + ac->fdsp.vector_fmul_scalar(coef1 + group * 128 + offsets[i], + coef0 + group * 128 + offsets[i], + scale, + offsets[i + 1] - offsets[i]); + } + } else { + int bt_run_end = sce1->band_type_run_end[idx]; + idx += bt_run_end - i; + i = bt_run_end; + } + } + coef0 += ics->group_len[g] * 128; + coef1 += ics->group_len[g] * 128; + } +} + +/** + * Decode a channel_pair_element; reference: table 4.4. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe) +{ + int i, ret, common_window, ms_present = 0; + + common_window = get_bits1(gb); + if (common_window) { + if (decode_ics_info(ac, &cpe->ch[0].ics, gb)) + return AVERROR_INVALIDDATA; + i = cpe->ch[1].ics.use_kb_window[0]; + cpe->ch[1].ics = cpe->ch[0].ics; + cpe->ch[1].ics.use_kb_window[1] = i; + if (cpe->ch[1].ics.predictor_present && + (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN)) + if ((cpe->ch[1].ics.ltp.present = get_bits(gb, 1))) + decode_ltp(&cpe->ch[1].ics.ltp, gb, cpe->ch[1].ics.max_sfb); + ms_present = get_bits(gb, 2); + if (ms_present == 3) { + av_log(ac->avctx, AV_LOG_ERROR, "ms_present = 3 is reserved.\n"); + return AVERROR_INVALIDDATA; + } else if (ms_present) + decode_mid_side_stereo(cpe, gb, ms_present); + } + if ((ret = decode_ics(ac, &cpe->ch[0], gb, common_window, 0))) + return ret; + if ((ret = decode_ics(ac, &cpe->ch[1], gb, common_window, 0))) + return ret; + + if (common_window) { + if (ms_present) + apply_mid_side_stereo(ac, cpe); + if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) { + apply_prediction(ac, &cpe->ch[0]); + apply_prediction(ac, &cpe->ch[1]); + } + } + + apply_intensity_stereo(ac, cpe, ms_present); + return 0; +} + +static const float cce_scale[] = { + 1.09050773266525765921, //2^(1/8) + 1.18920711500272106672, //2^(1/4) + M_SQRT2, + 2, +}; + +/** + * Decode coupling_channel_element; reference: table 4.8. + * + * @return Returns error status. 0 - OK, !0 - error + */ +static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che) +{ + int num_gain = 0; + int c, g, sfb, ret; + int sign; + float scale; + SingleChannelElement *sce = &che->ch[0]; + ChannelCoupling *coup = &che->coup; + + coup->coupling_point = 2 * get_bits1(gb); + coup->num_coupled = get_bits(gb, 3); + for (c = 0; c <= coup->num_coupled; c++) { + num_gain++; + coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE; + coup->id_select[c] = get_bits(gb, 4); + if (coup->type[c] == TYPE_CPE) { + coup->ch_select[c] = get_bits(gb, 2); + if (coup->ch_select[c] == 3) + num_gain++; + } else + coup->ch_select[c] = 2; + } + coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1); + + sign = get_bits(gb, 1); + scale = cce_scale[get_bits(gb, 2)]; + + if ((ret = decode_ics(ac, sce, gb, 0, 0))) + return ret; + + for (c = 0; c < num_gain; c++) { + int idx = 0; + int cge = 1; + int gain = 0; + float gain_cache = 1.0; + if (c) { + cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb); + gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0; + gain_cache = powf(scale, -gain); + } + if (coup->coupling_point == AFTER_IMDCT) { + coup->gain[c][0] = gain_cache; + } else { + for (g = 0; g < sce->ics.num_window_groups; g++) { + for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) { + if (sce->band_type[idx] != ZERO_BT) { + if (!cge) { + int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; + if (t) { + int s = 1; + t = gain += t; + if (sign) { + s -= 2 * (t & 0x1); + t >>= 1; + } + gain_cache = powf(scale, -t) * s; + } + } + coup->gain[c][idx] = gain_cache; + } + } + } + } + } + return 0; +} + +/** + * Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53. + * + * @return Returns number of bytes consumed. + */ +static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc, + GetBitContext *gb) +{ + int i; + int num_excl_chan = 0; + + do { + for (i = 0; i < 7; i++) + che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb); + } while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb)); + + return num_excl_chan / 7; +} + +/** + * Decode dynamic range information; reference: table 4.52. + * + * @return Returns number of bytes consumed. + */ +static int decode_dynamic_range(DynamicRangeControl *che_drc, + GetBitContext *gb) +{ + int n = 1; + int drc_num_bands = 1; + int i; + + /* pce_tag_present? */ + if (get_bits1(gb)) { + che_drc->pce_instance_tag = get_bits(gb, 4); + skip_bits(gb, 4); // tag_reserved_bits + n++; + } + + /* excluded_chns_present? */ + if (get_bits1(gb)) { + n += decode_drc_channel_exclusions(che_drc, gb); + } + + /* drc_bands_present? */ + if (get_bits1(gb)) { + che_drc->band_incr = get_bits(gb, 4); + che_drc->interpolation_scheme = get_bits(gb, 4); + n++; + drc_num_bands += che_drc->band_incr; + for (i = 0; i < drc_num_bands; i++) { + che_drc->band_top[i] = get_bits(gb, 8); + n++; + } + } + + /* prog_ref_level_present? */ + if (get_bits1(gb)) { + che_drc->prog_ref_level = get_bits(gb, 7); + skip_bits1(gb); // prog_ref_level_reserved_bits + n++; + } + + for (i = 0; i < drc_num_bands; i++) { + che_drc->dyn_rng_sgn[i] = get_bits1(gb); + che_drc->dyn_rng_ctl[i] = get_bits(gb, 7); + n++; + } + + return n; +} + +static int decode_fill(AACContext *ac, GetBitContext *gb, int len) { + uint8_t buf[256]; + int i, major, minor; + + if (len < 13+7*8) + goto unknown; + + get_bits(gb, 13); len -= 13; + + for(i=0; i+1=8; i++, len-=8) + buf[i] = get_bits(gb, 8); + + buf[i] = 0; + if (ac->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(ac->avctx, AV_LOG_DEBUG, "FILL:%s\n", buf); + + if (sscanf(buf, "libfaac %d.%d", &major, &minor) == 2){ + ac->avctx->internal->skip_samples = 1024; + } + +unknown: + skip_bits_long(gb, len); + + return 0; +} + +/** + * Decode extension data (incomplete); reference: table 4.51. + * + * @param cnt length of TYPE_FIL syntactic element in bytes + * + * @return Returns number of bytes consumed + */ +static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, + ChannelElement *che, enum RawDataBlockType elem_type) +{ + int crc_flag = 0; + int res = cnt; + switch (get_bits(gb, 4)) { // extension type + case EXT_SBR_DATA_CRC: + crc_flag++; + case EXT_SBR_DATA: + if (!che) { + av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the first channel element.\n"); + return res; + } else if (!ac->oc[1].m4ac.sbr) { + av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n"); + skip_bits_long(gb, 8 * cnt - 4); + return res; + } else if (ac->oc[1].m4ac.sbr == -1 && ac->oc[1].status == OC_LOCKED) { + av_log(ac->avctx, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n"); + skip_bits_long(gb, 8 * cnt - 4); + return res; + } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) { + ac->oc[1].m4ac.sbr = 1; + ac->oc[1].m4ac.ps = 1; + output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags, + ac->oc[1].status, 1); + } else { + ac->oc[1].m4ac.sbr = 1; + } + res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type); + break; + case EXT_DYNAMIC_RANGE: + res = decode_dynamic_range(&ac->che_drc, gb); + break; + case EXT_FILL: + decode_fill(ac, gb, 8 * cnt - 4); + break; + case EXT_FILL_DATA: + case EXT_DATA_ELEMENT: + default: + skip_bits_long(gb, 8 * cnt - 4); + break; + }; + return res; +} + +/** + * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3. + * + * @param decode 1 if tool is used normally, 0 if tool is used in LTP. + * @param coef spectral coefficients + */ +static void apply_tns(float coef[1024], TemporalNoiseShaping *tns, + IndividualChannelStream *ics, int decode) +{ + const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb); + int w, filt, m, i; + int bottom, top, order, start, end, size, inc; + float lpc[TNS_MAX_ORDER]; + float tmp[TNS_MAX_ORDER+1]; + + for (w = 0; w < ics->num_windows; w++) { + bottom = ics->num_swb; + for (filt = 0; filt < tns->n_filt[w]; filt++) { + top = bottom; + bottom = FFMAX(0, top - tns->length[w][filt]); + order = tns->order[w][filt]; + if (order == 0) + continue; + + // tns_decode_coef + compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0); + + start = ics->swb_offset[FFMIN(bottom, mmm)]; + end = ics->swb_offset[FFMIN( top, mmm)]; + if ((size = end - start) <= 0) + continue; + if (tns->direction[w][filt]) { + inc = -1; + start = end - 1; + } else { + inc = 1; + } + start += w * 128; + + if (decode) { + // ar filter + for (m = 0; m < size; m++, start += inc) + for (i = 1; i <= FFMIN(m, order); i++) + coef[start] -= coef[start - i * inc] * lpc[i - 1]; + } else { + // ma filter + for (m = 0; m < size; m++, start += inc) { + tmp[0] = coef[start]; + for (i = 1; i <= FFMIN(m, order); i++) + coef[start] += tmp[i] * lpc[i - 1]; + for (i = order; i > 0; i--) + tmp[i] = tmp[i - 1]; + } + } + } + } +} + +/** + * Apply windowing and MDCT to obtain the spectral + * coefficient from the predicted sample by LTP. + */ +static void windowing_and_mdct_ltp(AACContext *ac, float *out, + float *in, IndividualChannelStream *ics) +{ + const float *lwindow = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; + const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; + + if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) { + ac->fdsp.vector_fmul(in, in, lwindow_prev, 1024); + } else { + memset(in, 0, 448 * sizeof(float)); + ac->fdsp.vector_fmul(in + 448, in + 448, swindow_prev, 128); + } + if (ics->window_sequence[0] != LONG_START_SEQUENCE) { + ac->fdsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024); + } else { + ac->fdsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128); + memset(in + 1024 + 576, 0, 448 * sizeof(float)); + } + ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in); +} + +/** + * Apply the long term prediction + */ +static void apply_ltp(AACContext *ac, SingleChannelElement *sce) +{ + const LongTermPrediction *ltp = &sce->ics.ltp; + const uint16_t *offsets = sce->ics.swb_offset; + int i, sfb; + + if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) { + float *predTime = sce->ret; + float *predFreq = ac->buf_mdct; + int16_t num_samples = 2048; + + if (ltp->lag < 1024) + num_samples = ltp->lag + 1024; + for (i = 0; i < num_samples; i++) + predTime[i] = sce->ltp_state[i + 2048 - ltp->lag] * ltp->coef; + memset(&predTime[i], 0, (2048 - i) * sizeof(float)); + + ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics); + + if (sce->tns.present) + ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0); + + for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++) + if (ltp->used[sfb]) + for (i = offsets[sfb]; i < offsets[sfb + 1]; i++) + sce->coeffs[i] += predFreq[i]; + } +} + +/** + * Update the LTP buffer for next frame + */ +static void update_ltp(AACContext *ac, SingleChannelElement *sce) +{ + IndividualChannelStream *ics = &sce->ics; + float *saved = sce->saved; + float *saved_ltp = sce->coeffs; + const float *lwindow = ics->use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; + int i; + + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + memcpy(saved_ltp, saved, 512 * sizeof(float)); + memset(saved_ltp + 576, 0, 448 * sizeof(float)); + ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64); + for (i = 0; i < 64; i++) + saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i]; + } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { + memcpy(saved_ltp, ac->buf_mdct + 512, 448 * sizeof(float)); + memset(saved_ltp + 576, 0, 448 * sizeof(float)); + ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64); + for (i = 0; i < 64; i++) + saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i]; + } else { // LONG_STOP or ONLY_LONG + ac->fdsp.vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512); + for (i = 0; i < 512; i++) + saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * lwindow[511 - i]; + } + + memcpy(sce->ltp_state, sce->ltp_state+1024, 1024 * sizeof(*sce->ltp_state)); + memcpy(sce->ltp_state+1024, sce->ret, 1024 * sizeof(*sce->ltp_state)); + memcpy(sce->ltp_state+2048, saved_ltp, 1024 * sizeof(*sce->ltp_state)); +} + +/** + * Conduct IMDCT and windowing. + */ +static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce) +{ + IndividualChannelStream *ics = &sce->ics; + float *in = sce->coeffs; + float *out = sce->ret; + float *saved = sce->saved; + const float *swindow = ics->use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128; + const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024; + const float *swindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128; + float *buf = ac->buf_mdct; + float *temp = ac->temp; + int i; + + // imdct + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + for (i = 0; i < 1024; i += 128) + ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i); + } else + ac->mdct.imdct_half(&ac->mdct, buf, in); + + /* window overlapping + * NOTE: To simplify the overlapping code, all 'meaningless' short to long + * and long to short transitions are considered to be short to short + * transitions. This leaves just two cases (long to long and short to short) + * with a little special sauce for EIGHT_SHORT_SEQUENCE. + */ + if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) && + (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) { + ac->fdsp.vector_fmul_window( out, saved, buf, lwindow_prev, 512); + } else { + memcpy( out, saved, 448 * sizeof(float)); + + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + ac->fdsp.vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, 64); + ac->fdsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, 64); + ac->fdsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, 64); + ac->fdsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, 64); + ac->fdsp.vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, 64); + memcpy( out + 448 + 4*128, temp, 64 * sizeof(float)); + } else { + ac->fdsp.vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64); + memcpy( out + 576, buf + 64, 448 * sizeof(float)); + } + } + + // buffer update + if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { + memcpy( saved, temp + 64, 64 * sizeof(float)); + ac->fdsp.vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64); + ac->fdsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64); + ac->fdsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64); + memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(float)); + } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) { + memcpy( saved, buf + 512, 448 * sizeof(float)); + memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(float)); + } else { // LONG_STOP or ONLY_LONG + memcpy( saved, buf + 512, 512 * sizeof(float)); + } +} + +static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) +{ + IndividualChannelStream *ics = &sce->ics; + float *in = sce->coeffs; + float *out = sce->ret; + float *saved = sce->saved; + const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_512 : ff_sine_512; + float *buf = ac->buf_mdct; + + // imdct + ac->mdct.imdct_half(&ac->mdct_ld, buf, in); + + // window overlapping + ac->fdsp.vector_fmul_window(out, saved, buf, lwindow_prev, 256); + + // buffer update + memcpy(saved, buf + 256, 256 * sizeof(float)); +} + +/** + * Apply dependent channel coupling (applied before IMDCT). + * + * @param index index into coupling gain array + */ +static void apply_dependent_coupling(AACContext *ac, + SingleChannelElement *target, + ChannelElement *cce, int index) +{ + IndividualChannelStream *ics = &cce->ch[0].ics; + const uint16_t *offsets = ics->swb_offset; + float *dest = target->coeffs; + const float *src = cce->ch[0].coeffs; + int g, i, group, k, idx = 0; + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) { + av_log(ac->avctx, AV_LOG_ERROR, + "Dependent coupling is not supported together with LTP\n"); + return; + } + for (g = 0; g < ics->num_window_groups; g++) { + for (i = 0; i < ics->max_sfb; i++, idx++) { + if (cce->ch[0].band_type[idx] != ZERO_BT) { + const float gain = cce->coup.gain[index][idx]; + for (group = 0; group < ics->group_len[g]; group++) { + for (k = offsets[i]; k < offsets[i + 1]; k++) { + // XXX dsputil-ize + dest[group * 128 + k] += gain * src[group * 128 + k]; + } + } + } + } + dest += ics->group_len[g] * 128; + src += ics->group_len[g] * 128; + } +} + +/** + * Apply independent channel coupling (applied after IMDCT). + * + * @param index index into coupling gain array + */ +static void apply_independent_coupling(AACContext *ac, + SingleChannelElement *target, + ChannelElement *cce, int index) +{ + int i; + const float gain = cce->coup.gain[index][0]; + const float *src = cce->ch[0].ret; + float *dest = target->ret; + const int len = 1024 << (ac->oc[1].m4ac.sbr == 1); + + for (i = 0; i < len; i++) + dest[i] += gain * src[i]; +} + +/** + * channel coupling transformation interface + * + * @param apply_coupling_method pointer to (in)dependent coupling function + */ +static void apply_channel_coupling(AACContext *ac, ChannelElement *cc, + enum RawDataBlockType type, int elem_id, + enum CouplingPoint coupling_point, + void (*apply_coupling_method)(AACContext *ac, SingleChannelElement *target, ChannelElement *cce, int index)) +{ + int i, c; + + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *cce = ac->che[TYPE_CCE][i]; + int index = 0; + + if (cce && cce->coup.coupling_point == coupling_point) { + ChannelCoupling *coup = &cce->coup; + + for (c = 0; c <= coup->num_coupled; c++) { + if (coup->type[c] == type && coup->id_select[c] == elem_id) { + if (coup->ch_select[c] != 1) { + apply_coupling_method(ac, &cc->ch[0], cce, index); + if (coup->ch_select[c] != 0) + index++; + } + if (coup->ch_select[c] != 2) + apply_coupling_method(ac, &cc->ch[1], cce, index++); + } else + index += 1 + (coup->ch_select[c] == 3); + } + } + } +} + +/** + * Convert spectral data to float samples, applying all supported tools as appropriate. + */ +static void spectral_to_sample(AACContext *ac) +{ + int i, type; + void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce); + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) + imdct_and_window = imdct_and_windowing_ld; + else + imdct_and_window = ac->imdct_and_windowing; + for (type = 3; type >= 0; type--) { + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *che = ac->che[type][i]; + if (che) { + if (type <= TYPE_CPE) + apply_channel_coupling(ac, che, type, i, BEFORE_TNS, apply_dependent_coupling); + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) { + if (che->ch[0].ics.predictor_present) { + if (che->ch[0].ics.ltp.present) + ac->apply_ltp(ac, &che->ch[0]); + if (che->ch[1].ics.ltp.present && type == TYPE_CPE) + ac->apply_ltp(ac, &che->ch[1]); + } + } + if (che->ch[0].tns.present) + ac->apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1); + if (che->ch[1].tns.present) + ac->apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1); + if (type <= TYPE_CPE) + apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, apply_dependent_coupling); + if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) { + imdct_and_window(ac, &che->ch[0]); + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) + ac->update_ltp(ac, &che->ch[0]); + if (type == TYPE_CPE) { + imdct_and_window(ac, &che->ch[1]); + if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) + ac->update_ltp(ac, &che->ch[1]); + } + if (ac->oc[1].m4ac.sbr > 0) { + ff_sbr_apply(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret); + } + } + if (type <= TYPE_CCE) + apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, apply_independent_coupling); + } + } + } +} + +static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) +{ + int size; + AACADTSHeaderInfo hdr_info; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int layout_map_tags, ret; + + size = avpriv_aac_parse_header(gb, &hdr_info); + if (size > 0) { + if (!ac->warned_num_aac_frames && hdr_info.num_aac_frames != 1) { + // This is 2 for "VLB " audio in NSV files. + // See samples/nsv/vlb_audio. + avpriv_report_missing_feature(ac->avctx, + "More than one AAC RDB per ADTS frame"); + ac->warned_num_aac_frames = 1; + } + push_output_configuration(ac); + if (hdr_info.chan_config) { + ac->oc[1].m4ac.chan_config = hdr_info.chan_config; + if ((ret = set_default_channel_config(ac->avctx, + layout_map, + &layout_map_tags, + hdr_info.chan_config)) < 0) + return ret; + if ((ret = output_configure(ac, layout_map, layout_map_tags, + FFMAX(ac->oc[1].status, + OC_TRIAL_FRAME), 0)) < 0) + return ret; + } else { + ac->oc[1].m4ac.chan_config = 0; + /** + * dual mono frames in Japanese DTV can have chan_config 0 + * WITHOUT specifying PCE. + * thus, set dual mono as default. + */ + if (ac->dmono_mode && ac->oc[0].status == OC_NONE) { + layout_map_tags = 2; + layout_map[0][0] = layout_map[1][0] = TYPE_SCE; + layout_map[0][2] = layout_map[1][2] = AAC_CHANNEL_FRONT; + layout_map[0][1] = 0; + layout_map[1][1] = 1; + if (output_configure(ac, layout_map, layout_map_tags, + OC_TRIAL_FRAME, 0)) + return -7; + } + } + ac->oc[1].m4ac.sample_rate = hdr_info.sample_rate; + ac->oc[1].m4ac.sampling_index = hdr_info.sampling_index; + ac->oc[1].m4ac.object_type = hdr_info.object_type; + if (ac->oc[0].status != OC_LOCKED || + ac->oc[0].m4ac.chan_config != hdr_info.chan_config || + ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) { + ac->oc[1].m4ac.sbr = -1; + ac->oc[1].m4ac.ps = -1; + } + if (!hdr_info.crc_absent) + skip_bits(gb, 16); + } + return size; +} + +static int aac_decode_er_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, GetBitContext *gb) +{ + AACContext *ac = avctx->priv_data; + ChannelElement *che; + int err, i; + int samples = 1024; + int chan_config = ac->oc[1].m4ac.chan_config; + + if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) + samples >>= 1; + + ac->frame = data; + + if ((err = frame_configure_elements(avctx)) < 0) + return err; + + ac->tags_mapped = 0; + + if (chan_config < 0 || chan_config >= 8) { + avpriv_request_sample(avctx, "Unknown ER channel configuration %d", + ac->oc[1].m4ac.chan_config); + return AVERROR_INVALIDDATA; + } + for (i = 0; i < tags_per_config[chan_config]; i++) { + const int elem_type = aac_channel_layout_map[chan_config-1][i][0]; + const int elem_id = aac_channel_layout_map[chan_config-1][i][1]; + if (!(che=get_che(ac, elem_type, elem_id))) { + av_log(ac->avctx, AV_LOG_ERROR, + "channel element %d.%d is not allocated\n", + elem_type, elem_id); + return AVERROR_INVALIDDATA; + } + skip_bits(gb, 4); + switch (elem_type) { + case TYPE_SCE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + case TYPE_CPE: + err = decode_cpe(ac, gb, che); + break; + case TYPE_LFE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + break; + } + if (err < 0) + return err; + } + + spectral_to_sample(ac); + + ac->frame->nb_samples = samples; + *got_frame_ptr = 1; + + skip_bits_long(gb, get_bits_left(gb)); + return 0; +} + +static int aac_decode_frame_int(AVCodecContext *avctx, void *data, + int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt) +{ + AACContext *ac = avctx->priv_data; + ChannelElement *che = NULL, *che_prev = NULL; + enum RawDataBlockType elem_type, elem_type_prev = TYPE_END; + int err, elem_id; + int samples = 0, multiplier, audio_found = 0, pce_found = 0; + int is_dmono, sce_count = 0; + + ac->frame = data; + + if (show_bits(gb, 12) == 0xfff) { + if ((err = parse_adts_frame_header(ac, gb)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n"); + goto fail; + } + if (ac->oc[1].m4ac.sampling_index > 12) { + av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index); + err = AVERROR_INVALIDDATA; + goto fail; + } + } + + if ((err = frame_configure_elements(avctx)) < 0) + goto fail; + + ac->tags_mapped = 0; + // parse + while ((elem_type = get_bits(gb, 3)) != TYPE_END) { + elem_id = get_bits(gb, 4); + + if (elem_type < TYPE_DSE) { + if (!(che=get_che(ac, elem_type, elem_id))) { + av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", + elem_type, elem_id); + err = AVERROR_INVALIDDATA; + goto fail; + } + samples = 1024; + } + + switch (elem_type) { + + case TYPE_SCE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; + sce_count++; + break; + + case TYPE_CPE: + err = decode_cpe(ac, gb, che); + audio_found = 1; + break; + + case TYPE_CCE: + err = decode_cce(ac, gb, che); + break; + + case TYPE_LFE: + err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; + break; + + case TYPE_DSE: + err = skip_data_stream_element(ac, gb); + break; + + case TYPE_PCE: { + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int tags; + push_output_configuration(ac); + tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb); + if (tags < 0) { + err = tags; + break; + } + if (pce_found) { + av_log(avctx, AV_LOG_ERROR, + "Not evaluating a further program_config_element as this construct is dubious at best.\n"); + } else { + err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1); + if (!err) + ac->oc[1].m4ac.chan_config = 0; + pce_found = 1; + } + break; + } + + case TYPE_FIL: + if (elem_id == 15) + elem_id += get_bits(gb, 8) - 1; + if (get_bits_left(gb) < 8 * elem_id) { + av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err); + err = AVERROR_INVALIDDATA; + goto fail; + } + while (elem_id > 0) + elem_id -= decode_extension_payload(ac, gb, elem_id, che_prev, elem_type_prev); + err = 0; /* FIXME */ + break; + + default: + err = AVERROR_BUG; /* should not happen, but keeps compiler happy */ + break; + } + + che_prev = che; + elem_type_prev = elem_type; + + if (err) + goto fail; + + if (get_bits_left(gb) < 3) { + av_log(avctx, AV_LOG_ERROR, overread_err); + err = AVERROR_INVALIDDATA; + goto fail; + } + } + + spectral_to_sample(ac); + + multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0; + samples <<= multiplier; + /* for dual-mono audio (SCE + SCE) */ + is_dmono = ac->dmono_mode && sce_count == 2 && + ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); + + if (samples) + ac->frame->nb_samples = samples; + else + av_frame_unref(ac->frame); + *got_frame_ptr = !!samples; + + if (is_dmono) { + if (ac->dmono_mode == 1) + ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0]; + else if (ac->dmono_mode == 2) + ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1]; + } + + if (ac->oc[1].status && audio_found) { + avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier; + avctx->frame_size = samples; + ac->oc[1].status = OC_LOCKED; + } + + if (multiplier) { + int side_size; + const uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); + if (side && side_size>=4) + AV_WL32(side, 2*AV_RL32(side)); + } + return 0; +fail: + pop_output_configuration(ac); + return err; +} + +static int aac_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AACContext *ac = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + GetBitContext gb; + int buf_consumed; + int buf_offset; + int err; + int new_extradata_size; + const uint8_t *new_extradata = av_packet_get_side_data(avpkt, + AV_PKT_DATA_NEW_EXTRADATA, + &new_extradata_size); + int jp_dualmono_size; + const uint8_t *jp_dualmono = av_packet_get_side_data(avpkt, + AV_PKT_DATA_JP_DUALMONO, + &jp_dualmono_size); + + if (new_extradata && 0) { + av_free(avctx->extradata); + avctx->extradata = av_mallocz(new_extradata_size + + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + avctx->extradata_size = new_extradata_size; + memcpy(avctx->extradata, new_extradata, new_extradata_size); + push_output_configuration(ac); + if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, + avctx->extradata, + avctx->extradata_size*8, 1) < 0) { + pop_output_configuration(ac); + return AVERROR_INVALIDDATA; + } + } + + ac->dmono_mode = 0; + if (jp_dualmono && jp_dualmono_size > 0) + ac->dmono_mode = 1 + *jp_dualmono; + if (ac->force_dmono_mode >= 0) + ac->dmono_mode = ac->force_dmono_mode; + + if (INT_MAX / 8 <= buf_size) + return AVERROR_INVALIDDATA; + + if ((err = init_get_bits(&gb, buf, buf_size * 8)) < 0) + return err; + + switch (ac->oc[1].m4ac.object_type) { + case AOT_ER_AAC_LC: + case AOT_ER_AAC_LTP: + case AOT_ER_AAC_LD: + err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb); + break; + default: + err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt); + } + if (err < 0) + return err; + + buf_consumed = (get_bits_count(&gb) + 7) >> 3; + for (buf_offset = buf_consumed; buf_offset < buf_size; buf_offset++) + if (buf[buf_offset]) + break; + + return buf_size > buf_offset ? buf_consumed : buf_size; +} + +static av_cold int aac_decode_close(AVCodecContext *avctx) +{ + AACContext *ac = avctx->priv_data; + int i, type; + + for (i = 0; i < MAX_ELEM_ID; i++) { + for (type = 0; type < 4; type++) { + if (ac->che[type][i]) + ff_aac_sbr_ctx_close(&ac->che[type][i]->sbr); + av_freep(&ac->che[type][i]); + } + } + + ff_mdct_end(&ac->mdct); + ff_mdct_end(&ac->mdct_small); + ff_mdct_end(&ac->mdct_ld); + ff_mdct_end(&ac->mdct_ltp); + return 0; +} + + +#define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word + +struct LATMContext { + AACContext aac_ctx; ///< containing AACContext + int initialized; ///< initialized after a valid extradata was seen + + // parser data + int audio_mux_version_A; ///< LATM syntax version + int frame_length_type; ///< 0/1 variable/fixed frame length + int frame_length; ///< frame length for fixed frame length +}; + +static inline uint32_t latm_get_value(GetBitContext *b) +{ + int length = get_bits(b, 2); + + return get_bits_long(b, (length+1)*8); +} + +static int latm_decode_audio_specific_config(struct LATMContext *latmctx, + GetBitContext *gb, int asclen) +{ + AACContext *ac = &latmctx->aac_ctx; + AVCodecContext *avctx = ac->avctx; + MPEG4AudioConfig m4ac = { 0 }; + int config_start_bit = get_bits_count(gb); + int sync_extension = 0; + int bits_consumed, esize; + + if (asclen) { + sync_extension = 1; + asclen = FFMIN(asclen, get_bits_left(gb)); + } else + asclen = get_bits_left(gb); + + if (config_start_bit % 8) { + avpriv_request_sample(latmctx->aac_ctx.avctx, + "Non-byte-aligned audio-specific config"); + return AVERROR_PATCHWELCOME; + } + if (asclen <= 0) + return AVERROR_INVALIDDATA; + bits_consumed = decode_audio_specific_config(NULL, avctx, &m4ac, + gb->buffer + (config_start_bit / 8), + asclen, sync_extension); + + if (bits_consumed < 0) + return AVERROR_INVALIDDATA; + + if (!latmctx->initialized || + ac->oc[1].m4ac.sample_rate != m4ac.sample_rate || + ac->oc[1].m4ac.chan_config != m4ac.chan_config) { + + if(latmctx->initialized) { + av_log(avctx, AV_LOG_INFO, "audio config changed\n"); + } else { + av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n"); + } + latmctx->initialized = 0; + + esize = (bits_consumed+7) / 8; + + if (avctx->extradata_size < esize) { + av_free(avctx->extradata); + avctx->extradata = av_malloc(esize + FF_INPUT_BUFFER_PADDING_SIZE); + if (!avctx->extradata) + return AVERROR(ENOMEM); + } + + avctx->extradata_size = esize; + memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize); + memset(avctx->extradata+esize, 0, FF_INPUT_BUFFER_PADDING_SIZE); + } + skip_bits_long(gb, bits_consumed); + + return bits_consumed; +} + +static int read_stream_mux_config(struct LATMContext *latmctx, + GetBitContext *gb) +{ + int ret, audio_mux_version = get_bits(gb, 1); + + latmctx->audio_mux_version_A = 0; + if (audio_mux_version) + latmctx->audio_mux_version_A = get_bits(gb, 1); + + if (!latmctx->audio_mux_version_A) { + + if (audio_mux_version) + latm_get_value(gb); // taraFullness + + skip_bits(gb, 1); // allStreamSameTimeFraming + skip_bits(gb, 6); // numSubFrames + // numPrograms + if (get_bits(gb, 4)) { // numPrograms + avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs"); + return AVERROR_PATCHWELCOME; + } + + // for each program (which there is only one in DVB) + + // for each layer (which there is only one in DVB) + if (get_bits(gb, 3)) { // numLayer + avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers"); + return AVERROR_PATCHWELCOME; + } + + // for all but first stream: use_same_config = get_bits(gb, 1); + if (!audio_mux_version) { + if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0) + return ret; + } else { + int ascLen = latm_get_value(gb); + if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0) + return ret; + ascLen -= ret; + skip_bits_long(gb, ascLen); + } + + latmctx->frame_length_type = get_bits(gb, 3); + switch (latmctx->frame_length_type) { + case 0: + skip_bits(gb, 8); // latmBufferFullness + break; + case 1: + latmctx->frame_length = get_bits(gb, 9); + break; + case 3: + case 4: + case 5: + skip_bits(gb, 6); // CELP frame length table index + break; + case 6: + case 7: + skip_bits(gb, 1); // HVXC frame length table index + break; + } + + if (get_bits(gb, 1)) { // other data + if (audio_mux_version) { + latm_get_value(gb); // other_data_bits + } else { + int esc; + do { + esc = get_bits(gb, 1); + skip_bits(gb, 8); + } while (esc); + } + } + + if (get_bits(gb, 1)) // crc present + skip_bits(gb, 8); // config_crc + } + + return 0; +} + +static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb) +{ + uint8_t tmp; + + if (ctx->frame_length_type == 0) { + int mux_slot_length = 0; + do { + tmp = get_bits(gb, 8); + mux_slot_length += tmp; + } while (tmp == 255); + return mux_slot_length; + } else if (ctx->frame_length_type == 1) { + return ctx->frame_length; + } else if (ctx->frame_length_type == 3 || + ctx->frame_length_type == 5 || + ctx->frame_length_type == 7) { + skip_bits(gb, 2); // mux_slot_length_coded + } + return 0; +} + +static int read_audio_mux_element(struct LATMContext *latmctx, + GetBitContext *gb) +{ + int err; + uint8_t use_same_mux = get_bits(gb, 1); + if (!use_same_mux) { + if ((err = read_stream_mux_config(latmctx, gb)) < 0) + return err; + } else if (!latmctx->aac_ctx.avctx->extradata) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG, + "no decoder config found\n"); + return AVERROR(EAGAIN); + } + if (latmctx->audio_mux_version_A == 0) { + int mux_slot_length_bytes = read_payload_length_info(latmctx, gb); + if (mux_slot_length_bytes * 8 > get_bits_left(gb)) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n"); + return AVERROR_INVALIDDATA; + } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, + "frame length mismatch %d << %d\n", + mux_slot_length_bytes * 8, get_bits_left(gb)); + return AVERROR_INVALIDDATA; + } + } + return 0; +} + + +static int latm_decode_frame(AVCodecContext *avctx, void *out, + int *got_frame_ptr, AVPacket *avpkt) +{ + struct LATMContext *latmctx = avctx->priv_data; + int muxlength, err; + GetBitContext gb; + + if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) + return err; + + // check for LOAS sync word + if (get_bits(&gb, 11) != LOAS_SYNC_WORD) + return AVERROR_INVALIDDATA; + + muxlength = get_bits(&gb, 13) + 3; + // not enough data, the parser should have sorted this out + if (muxlength > avpkt->size) + return AVERROR_INVALIDDATA; + + if ((err = read_audio_mux_element(latmctx, &gb)) < 0) + return err; + + if (!latmctx->initialized) { + if (!avctx->extradata) { + *got_frame_ptr = 0; + return avpkt->size; + } else { + push_output_configuration(&latmctx->aac_ctx); + if ((err = decode_audio_specific_config( + &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac, + avctx->extradata, avctx->extradata_size*8, 1)) < 0) { + pop_output_configuration(&latmctx->aac_ctx); + return err; + } + latmctx->initialized = 1; + } + } + + if (show_bits(&gb, 12) == 0xfff) { + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, + "ADTS header detected, probably as result of configuration " + "misparsing\n"); + return AVERROR_INVALIDDATA; + } + + if ((err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt)) < 0) + return err; + + return muxlength; +} + +static av_cold int latm_decode_init(AVCodecContext *avctx) +{ + struct LATMContext *latmctx = avctx->priv_data; + int ret = aac_decode_init(avctx); + + if (avctx->extradata_size > 0) + latmctx->initialized = !ret; + + return ret; +} + +static void aacdec_init(AACContext *c) +{ + c->imdct_and_windowing = imdct_and_windowing; + c->apply_ltp = apply_ltp; + c->apply_tns = apply_tns; + c->windowing_and_mdct_ltp = windowing_and_mdct_ltp; + c->update_ltp = update_ltp; + + if(ARCH_MIPS) + ff_aacdec_init_mips(c); +} +/** + * AVOptions for Japanese DTV specific extensions (ADTS only) + */ +#define AACDEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM +static const AVOption options[] = { + {"dual_mono_mode", "Select the channel to decode for dual mono", + offsetof(AACContext, force_dmono_mode), AV_OPT_TYPE_INT, {.i64=-1}, -1, 2, + AACDEC_FLAGS, "dual_mono_mode"}, + + {"auto", "autoselection", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + {"main", "Select Main/Left channel", 0, AV_OPT_TYPE_CONST, {.i64= 1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + {"sub" , "Select Sub/Right channel", 0, AV_OPT_TYPE_CONST, {.i64= 2}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + {"both", "Select both channels", 0, AV_OPT_TYPE_CONST, {.i64= 0}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"}, + + {NULL}, +}; + +static const AVClass aac_decoder_class = { + .class_name = "AAC decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_aac_decoder = { + .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AAC, + .priv_data_size = sizeof(AACContext), + .init = aac_decode_init, + .close = aac_decode_close, + .decode = aac_decode_frame, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE + }, + .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, + .channel_layouts = aac_channel_layout, + .flush = flush, + .priv_class = &aac_decoder_class, +}; + +/* + Note: This decoder filter is intended to decode LATM streams transferred + in MPEG transport streams which only contain one program. + To do a more complex LATM demuxing a separate LATM demuxer should be used. +*/ +AVCodec ff_aac_latm_decoder = { + .name = "aac_latm", + .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AAC_LATM, + .priv_data_size = sizeof(struct LATMContext), + .init = latm_decode_init, + .close = aac_decode_close, + .decode = latm_decode_frame, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE + }, + .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, + .channel_layouts = aac_channel_layout, + .flush = flush, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdectab.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdectab.h new file mode 100644 index 000000000..4a12b4fb3 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdectab.h @@ -0,0 +1,104 @@ +/* + * AAC decoder data + * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) + * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC decoder data + * @author Oded Shimon ( ods15 ods15 dyndns org ) + * @author Maxim Gavrilov ( maxim.gavrilov gmail com ) + */ + +#ifndef AVCODEC_AACDECTAB_H +#define AVCODEC_AACDECTAB_H + +#include "libavutil/channel_layout.h" +#include "aac.h" + +#include + +/* @name ltp_coef + * Table of the LTP coefficients + */ +static const float ltp_coef[8] = { + 0.570829, 0.696616, 0.813004, 0.911304, + 0.984900, 1.067894, 1.194601, 1.369533, +}; + +/* @name tns_tmp2_map + * Tables of the tmp2[] arrays of LPC coefficients used for TNS. + * The suffix _M_N[] indicate the values of coef_compress and coef_res + * respectively. + * @{ + */ +static const float tns_tmp2_map_1_3[4] = { + 0.00000000, -0.43388373, 0.64278758, 0.34202015, +}; + +static const float tns_tmp2_map_0_3[8] = { + 0.00000000, -0.43388373, -0.78183150, -0.97492790, + 0.98480773, 0.86602539, 0.64278758, 0.34202015, +}; + +static const float tns_tmp2_map_1_4[8] = { + 0.00000000, -0.20791170, -0.40673664, -0.58778524, + 0.67369562, 0.52643216, 0.36124167, 0.18374951, +}; + +static const float tns_tmp2_map_0_4[16] = { + 0.00000000, -0.20791170, -0.40673664, -0.58778524, + -0.74314481, -0.86602539, -0.95105654, -0.99452192, + 0.99573416, 0.96182561, 0.89516330, 0.79801720, + 0.67369562, 0.52643216, 0.36124167, 0.18374951, +}; + +static const float * const tns_tmp2_map[4] = { + tns_tmp2_map_0_3, + tns_tmp2_map_0_4, + tns_tmp2_map_1_3, + tns_tmp2_map_1_4 +}; +// @} + +static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static const uint8_t aac_channel_layout_map[7][5][3] = { + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, }, + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, +}; + +static const uint64_t aac_channel_layout[8] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_7POINT1_WIDE_BACK, + 0, +}; + +#endif /* AVCODEC_AACDECTAB_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps.c new file mode 100644 index 000000000..c541a6997 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps.c @@ -0,0 +1,970 @@ +/* + * MPEG-4 Parametric Stereo decoding functions + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "libavutil/common.h" +#include "libavutil/internal.h" +#include "libavutil/mathematics.h" +#include "libavutil/intmath.h" +#include "avcodec.h" +#include "get_bits.h" +#include "aacps.h" +#include "aacps_tablegen.h" +#include "aacpsdata.c" + +#define PS_BASELINE 0 ///< Operate in Baseline PS mode + ///< Baseline implies 10 or 20 stereo bands, + ///< mixing mode A, and no ipd/opd + +#define numQMFSlots 32 //numTimeSlots * RATE + +static const int8_t num_env_tab[2][4] = { + { 0, 1, 2, 4, }, + { 1, 2, 3, 4, }, +}; + +static const int8_t nr_iidicc_par_tab[] = { + 10, 20, 34, 10, 20, 34, +}; + +static const int8_t nr_iidopd_par_tab[] = { + 5, 11, 17, 5, 11, 17, +}; + +enum { + huff_iid_df1, + huff_iid_dt1, + huff_iid_df0, + huff_iid_dt0, + huff_icc_df, + huff_icc_dt, + huff_ipd_df, + huff_ipd_dt, + huff_opd_df, + huff_opd_dt, +}; + +static const int huff_iid[] = { + huff_iid_df0, + huff_iid_df1, + huff_iid_dt0, + huff_iid_dt1, +}; + +static VLC vlc_ps[10]; + +#define READ_PAR_DATA(PAR, OFFSET, MASK, ERR_CONDITION) \ +/** \ + * Read Inter-channel Intensity Difference/Inter-Channel Coherence/ \ + * Inter-channel Phase Difference/Overall Phase Difference parameters from the \ + * bitstream. \ + * \ + * @param avctx contains the current codec context \ + * @param gb pointer to the input bitstream \ + * @param ps pointer to the Parametric Stereo context \ + * @param PAR pointer to the parameter to be read \ + * @param e envelope to decode \ + * @param dt 1: time delta-coded, 0: frequency delta-coded \ + */ \ +static int read_ ## PAR ## _data(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, \ + int8_t (*PAR)[PS_MAX_NR_IIDICC], int table_idx, int e, int dt) \ +{ \ + int b, num = ps->nr_ ## PAR ## _par; \ + VLC_TYPE (*vlc_table)[2] = vlc_ps[table_idx].table; \ + if (dt) { \ + int e_prev = e ? e - 1 : ps->num_env_old - 1; \ + e_prev = FFMAX(e_prev, 0); \ + for (b = 0; b < num; b++) { \ + int val = PAR[e_prev][b] + get_vlc2(gb, vlc_table, 9, 3) - OFFSET; \ + if (MASK) val &= MASK; \ + PAR[e][b] = val; \ + if (ERR_CONDITION) \ + goto err; \ + } \ + } else { \ + int val = 0; \ + for (b = 0; b < num; b++) { \ + val += get_vlc2(gb, vlc_table, 9, 3) - OFFSET; \ + if (MASK) val &= MASK; \ + PAR[e][b] = val; \ + if (ERR_CONDITION) \ + goto err; \ + } \ + } \ + return 0; \ +err: \ + av_log(avctx, AV_LOG_ERROR, "illegal "#PAR"\n"); \ + return -1; \ +} + +READ_PAR_DATA(iid, huff_offset[table_idx], 0, FFABS(ps->iid_par[e][b]) > 7 + 8 * ps->iid_quant) +READ_PAR_DATA(icc, huff_offset[table_idx], 0, ps->icc_par[e][b] > 7U) +READ_PAR_DATA(ipdopd, 0, 0x07, 0) + +static int ps_read_extension_data(GetBitContext *gb, PSContext *ps, int ps_extension_id) +{ + int e; + int count = get_bits_count(gb); + + if (ps_extension_id) + return 0; + + ps->enable_ipdopd = get_bits1(gb); + if (ps->enable_ipdopd) { + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + read_ipdopd_data(NULL, gb, ps, ps->ipd_par, dt ? huff_ipd_dt : huff_ipd_df, e, dt); + dt = get_bits1(gb); + read_ipdopd_data(NULL, gb, ps, ps->opd_par, dt ? huff_opd_dt : huff_opd_df, e, dt); + } + } + skip_bits1(gb); //reserved_ps + return get_bits_count(gb) - count; +} + +static void ipdopd_reset(int8_t *ipd_hist, int8_t *opd_hist) +{ + int i; + for (i = 0; i < PS_MAX_NR_IPDOPD; i++) { + opd_hist[i] = 0; + ipd_hist[i] = 0; + } +} + +int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps, int bits_left) +{ + int e; + int bit_count_start = get_bits_count(gb_host); + int header; + int bits_consumed; + GetBitContext gbc = *gb_host, *gb = &gbc; + + header = get_bits1(gb); + if (header) { //enable_ps_header + ps->enable_iid = get_bits1(gb); + if (ps->enable_iid) { + int iid_mode = get_bits(gb, 3); + if (iid_mode > 5) { + av_log(avctx, AV_LOG_ERROR, "iid_mode %d is reserved.\n", + iid_mode); + goto err; + } + ps->nr_iid_par = nr_iidicc_par_tab[iid_mode]; + ps->iid_quant = iid_mode > 2; + ps->nr_ipdopd_par = nr_iidopd_par_tab[iid_mode]; + } + ps->enable_icc = get_bits1(gb); + if (ps->enable_icc) { + ps->icc_mode = get_bits(gb, 3); + if (ps->icc_mode > 5) { + av_log(avctx, AV_LOG_ERROR, "icc_mode %d is reserved.\n", + ps->icc_mode); + goto err; + } + ps->nr_icc_par = nr_iidicc_par_tab[ps->icc_mode]; + } + ps->enable_ext = get_bits1(gb); + } + + ps->frame_class = get_bits1(gb); + ps->num_env_old = ps->num_env; + ps->num_env = num_env_tab[ps->frame_class][get_bits(gb, 2)]; + + ps->border_position[0] = -1; + if (ps->frame_class) { + for (e = 1; e <= ps->num_env; e++) + ps->border_position[e] = get_bits(gb, 5); + } else + for (e = 1; e <= ps->num_env; e++) + ps->border_position[e] = (e * numQMFSlots >> ff_log2_tab[ps->num_env]) - 1; + + if (ps->enable_iid) { + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + if (read_iid_data(avctx, gb, ps, ps->iid_par, huff_iid[2*dt+ps->iid_quant], e, dt)) + goto err; + } + } else + memset(ps->iid_par, 0, sizeof(ps->iid_par)); + + if (ps->enable_icc) + for (e = 0; e < ps->num_env; e++) { + int dt = get_bits1(gb); + if (read_icc_data(avctx, gb, ps, ps->icc_par, dt ? huff_icc_dt : huff_icc_df, e, dt)) + goto err; + } + else + memset(ps->icc_par, 0, sizeof(ps->icc_par)); + + if (ps->enable_ext) { + int cnt = get_bits(gb, 4); + if (cnt == 15) { + cnt += get_bits(gb, 8); + } + cnt *= 8; + while (cnt > 7) { + int ps_extension_id = get_bits(gb, 2); + cnt -= 2 + ps_read_extension_data(gb, ps, ps_extension_id); + } + if (cnt < 0) { + av_log(avctx, AV_LOG_ERROR, "ps extension overflow %d\n", cnt); + goto err; + } + skip_bits(gb, cnt); + } + + ps->enable_ipdopd &= !PS_BASELINE; + + //Fix up envelopes + if (!ps->num_env || ps->border_position[ps->num_env] < numQMFSlots - 1) { + //Create a fake envelope + int source = ps->num_env ? ps->num_env - 1 : ps->num_env_old - 1; + int b; + if (source >= 0 && source != ps->num_env) { + if (ps->enable_iid) { + memcpy(ps->iid_par+ps->num_env, ps->iid_par+source, sizeof(ps->iid_par[0])); + } + if (ps->enable_icc) { + memcpy(ps->icc_par+ps->num_env, ps->icc_par+source, sizeof(ps->icc_par[0])); + } + if (ps->enable_ipdopd) { + memcpy(ps->ipd_par+ps->num_env, ps->ipd_par+source, sizeof(ps->ipd_par[0])); + memcpy(ps->opd_par+ps->num_env, ps->opd_par+source, sizeof(ps->opd_par[0])); + } + } + if (ps->enable_iid){ + for (b = 0; b < ps->nr_iid_par; b++) { + if (FFABS(ps->iid_par[ps->num_env][b]) > 7 + 8 * ps->iid_quant) { + av_log(avctx, AV_LOG_ERROR, "iid_par invalid\n"); + goto err; + } + } + } + if (ps->enable_icc){ + for (b = 0; b < ps->nr_iid_par; b++) { + if (ps->icc_par[ps->num_env][b] > 7U) { + av_log(avctx, AV_LOG_ERROR, "icc_par invalid\n"); + goto err; + } + } + } + ps->num_env++; + ps->border_position[ps->num_env] = numQMFSlots - 1; + } + + + ps->is34bands_old = ps->is34bands; + if (!PS_BASELINE && (ps->enable_iid || ps->enable_icc)) + ps->is34bands = (ps->enable_iid && ps->nr_iid_par == 34) || + (ps->enable_icc && ps->nr_icc_par == 34); + + //Baseline + if (!ps->enable_ipdopd) { + memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); + memset(ps->opd_par, 0, sizeof(ps->opd_par)); + } + + if (header) + ps->start = 1; + + bits_consumed = get_bits_count(gb) - bit_count_start; + if (bits_consumed <= bits_left) { + skip_bits_long(gb_host, bits_consumed); + return bits_consumed; + } + av_log(avctx, AV_LOG_ERROR, "Expected to read %d PS bits actually read %d.\n", bits_left, bits_consumed); +err: + ps->start = 0; + skip_bits_long(gb_host, bits_left); + memset(ps->iid_par, 0, sizeof(ps->iid_par)); + memset(ps->icc_par, 0, sizeof(ps->icc_par)); + memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); + memset(ps->opd_par, 0, sizeof(ps->opd_par)); + return bits_left; +} + +/** Split one subband into 2 subsubbands with a symmetric real filter. + * The filter must have its non-center even coefficients equal to zero. */ +static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[8], int len, int reverse) +{ + int i, j; + for (i = 0; i < len; i++, in++) { + float re_in = filter[6] * in[6][0]; //real inphase + float re_op = 0.0f; //real out of phase + float im_in = filter[6] * in[6][1]; //imag inphase + float im_op = 0.0f; //imag out of phase + for (j = 0; j < 6; j += 2) { + re_op += filter[j+1] * (in[j+1][0] + in[12-j-1][0]); + im_op += filter[j+1] * (in[j+1][1] + in[12-j-1][1]); + } + out[ reverse][i][0] = re_in + re_op; + out[ reverse][i][1] = im_in + im_op; + out[!reverse][i][0] = re_in - re_op; + out[!reverse][i][1] = im_in - im_op; + } +} + +/** Split one subband into 6 subsubbands with a complex filter */ +static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int len) +{ + int i; + int N = 8; + LOCAL_ALIGNED_16(float, temp, [8], [2]); + + for (i = 0; i < len; i++, in++) { + dsp->hybrid_analysis(temp, in, filter, 1, N); + out[0][i][0] = temp[6][0]; + out[0][i][1] = temp[6][1]; + out[1][i][0] = temp[7][0]; + out[1][i][1] = temp[7][1]; + out[2][i][0] = temp[0][0]; + out[2][i][1] = temp[0][1]; + out[3][i][0] = temp[1][0]; + out[3][i][1] = temp[1][1]; + out[4][i][0] = temp[2][0] + temp[5][0]; + out[4][i][1] = temp[2][1] + temp[5][1]; + out[5][i][0] = temp[3][0] + temp[4][0]; + out[5][i][1] = temp[3][1] + temp[4][1]; + } +} + +static void hybrid4_8_12_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int N, int len) +{ + int i; + + for (i = 0; i < len; i++, in++) { + dsp->hybrid_analysis(out[0] + i, in, filter, 32, N); + } +} + +static void hybrid_analysis(PSDSPContext *dsp, float out[91][32][2], + float in[5][44][2], float L[2][38][64], + int is34, int len) +{ + int i, j; + for (i = 0; i < 5; i++) { + for (j = 0; j < 38; j++) { + in[i][j+6][0] = L[0][j][i]; + in[i][j+6][1] = L[1][j][i]; + } + } + if (is34) { + hybrid4_8_12_cx(dsp, in[0], out, f34_0_12, 12, len); + hybrid4_8_12_cx(dsp, in[1], out+12, f34_1_8, 8, len); + hybrid4_8_12_cx(dsp, in[2], out+20, f34_2_4, 4, len); + hybrid4_8_12_cx(dsp, in[3], out+24, f34_2_4, 4, len); + hybrid4_8_12_cx(dsp, in[4], out+28, f34_2_4, 4, len); + dsp->hybrid_analysis_ileave(out + 27, L, 5, len); + } else { + hybrid6_cx(dsp, in[0], out, f20_0_8, len); + hybrid2_re(in[1], out+6, g1_Q2, len, 1); + hybrid2_re(in[2], out+8, g1_Q2, len, 0); + dsp->hybrid_analysis_ileave(out + 7, L, 3, len); + } + //update in_buf + for (i = 0; i < 5; i++) { + memcpy(in[i], in[i]+32, 6 * sizeof(in[i][0])); + } +} + +static void hybrid_synthesis(PSDSPContext *dsp, float out[2][38][64], + float in[91][32][2], int is34, int len) +{ + int i, n; + if (is34) { + for (n = 0; n < len; n++) { + memset(out[0][n], 0, 5*sizeof(out[0][n][0])); + memset(out[1][n], 0, 5*sizeof(out[1][n][0])); + for (i = 0; i < 12; i++) { + out[0][n][0] += in[ i][n][0]; + out[1][n][0] += in[ i][n][1]; + } + for (i = 0; i < 8; i++) { + out[0][n][1] += in[12+i][n][0]; + out[1][n][1] += in[12+i][n][1]; + } + for (i = 0; i < 4; i++) { + out[0][n][2] += in[20+i][n][0]; + out[1][n][2] += in[20+i][n][1]; + out[0][n][3] += in[24+i][n][0]; + out[1][n][3] += in[24+i][n][1]; + out[0][n][4] += in[28+i][n][0]; + out[1][n][4] += in[28+i][n][1]; + } + } + dsp->hybrid_synthesis_deint(out, in + 27, 5, len); + } else { + for (n = 0; n < len; n++) { + out[0][n][0] = in[0][n][0] + in[1][n][0] + in[2][n][0] + + in[3][n][0] + in[4][n][0] + in[5][n][0]; + out[1][n][0] = in[0][n][1] + in[1][n][1] + in[2][n][1] + + in[3][n][1] + in[4][n][1] + in[5][n][1]; + out[0][n][1] = in[6][n][0] + in[7][n][0]; + out[1][n][1] = in[6][n][1] + in[7][n][1]; + out[0][n][2] = in[8][n][0] + in[9][n][0]; + out[1][n][2] = in[8][n][1] + in[9][n][1]; + } + dsp->hybrid_synthesis_deint(out, in + 7, 3, len); + } +} + +/// All-pass filter decay slope +#define DECAY_SLOPE 0.05f +/// Number of frequency bands that can be addressed by the parameter index, b(k) +static const int NR_PAR_BANDS[] = { 20, 34 }; +/// Number of frequency bands that can be addressed by the sub subband index, k +static const int NR_BANDS[] = { 71, 91 }; +/// Start frequency band for the all-pass filter decay slope +static const int DECAY_CUTOFF[] = { 10, 32 }; +/// Number of all-pass filer bands +static const int NR_ALLPASS_BANDS[] = { 30, 50 }; +/// First stereo band using the short one sample delay +static const int SHORT_DELAY_BAND[] = { 42, 62 }; + +/** Table 8.46 */ +static void map_idx_10_to_20(int8_t *par_mapped, const int8_t *par, int full) +{ + int b; + if (full) + b = 9; + else { + b = 4; + par_mapped[10] = 0; + } + for (; b >= 0; b--) { + par_mapped[2*b+1] = par_mapped[2*b] = par[b]; + } +} + +static void map_idx_34_to_20(int8_t *par_mapped, const int8_t *par, int full) +{ + par_mapped[ 0] = (2*par[ 0] + par[ 1]) / 3; + par_mapped[ 1] = ( par[ 1] + 2*par[ 2]) / 3; + par_mapped[ 2] = (2*par[ 3] + par[ 4]) / 3; + par_mapped[ 3] = ( par[ 4] + 2*par[ 5]) / 3; + par_mapped[ 4] = ( par[ 6] + par[ 7]) / 2; + par_mapped[ 5] = ( par[ 8] + par[ 9]) / 2; + par_mapped[ 6] = par[10]; + par_mapped[ 7] = par[11]; + par_mapped[ 8] = ( par[12] + par[13]) / 2; + par_mapped[ 9] = ( par[14] + par[15]) / 2; + par_mapped[10] = par[16]; + if (full) { + par_mapped[11] = par[17]; + par_mapped[12] = par[18]; + par_mapped[13] = par[19]; + par_mapped[14] = ( par[20] + par[21]) / 2; + par_mapped[15] = ( par[22] + par[23]) / 2; + par_mapped[16] = ( par[24] + par[25]) / 2; + par_mapped[17] = ( par[26] + par[27]) / 2; + par_mapped[18] = ( par[28] + par[29] + par[30] + par[31]) / 4; + par_mapped[19] = ( par[32] + par[33]) / 2; + } +} + +static void map_val_34_to_20(float par[PS_MAX_NR_IIDICC]) +{ + par[ 0] = (2*par[ 0] + par[ 1]) * 0.33333333f; + par[ 1] = ( par[ 1] + 2*par[ 2]) * 0.33333333f; + par[ 2] = (2*par[ 3] + par[ 4]) * 0.33333333f; + par[ 3] = ( par[ 4] + 2*par[ 5]) * 0.33333333f; + par[ 4] = ( par[ 6] + par[ 7]) * 0.5f; + par[ 5] = ( par[ 8] + par[ 9]) * 0.5f; + par[ 6] = par[10]; + par[ 7] = par[11]; + par[ 8] = ( par[12] + par[13]) * 0.5f; + par[ 9] = ( par[14] + par[15]) * 0.5f; + par[10] = par[16]; + par[11] = par[17]; + par[12] = par[18]; + par[13] = par[19]; + par[14] = ( par[20] + par[21]) * 0.5f; + par[15] = ( par[22] + par[23]) * 0.5f; + par[16] = ( par[24] + par[25]) * 0.5f; + par[17] = ( par[26] + par[27]) * 0.5f; + par[18] = ( par[28] + par[29] + par[30] + par[31]) * 0.25f; + par[19] = ( par[32] + par[33]) * 0.5f; +} + +static void map_idx_10_to_34(int8_t *par_mapped, const int8_t *par, int full) +{ + if (full) { + par_mapped[33] = par[9]; + par_mapped[32] = par[9]; + par_mapped[31] = par[9]; + par_mapped[30] = par[9]; + par_mapped[29] = par[9]; + par_mapped[28] = par[9]; + par_mapped[27] = par[8]; + par_mapped[26] = par[8]; + par_mapped[25] = par[8]; + par_mapped[24] = par[8]; + par_mapped[23] = par[7]; + par_mapped[22] = par[7]; + par_mapped[21] = par[7]; + par_mapped[20] = par[7]; + par_mapped[19] = par[6]; + par_mapped[18] = par[6]; + par_mapped[17] = par[5]; + par_mapped[16] = par[5]; + } else { + par_mapped[16] = 0; + } + par_mapped[15] = par[4]; + par_mapped[14] = par[4]; + par_mapped[13] = par[4]; + par_mapped[12] = par[4]; + par_mapped[11] = par[3]; + par_mapped[10] = par[3]; + par_mapped[ 9] = par[2]; + par_mapped[ 8] = par[2]; + par_mapped[ 7] = par[2]; + par_mapped[ 6] = par[2]; + par_mapped[ 5] = par[1]; + par_mapped[ 4] = par[1]; + par_mapped[ 3] = par[1]; + par_mapped[ 2] = par[0]; + par_mapped[ 1] = par[0]; + par_mapped[ 0] = par[0]; +} + +static void map_idx_20_to_34(int8_t *par_mapped, const int8_t *par, int full) +{ + if (full) { + par_mapped[33] = par[19]; + par_mapped[32] = par[19]; + par_mapped[31] = par[18]; + par_mapped[30] = par[18]; + par_mapped[29] = par[18]; + par_mapped[28] = par[18]; + par_mapped[27] = par[17]; + par_mapped[26] = par[17]; + par_mapped[25] = par[16]; + par_mapped[24] = par[16]; + par_mapped[23] = par[15]; + par_mapped[22] = par[15]; + par_mapped[21] = par[14]; + par_mapped[20] = par[14]; + par_mapped[19] = par[13]; + par_mapped[18] = par[12]; + par_mapped[17] = par[11]; + } + par_mapped[16] = par[10]; + par_mapped[15] = par[ 9]; + par_mapped[14] = par[ 9]; + par_mapped[13] = par[ 8]; + par_mapped[12] = par[ 8]; + par_mapped[11] = par[ 7]; + par_mapped[10] = par[ 6]; + par_mapped[ 9] = par[ 5]; + par_mapped[ 8] = par[ 5]; + par_mapped[ 7] = par[ 4]; + par_mapped[ 6] = par[ 4]; + par_mapped[ 5] = par[ 3]; + par_mapped[ 4] = (par[ 2] + par[ 3]) / 2; + par_mapped[ 3] = par[ 2]; + par_mapped[ 2] = par[ 1]; + par_mapped[ 1] = (par[ 0] + par[ 1]) / 2; + par_mapped[ 0] = par[ 0]; +} + +static void map_val_20_to_34(float par[PS_MAX_NR_IIDICC]) +{ + par[33] = par[19]; + par[32] = par[19]; + par[31] = par[18]; + par[30] = par[18]; + par[29] = par[18]; + par[28] = par[18]; + par[27] = par[17]; + par[26] = par[17]; + par[25] = par[16]; + par[24] = par[16]; + par[23] = par[15]; + par[22] = par[15]; + par[21] = par[14]; + par[20] = par[14]; + par[19] = par[13]; + par[18] = par[12]; + par[17] = par[11]; + par[16] = par[10]; + par[15] = par[ 9]; + par[14] = par[ 9]; + par[13] = par[ 8]; + par[12] = par[ 8]; + par[11] = par[ 7]; + par[10] = par[ 6]; + par[ 9] = par[ 5]; + par[ 8] = par[ 5]; + par[ 7] = par[ 4]; + par[ 6] = par[ 4]; + par[ 5] = par[ 3]; + par[ 4] = (par[ 2] + par[ 3]) * 0.5f; + par[ 3] = par[ 2]; + par[ 2] = par[ 1]; + par[ 1] = (par[ 0] + par[ 1]) * 0.5f; +} + +static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[32][2], int is34) +{ + LOCAL_ALIGNED_16(float, power, [34], [PS_QMF_TIME_SLOTS]); + LOCAL_ALIGNED_16(float, transient_gain, [34], [PS_QMF_TIME_SLOTS]); + float *peak_decay_nrg = ps->peak_decay_nrg; + float *power_smooth = ps->power_smooth; + float *peak_decay_diff_smooth = ps->peak_decay_diff_smooth; + float (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay; + float (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay; + const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; + const float peak_decay_factor = 0.76592833836465f; + const float transient_impact = 1.5f; + const float a_smooth = 0.25f; ///< Smoothing coefficient + int i, k, m, n; + int n0 = 0, nL = 32; + + memset(power, 0, 34 * sizeof(*power)); + + if (is34 != ps->is34bands_old) { + memset(ps->peak_decay_nrg, 0, sizeof(ps->peak_decay_nrg)); + memset(ps->power_smooth, 0, sizeof(ps->power_smooth)); + memset(ps->peak_decay_diff_smooth, 0, sizeof(ps->peak_decay_diff_smooth)); + memset(ps->delay, 0, sizeof(ps->delay)); + memset(ps->ap_delay, 0, sizeof(ps->ap_delay)); + } + + for (k = 0; k < NR_BANDS[is34]; k++) { + int i = k_to_i[k]; + ps->dsp.add_squares(power[i], s[k], nL - n0); + } + + //Transient detection + for (i = 0; i < NR_PAR_BANDS[is34]; i++) { + for (n = n0; n < nL; n++) { + float decayed_peak = peak_decay_factor * peak_decay_nrg[i]; + float denom; + peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]); + power_smooth[i] += a_smooth * (power[i][n] - power_smooth[i]); + peak_decay_diff_smooth[i] += a_smooth * (peak_decay_nrg[i] - power[i][n] - peak_decay_diff_smooth[i]); + denom = transient_impact * peak_decay_diff_smooth[i]; + transient_gain[i][n] = (denom > power_smooth[i]) ? + power_smooth[i] / denom : 1.0f; + } + } + + //Decorrelation and transient reduction + // PS_AP_LINKS - 1 + // ----- + // | | Q_fract_allpass[k][m]*z^-link_delay[m] - a[m]*g_decay_slope[k] + //H[k][z] = z^-2 * phi_fract[k] * | | ---------------------------------------------------------------- + // | | 1 - a[m]*g_decay_slope[k]*Q_fract_allpass[k][m]*z^-link_delay[m] + // m = 0 + //d[k][z] (out) = transient_gain_mapped[k][z] * H[k][z] * s[k][z] + for (k = 0; k < NR_ALLPASS_BANDS[is34]; k++) { + int b = k_to_i[k]; + float g_decay_slope = 1.f - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]); + g_decay_slope = av_clipf(g_decay_slope, 0.f, 1.f); + memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0])); + memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0])); + for (m = 0; m < PS_AP_LINKS; m++) { + memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0])); + } + ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k], + phi_fract[is34][k], Q_fract_allpass[is34][k], + transient_gain[b], g_decay_slope, nL - n0); + } + for (; k < SHORT_DELAY_BAND[is34]; k++) { + int i = k_to_i[k]; + memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0])); + memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0])); + //H = delay 14 + ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 14, + transient_gain[i], nL - n0); + } + for (; k < NR_BANDS[is34]; k++) { + int i = k_to_i[k]; + memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0])); + memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0])); + //H = delay 1 + ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 1, + transient_gain[i], nL - n0); + } +} + +static void remap34(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC], + int8_t (*par)[PS_MAX_NR_IIDICC], + int num_par, int num_env, int full) +{ + int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped; + int e; + if (num_par == 20 || num_par == 11) { + for (e = 0; e < num_env; e++) { + map_idx_20_to_34(par_mapped[e], par[e], full); + } + } else if (num_par == 10 || num_par == 5) { + for (e = 0; e < num_env; e++) { + map_idx_10_to_34(par_mapped[e], par[e], full); + } + } else { + *p_par_mapped = par; + } +} + +static void remap20(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC], + int8_t (*par)[PS_MAX_NR_IIDICC], + int num_par, int num_env, int full) +{ + int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped; + int e; + if (num_par == 34 || num_par == 17) { + for (e = 0; e < num_env; e++) { + map_idx_34_to_20(par_mapped[e], par[e], full); + } + } else if (num_par == 10 || num_par == 5) { + for (e = 0; e < num_env; e++) { + map_idx_10_to_20(par_mapped[e], par[e], full); + } + } else { + *p_par_mapped = par; + } +} + +static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2], int is34) +{ + int e, b, k; + + float (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11; + float (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12; + float (*H21)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H21; + float (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22; + int8_t *opd_hist = ps->opd_hist; + int8_t *ipd_hist = ps->ipd_hist; + int8_t iid_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t icc_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t ipd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t opd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; + int8_t (*iid_mapped)[PS_MAX_NR_IIDICC] = iid_mapped_buf; + int8_t (*icc_mapped)[PS_MAX_NR_IIDICC] = icc_mapped_buf; + int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf; + int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf; + const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; + const float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; + + //Remapping + if (ps->num_env_old) { + memcpy(H11[0][0], H11[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[0][0][0])); + memcpy(H11[1][0], H11[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[1][0][0])); + memcpy(H12[0][0], H12[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[0][0][0])); + memcpy(H12[1][0], H12[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[1][0][0])); + memcpy(H21[0][0], H21[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[0][0][0])); + memcpy(H21[1][0], H21[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[1][0][0])); + memcpy(H22[0][0], H22[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[0][0][0])); + memcpy(H22[1][0], H22[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[1][0][0])); + } + + if (is34) { + remap34(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1); + remap34(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1); + if (ps->enable_ipdopd) { + remap34(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0); + remap34(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0); + } + if (!ps->is34bands_old) { + map_val_20_to_34(H11[0][0]); + map_val_20_to_34(H11[1][0]); + map_val_20_to_34(H12[0][0]); + map_val_20_to_34(H12[1][0]); + map_val_20_to_34(H21[0][0]); + map_val_20_to_34(H21[1][0]); + map_val_20_to_34(H22[0][0]); + map_val_20_to_34(H22[1][0]); + ipdopd_reset(ipd_hist, opd_hist); + } + } else { + remap20(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1); + remap20(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1); + if (ps->enable_ipdopd) { + remap20(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0); + remap20(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0); + } + if (ps->is34bands_old) { + map_val_34_to_20(H11[0][0]); + map_val_34_to_20(H11[1][0]); + map_val_34_to_20(H12[0][0]); + map_val_34_to_20(H12[1][0]); + map_val_34_to_20(H21[0][0]); + map_val_34_to_20(H21[1][0]); + map_val_34_to_20(H22[0][0]); + map_val_34_to_20(H22[1][0]); + ipdopd_reset(ipd_hist, opd_hist); + } + } + + //Mixing + for (e = 0; e < ps->num_env; e++) { + for (b = 0; b < NR_PAR_BANDS[is34]; b++) { + float h11, h12, h21, h22; + h11 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][0]; + h12 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][1]; + h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][2]; + h22 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][3]; + + if (!PS_BASELINE && ps->enable_ipdopd && 2*b <= NR_PAR_BANDS[is34]) { + //The spec say says to only run this smoother when enable_ipdopd + //is set but the reference decoder appears to run it constantly + float h11i, h12i, h21i, h22i; + float ipd_adj_re, ipd_adj_im; + int opd_idx = opd_hist[b] * 8 + opd_mapped[e][b]; + int ipd_idx = ipd_hist[b] * 8 + ipd_mapped[e][b]; + float opd_re = pd_re_smooth[opd_idx]; + float opd_im = pd_im_smooth[opd_idx]; + float ipd_re = pd_re_smooth[ipd_idx]; + float ipd_im = pd_im_smooth[ipd_idx]; + opd_hist[b] = opd_idx & 0x3F; + ipd_hist[b] = ipd_idx & 0x3F; + + ipd_adj_re = opd_re*ipd_re + opd_im*ipd_im; + ipd_adj_im = opd_im*ipd_re - opd_re*ipd_im; + h11i = h11 * opd_im; + h11 = h11 * opd_re; + h12i = h12 * ipd_adj_im; + h12 = h12 * ipd_adj_re; + h21i = h21 * opd_im; + h21 = h21 * opd_re; + h22i = h22 * ipd_adj_im; + h22 = h22 * ipd_adj_re; + H11[1][e+1][b] = h11i; + H12[1][e+1][b] = h12i; + H21[1][e+1][b] = h21i; + H22[1][e+1][b] = h22i; + } + H11[0][e+1][b] = h11; + H12[0][e+1][b] = h12; + H21[0][e+1][b] = h21; + H22[0][e+1][b] = h22; + } + for (k = 0; k < NR_BANDS[is34]; k++) { + float h[2][4]; + float h_step[2][4]; + int start = ps->border_position[e]; + int stop = ps->border_position[e+1]; + float width = 1.f / (stop - start); + b = k_to_i[k]; + h[0][0] = H11[0][e][b]; + h[0][1] = H12[0][e][b]; + h[0][2] = H21[0][e][b]; + h[0][3] = H22[0][e][b]; + if (!PS_BASELINE && ps->enable_ipdopd) { + //Is this necessary? ps_04_new seems unchanged + if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) { + h[1][0] = -H11[1][e][b]; + h[1][1] = -H12[1][e][b]; + h[1][2] = -H21[1][e][b]; + h[1][3] = -H22[1][e][b]; + } else { + h[1][0] = H11[1][e][b]; + h[1][1] = H12[1][e][b]; + h[1][2] = H21[1][e][b]; + h[1][3] = H22[1][e][b]; + } + } + //Interpolation + h_step[0][0] = (H11[0][e+1][b] - h[0][0]) * width; + h_step[0][1] = (H12[0][e+1][b] - h[0][1]) * width; + h_step[0][2] = (H21[0][e+1][b] - h[0][2]) * width; + h_step[0][3] = (H22[0][e+1][b] - h[0][3]) * width; + if (!PS_BASELINE && ps->enable_ipdopd) { + h_step[1][0] = (H11[1][e+1][b] - h[1][0]) * width; + h_step[1][1] = (H12[1][e+1][b] - h[1][1]) * width; + h_step[1][2] = (H21[1][e+1][b] - h[1][2]) * width; + h_step[1][3] = (H22[1][e+1][b] - h[1][3]) * width; + } + ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd]( + l[k] + start + 1, r[k] + start + 1, + h, h_step, stop - start); + } + } +} + +int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float R[2][38][64], int top) +{ + LOCAL_ALIGNED_16(float, Lbuf, [91], [32][2]); + LOCAL_ALIGNED_16(float, Rbuf, [91], [32][2]); + const int len = 32; + int is34 = ps->is34bands; + + top += NR_BANDS[is34] - 64; + memset(ps->delay+top, 0, (NR_BANDS[is34] - top)*sizeof(ps->delay[0])); + if (top < NR_ALLPASS_BANDS[is34]) + memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0])); + + hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len); + decorrelation(ps, Rbuf, Lbuf, is34); + stereo_processing(ps, Lbuf, Rbuf, is34); + hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len); + hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len); + + return 0; +} + +#define PS_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_ps[num], 9, ps_tmp[num].table_size / ps_tmp[num].elem_size, \ + ps_tmp[num].ps_bits, 1, 1, \ + ps_tmp[num].ps_codes, ps_tmp[num].elem_size, ps_tmp[num].elem_size, \ + size); + +#define PS_VLC_ROW(name) \ + { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) } + +av_cold void ff_ps_init(void) { + // Syntax initialization + static const struct { + const void *ps_codes, *ps_bits; + const unsigned int table_size, elem_size; + } ps_tmp[] = { + PS_VLC_ROW(huff_iid_df1), + PS_VLC_ROW(huff_iid_dt1), + PS_VLC_ROW(huff_iid_df0), + PS_VLC_ROW(huff_iid_dt0), + PS_VLC_ROW(huff_icc_df), + PS_VLC_ROW(huff_icc_dt), + PS_VLC_ROW(huff_ipd_df), + PS_VLC_ROW(huff_ipd_dt), + PS_VLC_ROW(huff_opd_df), + PS_VLC_ROW(huff_opd_dt), + }; + + PS_INIT_VLC_STATIC(0, 1544); + PS_INIT_VLC_STATIC(1, 832); + PS_INIT_VLC_STATIC(2, 1024); + PS_INIT_VLC_STATIC(3, 1036); + PS_INIT_VLC_STATIC(4, 544); + PS_INIT_VLC_STATIC(5, 544); + PS_INIT_VLC_STATIC(6, 512); + PS_INIT_VLC_STATIC(7, 512); + PS_INIT_VLC_STATIC(8, 512); + PS_INIT_VLC_STATIC(9, 512); + + ps_tableinit(); +} + +av_cold void ff_ps_ctx_init(PSContext *ps) +{ + ff_psdsp_init(&ps->dsp); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.h new file mode 100644 index 000000000..05a2af652 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.h @@ -0,0 +1,215 @@ +/* + * Header file for hardcoded Parametric Stereo tables + * + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AACPS_TABLEGEN_H +#define AACPS_TABLEGEN_H + +#include +#include + +#if CONFIG_HARDCODED_TABLES +#define ps_tableinit() +#include "libavcodec/aacps_tables.h" +#else +#include "libavutil/common.h" +#include "libavutil/libm.h" +#include "libavutil/mathematics.h" +#include "libavutil/mem.h" +#define NR_ALLPASS_BANDS20 30 +#define NR_ALLPASS_BANDS34 50 +#define PS_AP_LINKS 3 +static float pd_re_smooth[8*8*8]; +static float pd_im_smooth[8*8*8]; +static float HA[46][8][4]; +static float HB[46][8][4]; +static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2]; +static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2]; +static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2]; +static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2]; +static DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2]; +static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2]; + +static const float g0_Q8[] = { + 0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f, + 0.09885108575264f, 0.11793710567217f, 0.125f +}; + +static const float g0_Q12[] = { + 0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f, + 0.07428313801106f, 0.08100347892914f, 0.08333333333333f +}; + +static const float g1_Q8[] = { + 0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f, + 0.10307344158036f, 0.12222452249753f, 0.125f +}; + +static const float g2_Q4[] = { + -0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f, + 0.16486303567403f, 0.23279856662996f, 0.25f +}; + +static void make_filters_from_proto(float (*filter)[8][2], const float *proto, int bands) +{ + int q, n; + for (q = 0; q < bands; q++) { + for (n = 0; n < 7; n++) { + double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands; + filter[q][n][0] = proto[n] * cos(theta); + filter[q][n][1] = proto[n] * -sin(theta); + } + } +} + +static void ps_tableinit(void) +{ + static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 }; + static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 }; + int pd0, pd1, pd2; + + static const float iid_par_dequant[] = { + //iid_par_dequant_default + 0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684, + 0.44668359215096, 0.63095734448019, 0.79432823472428, 1, + 1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838, + 5.01187233627272, 7.94328234724282, 17.7827941003892, + //iid_par_dequant_fine + 0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039, + 0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020, + 0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350, + 0.50118723362727, 0.63095734448019, 0.79432823472428, 1, + 1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958, + 3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745, + 12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349, + 100, 177.827941003892, 316.227766016837, + }; + static const float icc_invq[] = { + 1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1 + }; + static const float acos_icc_invq[] = { + 0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI + }; + int iid, icc; + + int k, m; + static const int8_t f_center_20[] = { + -3, -1, 1, 3, 5, 7, 10, 14, 18, 22, + }; + static const int8_t f_center_34[] = { + 2, 6, 10, 14, 18, 22, 26, 30, + 34,-10, -6, -2, 51, 57, 15, 21, + 27, 33, 39, 45, 54, 66, 78, 42, + 102, 66, 78, 90,102,114,126, 90, + }; + static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f }; + const float fractional_delay_gain = 0.39f; + + for (pd0 = 0; pd0 < 8; pd0++) { + float pd0_re = ipdopd_cos[pd0]; + float pd0_im = ipdopd_sin[pd0]; + for (pd1 = 0; pd1 < 8; pd1++) { + float pd1_re = ipdopd_cos[pd1]; + float pd1_im = ipdopd_sin[pd1]; + for (pd2 = 0; pd2 < 8; pd2++) { + float pd2_re = ipdopd_cos[pd2]; + float pd2_im = ipdopd_sin[pd2]; + float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re; + float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im; + float pd_mag = 1 / sqrt(im_smooth * im_smooth + re_smooth * re_smooth); + pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag; + pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag; + } + } + } + + for (iid = 0; iid < 46; iid++) { + float c = iid_par_dequant[iid]; ///< Linear Inter-channel Intensity Difference + float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c); + float c2 = c * c1; + for (icc = 0; icc < 8; icc++) { + /*if (PS_BASELINE || ps->icc_mode < 3)*/ { + float alpha = 0.5f * acos_icc_invq[icc]; + float beta = alpha * (c1 - c2) * (float)M_SQRT1_2; + HA[iid][icc][0] = c2 * cosf(beta + alpha); + HA[iid][icc][1] = c1 * cosf(beta - alpha); + HA[iid][icc][2] = c2 * sinf(beta + alpha); + HA[iid][icc][3] = c1 * sinf(beta - alpha); + } /* else */ { + float alpha, gamma, mu, rho; + float alpha_c, alpha_s, gamma_c, gamma_s; + rho = FFMAX(icc_invq[icc], 0.05f); + alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f); + mu = c + 1.0f / c; + mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu)); + gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu))); + if (alpha < 0) alpha += M_PI/2; + alpha_c = cosf(alpha); + alpha_s = sinf(alpha); + gamma_c = cosf(gamma); + gamma_s = sinf(gamma); + HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c; + HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c; + HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s; + HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s; + } + } + } + + for (k = 0; k < NR_ALLPASS_BANDS20; k++) { + double f_center, theta; + if (k < FF_ARRAY_ELEMS(f_center_20)) + f_center = f_center_20[k] * 0.125; + else + f_center = k - 6.5f; + for (m = 0; m < PS_AP_LINKS; m++) { + theta = -M_PI * fractional_delay_links[m] * f_center; + Q_fract_allpass[0][k][m][0] = cos(theta); + Q_fract_allpass[0][k][m][1] = sin(theta); + } + theta = -M_PI*fractional_delay_gain*f_center; + phi_fract[0][k][0] = cos(theta); + phi_fract[0][k][1] = sin(theta); + } + for (k = 0; k < NR_ALLPASS_BANDS34; k++) { + double f_center, theta; + if (k < FF_ARRAY_ELEMS(f_center_34)) + f_center = f_center_34[k] / 24.0; + else + f_center = k - 26.5f; + for (m = 0; m < PS_AP_LINKS; m++) { + theta = -M_PI * fractional_delay_links[m] * f_center; + Q_fract_allpass[1][k][m][0] = cos(theta); + Q_fract_allpass[1][k][m][1] = sin(theta); + } + theta = -M_PI*fractional_delay_gain*f_center; + phi_fract[1][k][0] = cos(theta); + phi_fract[1][k][1] = sin(theta); + } + + make_filters_from_proto(f20_0_8, g0_Q8, 8); + make_filters_from_proto(f34_0_12, g0_Q12, 12); + make_filters_from_proto(f34_1_8, g1_Q8, 8); + make_filters_from_proto(f34_2_4, g2_Q4, 4); +} +#endif /* CONFIG_HARDCODED_TABLES */ + +#endif /* AACPS_TABLEGEN_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdata.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdata.c new file mode 100644 index 000000000..7431caebc --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdata.c @@ -0,0 +1,163 @@ +/* + * MPEG-4 Parametric Stereo data tables + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static const uint8_t huff_iid_df1_bits[] = { + 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15, 14, 14, + 13, 12, 12, 11, 10, 10, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 17, 18, 18, + 18, 18, 18, 18, 18, 18, 18, +}; + +static const uint32_t huff_iid_df1_codes[] = { + 0x01FEB4, 0x01FEB5, 0x01FD76, 0x01FD77, 0x01FD74, 0x01FD75, 0x01FE8A, + 0x01FE8B, 0x01FE88, 0x00FE80, 0x01FEB6, 0x00FE82, 0x00FEB8, 0x007F42, + 0x007FAE, 0x003FAF, 0x001FD1, 0x001FE9, 0x000FE9, 0x0007EA, 0x0007FB, + 0x0003FB, 0x0001FB, 0x0001FF, 0x00007C, 0x00003C, 0x00001C, 0x00000C, + 0x000000, 0x000001, 0x000001, 0x000002, 0x000001, 0x00000D, 0x00001D, + 0x00003D, 0x00007D, 0x0000FC, 0x0001FC, 0x0003FC, 0x0003F4, 0x0007EB, + 0x000FEA, 0x001FEA, 0x001FD6, 0x003FD0, 0x007FAF, 0x007F43, 0x00FEB9, + 0x00FE83, 0x01FEB7, 0x00FE81, 0x01FE89, 0x01FE8E, 0x01FE8F, 0x01FE8C, + 0x01FE8D, 0x01FEB2, 0x01FEB3, 0x01FEB0, 0x01FEB1, +}; + +static const uint8_t huff_iid_dt1_bits[] = { + 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 13, + 13, 13, 12, 12, 11, 10, 9, 9, 7, 6, 5, 3, 1, 2, 5, 6, 7, 8, + 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint16_t huff_iid_dt1_codes[] = { + 0x004ED4, 0x004ED5, 0x004ECE, 0x004ECF, 0x004ECC, 0x004ED6, 0x004ED8, + 0x004F46, 0x004F60, 0x002718, 0x002719, 0x002764, 0x002765, 0x00276D, + 0x0027B1, 0x0013B7, 0x0013D6, 0x0009C7, 0x0009E9, 0x0009ED, 0x0004EE, + 0x0004F7, 0x000278, 0x000139, 0x00009A, 0x00009F, 0x000020, 0x000011, + 0x00000A, 0x000003, 0x000001, 0x000000, 0x00000B, 0x000012, 0x000021, + 0x00004C, 0x00009B, 0x00013A, 0x000279, 0x000270, 0x0004EF, 0x0004E2, + 0x0009EA, 0x0009D8, 0x0013D7, 0x0013D0, 0x0027B2, 0x0027A2, 0x00271A, + 0x00271B, 0x004F66, 0x004F67, 0x004F61, 0x004F47, 0x004ED9, 0x004ED7, + 0x004ECD, 0x004ED2, 0x004ED3, 0x004ED0, 0x004ED1, +}; + +static const uint8_t huff_iid_df0_bits[] = { + 17, 17, 17, 17, 16, 15, 13, 10, 9, 7, 6, 5, 4, 3, 1, 3, 4, 5, + 6, 6, 8, 11, 13, 14, 14, 15, 17, 18, 18, +}; + +static const uint32_t huff_iid_df0_codes[] = { + 0x01FFFB, 0x01FFFC, 0x01FFFD, 0x01FFFA, 0x00FFFC, 0x007FFC, 0x001FFD, + 0x0003FE, 0x0001FE, 0x00007E, 0x00003C, 0x00001D, 0x00000D, 0x000005, + 0x000000, 0x000004, 0x00000C, 0x00001C, 0x00003D, 0x00003E, 0x0000FE, + 0x0007FE, 0x001FFC, 0x003FFC, 0x003FFD, 0x007FFD, 0x01FFFE, 0x03FFFE, + 0x03FFFF, +}; + +static const uint8_t huff_iid_dt0_bits[] = { + 19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7, + 9, 11, 13, 14, 17, 19, 20, 20, 20, 20, 20, +}; + +static const uint32_t huff_iid_dt0_codes[] = { + 0x07FFF9, 0x07FFFA, 0x07FFFB, 0x0FFFF8, 0x0FFFF9, 0x0FFFFA, 0x01FFFD, + 0x007FFE, 0x000FFE, 0x0003FE, 0x0000FE, 0x00003E, 0x00000E, 0x000002, + 0x000000, 0x000006, 0x00001E, 0x00007E, 0x0001FE, 0x0007FE, 0x001FFE, + 0x003FFE, 0x01FFFC, 0x07FFF8, 0x0FFFFB, 0x0FFFFC, 0x0FFFFD, 0x0FFFFE, + 0x0FFFFF, +}; + +static const uint8_t huff_icc_df_bits[] = { + 14, 14, 12, 10, 7, 5, 3, 1, 2, 4, 6, 8, 9, 11, 13, +}; + +static const uint16_t huff_icc_df_codes[] = { + 0x3FFF, 0x3FFE, 0x0FFE, 0x03FE, 0x007E, 0x001E, 0x0006, 0x0000, + 0x0002, 0x000E, 0x003E, 0x00FE, 0x01FE, 0x07FE, 0x1FFE, +}; + +static const uint8_t huff_icc_dt_bits[] = { + 14, 13, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14, +}; + +static const uint16_t huff_icc_dt_codes[] = { + 0x3FFE, 0x1FFE, 0x07FE, 0x01FE, 0x007E, 0x001E, 0x0006, 0x0000, + 0x0002, 0x000E, 0x003E, 0x00FE, 0x03FE, 0x0FFE, 0x3FFF, +}; + +static const uint8_t huff_ipd_df_bits[] = { + 1, 3, 4, 4, 4, 4, 4, 4, +}; + +static const uint8_t huff_ipd_df_codes[] = { + 0x01, 0x00, 0x06, 0x04, 0x02, 0x03, 0x05, 0x07, +}; + +static const uint8_t huff_ipd_dt_bits[] = { + 1, 3, 4, 5, 5, 4, 4, 3, +}; + +static const uint8_t huff_ipd_dt_codes[] = { + 0x01, 0x02, 0x02, 0x03, 0x02, 0x00, 0x03, 0x03, +}; + +static const uint8_t huff_opd_df_bits[] = { + 1, 3, 4, 4, 5, 5, 4, 3, +}; + +static const uint8_t huff_opd_df_codes[] = { + 0x01, 0x01, 0x06, 0x04, 0x0F, 0x0E, 0x05, 0x00, +}; + +static const uint8_t huff_opd_dt_bits[] = { + 1, 3, 4, 5, 5, 4, 4, 3, +}; + +static const uint8_t huff_opd_dt_codes[] = { + 0x01, 0x02, 0x01, 0x07, 0x06, 0x00, 0x02, 0x03, +}; + +static const int8_t huff_offset[] = { + 30, 30, + 14, 14, + 7, 7, + 0, 0, + 0, 0, +}; + +///Table 8.48 +static const int8_t k_to_i_20[] = { + 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, + 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19 +}; +///Table 8.49 +static const int8_t k_to_i_34[] = { + 0, 1, 2, 3, 4, 5, 6, 6, 7, 2, 1, 0, 10, 10, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 9, 14, 11, 12, 13, 14, 15, 16, 13, 16, 17, 18, 19, 20, 21, + 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, + 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 +}; + +static const float g1_Q2[] = { + 0.0f, 0.01899487526049f, 0.0f, -0.07293139167538f, + 0.0f, 0.30596630545168f, 0.5f +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.c new file mode 100644 index 000000000..9f6284413 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "aacpsdsp.h" + +static void ps_add_squares_c(float *dst, const float (*src)[2], int n) +{ + int i; + for (i = 0; i < n; i++) + dst[i] += src[i][0] * src[i][0] + src[i][1] * src[i][1]; +} + +static void ps_mul_pair_single_c(float (*dst)[2], float (*src0)[2], float *src1, + int n) +{ + int i; + for (i = 0; i < n; i++) { + dst[i][0] = src0[i][0] * src1[i]; + dst[i][1] = src0[i][1] * src1[i]; + } +} + +static void ps_hybrid_analysis_c(float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + int stride, int n) +{ + int i, j; + + for (i = 0; i < n; i++) { + float sum_re = filter[i][6][0] * in[6][0]; + float sum_im = filter[i][6][0] * in[6][1]; + + for (j = 0; j < 6; j++) { + float in0_re = in[j][0]; + float in0_im = in[j][1]; + float in1_re = in[12-j][0]; + float in1_im = in[12-j][1]; + sum_re += filter[i][j][0] * (in0_re + in1_re) - + filter[i][j][1] * (in0_im - in1_im); + sum_im += filter[i][j][0] * (in0_im + in1_im) + + filter[i][j][1] * (in0_re - in1_re); + } + out[i * stride][0] = sum_re; + out[i * stride][1] = sum_im; + } +} + +static void ps_hybrid_analysis_ileave_c(float (*out)[32][2], float L[2][38][64], + int i, int len) +{ + int j; + + for (; i < 64; i++) { + for (j = 0; j < len; j++) { + out[i][j][0] = L[0][j][i]; + out[i][j][1] = L[1][j][i]; + } + } +} + +static void ps_hybrid_synthesis_deint_c(float out[2][38][64], + float (*in)[32][2], + int i, int len) +{ + int n; + + for (; i < 64; i++) { + for (n = 0; n < len; n++) { + out[0][n][i] = in[i][n][0]; + out[1][n][i] = in[i][n][1]; + } + } +} + +static void ps_decorrelate_c(float (*out)[2], float (*delay)[2], + float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2], + const float phi_fract[2], float (*Q_fract)[2], + const float *transient_gain, + float g_decay_slope, + int len) +{ + static const float a[] = { 0.65143905753106f, + 0.56471812200776f, + 0.48954165955695f }; + float ag[PS_AP_LINKS]; + int m, n; + + for (m = 0; m < PS_AP_LINKS; m++) + ag[m] = a[m] * g_decay_slope; + + for (n = 0; n < len; n++) { + float in_re = delay[n][0] * phi_fract[0] - delay[n][1] * phi_fract[1]; + float in_im = delay[n][0] * phi_fract[1] + delay[n][1] * phi_fract[0]; + for (m = 0; m < PS_AP_LINKS; m++) { + float a_re = ag[m] * in_re; + float a_im = ag[m] * in_im; + float link_delay_re = ap_delay[m][n+2-m][0]; + float link_delay_im = ap_delay[m][n+2-m][1]; + float fractional_delay_re = Q_fract[m][0]; + float fractional_delay_im = Q_fract[m][1]; + float apd_re = in_re; + float apd_im = in_im; + in_re = link_delay_re * fractional_delay_re - + link_delay_im * fractional_delay_im - a_re; + in_im = link_delay_re * fractional_delay_im + + link_delay_im * fractional_delay_re - a_im; + ap_delay[m][n+5][0] = apd_re + ag[m] * in_re; + ap_delay[m][n+5][1] = apd_im + ag[m] * in_im; + } + out[n][0] = transient_gain[n] * in_re; + out[n][1] = transient_gain[n] * in_im; + } +} + +static void ps_stereo_interpolate_c(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len) +{ + float h0 = h[0][0]; + float h1 = h[0][1]; + float h2 = h[0][2]; + float h3 = h[0][3]; + float hs0 = h_step[0][0]; + float hs1 = h_step[0][1]; + float hs2 = h_step[0][2]; + float hs3 = h_step[0][3]; + int n; + + for (n = 0; n < len; n++) { + //l is s, r is d + float l_re = l[n][0]; + float l_im = l[n][1]; + float r_re = r[n][0]; + float r_im = r[n][1]; + h0 += hs0; + h1 += hs1; + h2 += hs2; + h3 += hs3; + l[n][0] = h0 * l_re + h2 * r_re; + l[n][1] = h0 * l_im + h2 * r_im; + r[n][0] = h1 * l_re + h3 * r_re; + r[n][1] = h1 * l_im + h3 * r_im; + } +} + +static void ps_stereo_interpolate_ipdopd_c(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len) +{ + float h00 = h[0][0], h10 = h[1][0]; + float h01 = h[0][1], h11 = h[1][1]; + float h02 = h[0][2], h12 = h[1][2]; + float h03 = h[0][3], h13 = h[1][3]; + float hs00 = h_step[0][0], hs10 = h_step[1][0]; + float hs01 = h_step[0][1], hs11 = h_step[1][1]; + float hs02 = h_step[0][2], hs12 = h_step[1][2]; + float hs03 = h_step[0][3], hs13 = h_step[1][3]; + int n; + + for (n = 0; n < len; n++) { + //l is s, r is d + float l_re = l[n][0]; + float l_im = l[n][1]; + float r_re = r[n][0]; + float r_im = r[n][1]; + h00 += hs00; + h01 += hs01; + h02 += hs02; + h03 += hs03; + h10 += hs10; + h11 += hs11; + h12 += hs12; + h13 += hs13; + + l[n][0] = h00 * l_re + h02 * r_re - h10 * l_im - h12 * r_im; + l[n][1] = h00 * l_im + h02 * r_im + h10 * l_re + h12 * r_re; + r[n][0] = h01 * l_re + h03 * r_re - h11 * l_im - h13 * r_im; + r[n][1] = h01 * l_im + h03 * r_im + h11 * l_re + h13 * r_re; + } +} + +av_cold void ff_psdsp_init(PSDSPContext *s) +{ + s->add_squares = ps_add_squares_c; + s->mul_pair_single = ps_mul_pair_single_c; + s->hybrid_analysis = ps_hybrid_analysis_c; + s->hybrid_analysis_ileave = ps_hybrid_analysis_ileave_c; + s->hybrid_synthesis_deint = ps_hybrid_synthesis_deint_c; + s->decorrelate = ps_decorrelate_c; + s->stereo_interpolate[0] = ps_stereo_interpolate_c; + s->stereo_interpolate[1] = ps_stereo_interpolate_ipdopd_c; + + if (ARCH_ARM) + ff_psdsp_init_arm(s); + if (ARCH_MIPS) + ff_psdsp_init_mips(s); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbr.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbr.c new file mode 100644 index 000000000..0b6779c29 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbr.c @@ -0,0 +1,1762 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication decoding functions + * @author Robert Swain ( rob opendot cl ) + */ + +#include "aac.h" +#include "sbr.h" +#include "aacsbr.h" +#include "aacsbrdata.h" +#include "fft.h" +#include "aacps.h" +#include "sbrdsp.h" +#include "libavutil/internal.h" +#include "libavutil/libm.h" +#include "libavutil/avassert.h" + +#include +#include +#include + +#define ENVELOPE_ADJUSTMENT_OFFSET 2 +#define NOISE_FLOOR_OFFSET 6.0f + +#if ARCH_MIPS +#include "mips/aacsbr_mips.h" +#endif /* ARCH_MIPS */ + +/** + * SBR VLC tables + */ +enum { + T_HUFFMAN_ENV_1_5DB, + F_HUFFMAN_ENV_1_5DB, + T_HUFFMAN_ENV_BAL_1_5DB, + F_HUFFMAN_ENV_BAL_1_5DB, + T_HUFFMAN_ENV_3_0DB, + F_HUFFMAN_ENV_3_0DB, + T_HUFFMAN_ENV_BAL_3_0DB, + F_HUFFMAN_ENV_BAL_3_0DB, + T_HUFFMAN_NOISE_3_0DB, + T_HUFFMAN_NOISE_BAL_3_0DB, +}; + +/** + * bs_frame_class - frame class of current SBR frame (14496-3 sp04 p98) + */ +enum { + FIXFIX, + FIXVAR, + VARFIX, + VARVAR, +}; + +enum { + EXTENSION_ID_PS = 2, +}; + +static VLC vlc_sbr[10]; +static const int8_t vlc_sbr_lav[10] = + { 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 }; + +#define SBR_INIT_VLC_STATIC(num, size) \ + INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size, \ + sbr_tmp[num].sbr_bits , 1, 1, \ + sbr_tmp[num].sbr_codes, sbr_tmp[num].elem_size, sbr_tmp[num].elem_size, \ + size) + +#define SBR_VLC_ROW(name) \ + { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) } + +static void aacsbr_func_ptr_init(AACSBRContext *c); + +av_cold void ff_aac_sbr_init(void) +{ + int n; + static const struct { + const void *sbr_codes, *sbr_bits; + const unsigned int table_size, elem_size; + } sbr_tmp[] = { + SBR_VLC_ROW(t_huffman_env_1_5dB), + SBR_VLC_ROW(f_huffman_env_1_5dB), + SBR_VLC_ROW(t_huffman_env_bal_1_5dB), + SBR_VLC_ROW(f_huffman_env_bal_1_5dB), + SBR_VLC_ROW(t_huffman_env_3_0dB), + SBR_VLC_ROW(f_huffman_env_3_0dB), + SBR_VLC_ROW(t_huffman_env_bal_3_0dB), + SBR_VLC_ROW(f_huffman_env_bal_3_0dB), + SBR_VLC_ROW(t_huffman_noise_3_0dB), + SBR_VLC_ROW(t_huffman_noise_bal_3_0dB), + }; + + // SBR VLC table initialization + SBR_INIT_VLC_STATIC(0, 1098); + SBR_INIT_VLC_STATIC(1, 1092); + SBR_INIT_VLC_STATIC(2, 768); + SBR_INIT_VLC_STATIC(3, 1026); + SBR_INIT_VLC_STATIC(4, 1058); + SBR_INIT_VLC_STATIC(5, 1052); + SBR_INIT_VLC_STATIC(6, 544); + SBR_INIT_VLC_STATIC(7, 544); + SBR_INIT_VLC_STATIC(8, 592); + SBR_INIT_VLC_STATIC(9, 512); + + for (n = 1; n < 320; n++) + sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n]; + sbr_qmf_window_us[384] = -sbr_qmf_window_us[384]; + sbr_qmf_window_us[512] = -sbr_qmf_window_us[512]; + + for (n = 0; n < 320; n++) + sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n]; + + ff_ps_init(); +} + +/** Places SBR in pure upsampling mode. */ +static void sbr_turnoff(SpectralBandReplication *sbr) { + sbr->start = 0; + // Init defults used in pure upsampling mode + sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 + sbr->m[1] = 0; + // Reset values for first SBR header + sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; + memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters)); +} + +av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr) +{ + if(sbr->mdct.mdct_bits) + return; + sbr->kx[0] = sbr->kx[1]; + sbr_turnoff(sbr); + sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); + sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); + /* SBR requires samples to be scaled to +/-32768.0 to work correctly. + * mdct scale factors are adjusted to scale up from +/-1.0 at analysis + * and scale back down at synthesis. */ + ff_mdct_init(&sbr->mdct, 7, 1, 1.0 / (64 * 32768.0)); + ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0); + ff_ps_ctx_init(&sbr->ps); + ff_sbrdsp_init(&sbr->dsp); + aacsbr_func_ptr_init(&sbr->c); +} + +av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr) +{ + ff_mdct_end(&sbr->mdct); + ff_mdct_end(&sbr->mdct_ana); +} + +static int qsort_comparison_function_int16(const void *a, const void *b) +{ + return *(const int16_t *)a - *(const int16_t *)b; +} + +static inline int in_table_int16(const int16_t *table, int last_el, int16_t needle) +{ + int i; + for (i = 0; i <= last_el; i++) + if (table[i] == needle) + return 1; + return 0; +} + +/// Limiter Frequency Band Table (14496-3 sp04 p198) +static void sbr_make_f_tablelim(SpectralBandReplication *sbr) +{ + int k; + if (sbr->bs_limiter_bands > 0) { + static const float bands_warped[3] = { 1.32715174233856803909f, //2^(0.49/1.2) + 1.18509277094158210129f, //2^(0.49/2) + 1.11987160404675912501f }; //2^(0.49/3) + const float lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1]; + int16_t patch_borders[7]; + uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim; + + patch_borders[0] = sbr->kx[1]; + for (k = 1; k <= sbr->num_patches; k++) + patch_borders[k] = patch_borders[k-1] + sbr->patch_num_subbands[k-1]; + + memcpy(sbr->f_tablelim, sbr->f_tablelow, + (sbr->n[0] + 1) * sizeof(sbr->f_tablelow[0])); + if (sbr->num_patches > 1) + memcpy(sbr->f_tablelim + sbr->n[0] + 1, patch_borders + 1, + (sbr->num_patches - 1) * sizeof(patch_borders[0])); + + qsort(sbr->f_tablelim, sbr->num_patches + sbr->n[0], + sizeof(sbr->f_tablelim[0]), + qsort_comparison_function_int16); + + sbr->n_lim = sbr->n[0] + sbr->num_patches - 1; + while (out < sbr->f_tablelim + sbr->n_lim) { + if (*in >= *out * lim_bands_per_octave_warped) { + *++out = *in++; + } else if (*in == *out || + !in_table_int16(patch_borders, sbr->num_patches, *in)) { + in++; + sbr->n_lim--; + } else if (!in_table_int16(patch_borders, sbr->num_patches, *out)) { + *out = *in++; + sbr->n_lim--; + } else { + *++out = *in++; + } + } + } else { + sbr->f_tablelim[0] = sbr->f_tablelow[0]; + sbr->f_tablelim[1] = sbr->f_tablelow[sbr->n[0]]; + sbr->n_lim = 1; + } +} + +static unsigned int read_sbr_header(SpectralBandReplication *sbr, GetBitContext *gb) +{ + unsigned int cnt = get_bits_count(gb); + uint8_t bs_header_extra_1; + uint8_t bs_header_extra_2; + int old_bs_limiter_bands = sbr->bs_limiter_bands; + SpectrumParameters old_spectrum_params; + + sbr->start = 1; + + // Save last spectrum parameters variables to compare to new ones + memcpy(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters)); + + sbr->bs_amp_res_header = get_bits1(gb); + sbr->spectrum_params.bs_start_freq = get_bits(gb, 4); + sbr->spectrum_params.bs_stop_freq = get_bits(gb, 4); + sbr->spectrum_params.bs_xover_band = get_bits(gb, 3); + skip_bits(gb, 2); // bs_reserved + + bs_header_extra_1 = get_bits1(gb); + bs_header_extra_2 = get_bits1(gb); + + if (bs_header_extra_1) { + sbr->spectrum_params.bs_freq_scale = get_bits(gb, 2); + sbr->spectrum_params.bs_alter_scale = get_bits1(gb); + sbr->spectrum_params.bs_noise_bands = get_bits(gb, 2); + } else { + sbr->spectrum_params.bs_freq_scale = 2; + sbr->spectrum_params.bs_alter_scale = 1; + sbr->spectrum_params.bs_noise_bands = 2; + } + + // Check if spectrum parameters changed + if (memcmp(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters))) + sbr->reset = 1; + + if (bs_header_extra_2) { + sbr->bs_limiter_bands = get_bits(gb, 2); + sbr->bs_limiter_gains = get_bits(gb, 2); + sbr->bs_interpol_freq = get_bits1(gb); + sbr->bs_smoothing_mode = get_bits1(gb); + } else { + sbr->bs_limiter_bands = 2; + sbr->bs_limiter_gains = 2; + sbr->bs_interpol_freq = 1; + sbr->bs_smoothing_mode = 1; + } + + if (sbr->bs_limiter_bands != old_bs_limiter_bands && !sbr->reset) + sbr_make_f_tablelim(sbr); + + return get_bits_count(gb) - cnt; +} + +static int array_min_int16(const int16_t *array, int nel) +{ + int i, min = array[0]; + for (i = 1; i < nel; i++) + min = FFMIN(array[i], min); + return min; +} + +static void make_bands(int16_t* bands, int start, int stop, int num_bands) +{ + int k, previous, present; + float base, prod; + + base = powf((float)stop / start, 1.0f / num_bands); + prod = start; + previous = start; + + for (k = 0; k < num_bands-1; k++) { + prod *= base; + present = lrintf(prod); + bands[k] = present - previous; + previous = present; + } + bands[num_bands-1] = stop - previous; +} + +static int check_n_master(AVCodecContext *avctx, int n_master, int bs_xover_band) +{ + // Requirements (14496-3 sp04 p205) + if (n_master <= 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master); + return -1; + } + if (bs_xover_band >= n_master) { + av_log(avctx, AV_LOG_ERROR, + "Invalid bitstream, crossover band index beyond array bounds: %d\n", + bs_xover_band); + return -1; + } + return 0; +} + +/// Master Frequency Band Table (14496-3 sp04 p194) +static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, + SpectrumParameters *spectrum) +{ + unsigned int temp, max_qmf_subbands; + unsigned int start_min, stop_min; + int k; + const int8_t *sbr_offset_ptr; + int16_t stop_dk[13]; + + if (sbr->sample_rate < 32000) { + temp = 3000; + } else if (sbr->sample_rate < 64000) { + temp = 4000; + } else + temp = 5000; + + switch (sbr->sample_rate) { + case 16000: + sbr_offset_ptr = sbr_offset[0]; + break; + case 22050: + sbr_offset_ptr = sbr_offset[1]; + break; + case 24000: + sbr_offset_ptr = sbr_offset[2]; + break; + case 32000: + sbr_offset_ptr = sbr_offset[3]; + break; + case 44100: case 48000: case 64000: + sbr_offset_ptr = sbr_offset[4]; + break; + case 88200: case 96000: case 128000: case 176400: case 192000: + sbr_offset_ptr = sbr_offset[5]; + break; + default: + av_log(ac->avctx, AV_LOG_ERROR, + "Unsupported sample rate for SBR: %d\n", sbr->sample_rate); + return -1; + } + + start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + + sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq]; + + if (spectrum->bs_stop_freq < 14) { + sbr->k[2] = stop_min; + make_bands(stop_dk, stop_min, 64, 13); + qsort(stop_dk, 13, sizeof(stop_dk[0]), qsort_comparison_function_int16); + for (k = 0; k < spectrum->bs_stop_freq; k++) + sbr->k[2] += stop_dk[k]; + } else if (spectrum->bs_stop_freq == 14) { + sbr->k[2] = 2*sbr->k[0]; + } else if (spectrum->bs_stop_freq == 15) { + sbr->k[2] = 3*sbr->k[0]; + } else { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq); + return -1; + } + sbr->k[2] = FFMIN(64, sbr->k[2]); + + // Requirements (14496-3 sp04 p205) + if (sbr->sample_rate <= 32000) { + max_qmf_subbands = 48; + } else if (sbr->sample_rate == 44100) { + max_qmf_subbands = 35; + } else if (sbr->sample_rate >= 48000) + max_qmf_subbands = 32; + else + av_assert0(0); + + if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]); + return -1; + } + + if (!spectrum->bs_freq_scale) { + int dk, k2diff; + + dk = spectrum->bs_alter_scale + 1; + sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1; + if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band)) + return -1; + + for (k = 1; k <= sbr->n_master; k++) + sbr->f_master[k] = dk; + + k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk; + if (k2diff < 0) { + sbr->f_master[1]--; + sbr->f_master[2]-= (k2diff < -1); + } else if (k2diff) { + sbr->f_master[sbr->n_master]++; + } + + sbr->f_master[0] = sbr->k[0]; + for (k = 1; k <= sbr->n_master; k++) + sbr->f_master[k] += sbr->f_master[k - 1]; + + } else { + int half_bands = 7 - spectrum->bs_freq_scale; // bs_freq_scale = {1,2,3} + int two_regions, num_bands_0; + int vdk0_max, vdk1_min; + int16_t vk0[49]; + + if (49 * sbr->k[2] > 110 * sbr->k[0]) { + two_regions = 1; + sbr->k[1] = 2 * sbr->k[0]; + } else { + two_regions = 0; + sbr->k[1] = sbr->k[2]; + } + + num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2; + + if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205) + av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0); + return -1; + } + + vk0[0] = 0; + + make_bands(vk0+1, sbr->k[0], sbr->k[1], num_bands_0); + + qsort(vk0 + 1, num_bands_0, sizeof(vk0[1]), qsort_comparison_function_int16); + vdk0_max = vk0[num_bands_0]; + + vk0[0] = sbr->k[0]; + for (k = 1; k <= num_bands_0; k++) { + if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205) + av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]); + return -1; + } + vk0[k] += vk0[k-1]; + } + + if (two_regions) { + int16_t vk1[49]; + float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f + : 1.0f; // bs_alter_scale = {0,1} + int num_bands_1 = lrintf(half_bands * invwarp * + log2f(sbr->k[2] / (float)sbr->k[1])) * 2; + + make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1); + + vdk1_min = array_min_int16(vk1 + 1, num_bands_1); + + if (vdk1_min < vdk0_max) { + int change; + qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16); + change = FFMIN(vdk0_max - vk1[1], (vk1[num_bands_1] - vk1[1]) >> 1); + vk1[1] += change; + vk1[num_bands_1] -= change; + } + + qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16); + + vk1[0] = sbr->k[1]; + for (k = 1; k <= num_bands_1; k++) { + if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205) + av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]); + return -1; + } + vk1[k] += vk1[k-1]; + } + + sbr->n_master = num_bands_0 + num_bands_1; + if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band)) + return -1; + memcpy(&sbr->f_master[0], vk0, + (num_bands_0 + 1) * sizeof(sbr->f_master[0])); + memcpy(&sbr->f_master[num_bands_0 + 1], vk1 + 1, + num_bands_1 * sizeof(sbr->f_master[0])); + + } else { + sbr->n_master = num_bands_0; + if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band)) + return -1; + memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0])); + } + } + + return 0; +} + +/// High Frequency Generation - Patch Construction (14496-3 sp04 p216 fig. 4.46) +static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) +{ + int i, k, sb = 0; + int msb = sbr->k[0]; + int usb = sbr->kx[1]; + int goal_sb = ((1000 << 11) + (sbr->sample_rate >> 1)) / sbr->sample_rate; + + sbr->num_patches = 0; + + if (goal_sb < sbr->kx[1] + sbr->m[1]) { + for (k = 0; sbr->f_master[k] < goal_sb; k++) ; + } else + k = sbr->n_master; + + do { + int odd = 0; + for (i = k; i == k || sb > (sbr->k[0] - 1 + msb - odd); i--) { + sb = sbr->f_master[i]; + odd = (sb + sbr->k[0]) & 1; + } + + // Requirements (14496-3 sp04 p205) sets the maximum number of patches to 5. + // After this check the final number of patches can still be six which is + // illegal however the Coding Technologies decoder check stream has a final + // count of 6 patches + if (sbr->num_patches > 5) { + av_log(ac->avctx, AV_LOG_ERROR, "Too many patches: %d\n", sbr->num_patches); + return -1; + } + + sbr->patch_num_subbands[sbr->num_patches] = FFMAX(sb - usb, 0); + sbr->patch_start_subband[sbr->num_patches] = sbr->k[0] - odd - sbr->patch_num_subbands[sbr->num_patches]; + + if (sbr->patch_num_subbands[sbr->num_patches] > 0) { + usb = sb; + msb = sb; + sbr->num_patches++; + } else + msb = sbr->kx[1]; + + if (sbr->f_master[k] - sb < 3) + k = sbr->n_master; + } while (sb != sbr->kx[1] + sbr->m[1]); + + if (sbr->num_patches > 1 && sbr->patch_num_subbands[sbr->num_patches-1] < 3) + sbr->num_patches--; + + return 0; +} + +/// Derived Frequency Band Tables (14496-3 sp04 p197) +static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr) +{ + int k, temp; + + sbr->n[1] = sbr->n_master - sbr->spectrum_params.bs_xover_band; + sbr->n[0] = (sbr->n[1] + 1) >> 1; + + memcpy(sbr->f_tablehigh, &sbr->f_master[sbr->spectrum_params.bs_xover_band], + (sbr->n[1] + 1) * sizeof(sbr->f_master[0])); + sbr->m[1] = sbr->f_tablehigh[sbr->n[1]] - sbr->f_tablehigh[0]; + sbr->kx[1] = sbr->f_tablehigh[0]; + + // Requirements (14496-3 sp04 p205) + if (sbr->kx[1] + sbr->m[1] > 64) { + av_log(ac->avctx, AV_LOG_ERROR, + "Stop frequency border too high: %d\n", sbr->kx[1] + sbr->m[1]); + return -1; + } + if (sbr->kx[1] > 32) { + av_log(ac->avctx, AV_LOG_ERROR, "Start frequency border too high: %d\n", sbr->kx[1]); + return -1; + } + + sbr->f_tablelow[0] = sbr->f_tablehigh[0]; + temp = sbr->n[1] & 1; + for (k = 1; k <= sbr->n[0]; k++) + sbr->f_tablelow[k] = sbr->f_tablehigh[2 * k - temp]; + + sbr->n_q = FFMAX(1, lrintf(sbr->spectrum_params.bs_noise_bands * + log2f(sbr->k[2] / (float)sbr->kx[1]))); // 0 <= bs_noise_bands <= 3 + if (sbr->n_q > 5) { + av_log(ac->avctx, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q); + return -1; + } + + sbr->f_tablenoise[0] = sbr->f_tablelow[0]; + temp = 0; + for (k = 1; k <= sbr->n_q; k++) { + temp += (sbr->n[0] - temp) / (sbr->n_q + 1 - k); + sbr->f_tablenoise[k] = sbr->f_tablelow[temp]; + } + + if (sbr_hf_calc_npatches(ac, sbr) < 0) + return -1; + + sbr_make_f_tablelim(sbr); + + sbr->data[0].f_indexnoise = 0; + sbr->data[1].f_indexnoise = 0; + + return 0; +} + +static av_always_inline void get_bits1_vector(GetBitContext *gb, uint8_t *vec, + int elements) +{ + int i; + for (i = 0; i < elements; i++) { + vec[i] = get_bits1(gb); + } +} + +/** ceil(log2(index+1)) */ +static const int8_t ceil_log2[] = { + 0, 1, 2, 2, 3, 3, +}; + +static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, SBRData *ch_data) +{ + int i; + unsigned bs_pointer = 0; + // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots + int abs_bord_trail = 16; + int num_rel_lead, num_rel_trail; + unsigned bs_num_env_old = ch_data->bs_num_env; + + ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env]; + ch_data->bs_amp_res = sbr->bs_amp_res_header; + ch_data->t_env_num_env_old = ch_data->t_env[bs_num_env_old]; + + switch (ch_data->bs_frame_class = get_bits(gb, 2)) { + case FIXFIX: + ch_data->bs_num_env = 1 << get_bits(gb, 2); + num_rel_lead = ch_data->bs_num_env - 1; + if (ch_data->bs_num_env == 1) + ch_data->bs_amp_res = 0; + + if (ch_data->bs_num_env > 4) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n", + ch_data->bs_num_env); + return -1; + } + + ch_data->t_env[0] = 0; + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + abs_bord_trail = (abs_bord_trail + (ch_data->bs_num_env >> 1)) / + ch_data->bs_num_env; + for (i = 0; i < num_rel_lead; i++) + ch_data->t_env[i + 1] = ch_data->t_env[i] + abs_bord_trail; + + ch_data->bs_freq_res[1] = get_bits1(gb); + for (i = 1; i < ch_data->bs_num_env; i++) + ch_data->bs_freq_res[i + 1] = ch_data->bs_freq_res[1]; + break; + case FIXVAR: + abs_bord_trail += get_bits(gb, 2); + num_rel_trail = get_bits(gb, 2); + ch_data->bs_num_env = num_rel_trail + 1; + ch_data->t_env[0] = 0; + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + for (i = 0; i < num_rel_trail; i++) + ch_data->t_env[ch_data->bs_num_env - 1 - i] = + ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2; + + bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); + + for (i = 0; i < ch_data->bs_num_env; i++) + ch_data->bs_freq_res[ch_data->bs_num_env - i] = get_bits1(gb); + break; + case VARFIX: + ch_data->t_env[0] = get_bits(gb, 2); + num_rel_lead = get_bits(gb, 2); + ch_data->bs_num_env = num_rel_lead + 1; + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + for (i = 0; i < num_rel_lead; i++) + ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2; + + bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); + + get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env); + break; + case VARVAR: + ch_data->t_env[0] = get_bits(gb, 2); + abs_bord_trail += get_bits(gb, 2); + num_rel_lead = get_bits(gb, 2); + num_rel_trail = get_bits(gb, 2); + ch_data->bs_num_env = num_rel_lead + num_rel_trail + 1; + + if (ch_data->bs_num_env > 5) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n", + ch_data->bs_num_env); + return -1; + } + + ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail; + + for (i = 0; i < num_rel_lead; i++) + ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2; + for (i = 0; i < num_rel_trail; i++) + ch_data->t_env[ch_data->bs_num_env - 1 - i] = + ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2; + + bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]); + + get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env); + break; + } + + if (bs_pointer > ch_data->bs_num_env + 1) { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream, bs_pointer points to a middle noise border outside the time borders table: %d\n", + bs_pointer); + return -1; + } + + for (i = 1; i <= ch_data->bs_num_env; i++) { + if (ch_data->t_env[i-1] > ch_data->t_env[i]) { + av_log(ac->avctx, AV_LOG_ERROR, "Non monotone time borders\n"); + return -1; + } + } + + ch_data->bs_num_noise = (ch_data->bs_num_env > 1) + 1; + + ch_data->t_q[0] = ch_data->t_env[0]; + ch_data->t_q[ch_data->bs_num_noise] = ch_data->t_env[ch_data->bs_num_env]; + if (ch_data->bs_num_noise > 1) { + unsigned int idx; + if (ch_data->bs_frame_class == FIXFIX) { + idx = ch_data->bs_num_env >> 1; + } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR + idx = ch_data->bs_num_env - FFMAX((int)bs_pointer - 1, 1); + } else { // VARFIX + if (!bs_pointer) + idx = 1; + else if (bs_pointer == 1) + idx = ch_data->bs_num_env - 1; + else // bs_pointer > 1 + idx = bs_pointer - 1; + } + ch_data->t_q[1] = ch_data->t_env[idx]; + } + + ch_data->e_a[0] = -(ch_data->e_a[1] != bs_num_env_old); // l_APrev + ch_data->e_a[1] = -1; + if ((ch_data->bs_frame_class & 1) && bs_pointer) { // FIXVAR or VARVAR and bs_pointer != 0 + ch_data->e_a[1] = ch_data->bs_num_env + 1 - bs_pointer; + } else if ((ch_data->bs_frame_class == 2) && (bs_pointer > 1)) // VARFIX and bs_pointer > 1 + ch_data->e_a[1] = bs_pointer - 1; + + return 0; +} + +static void copy_sbr_grid(SBRData *dst, const SBRData *src) { + //These variables are saved from the previous frame rather than copied + dst->bs_freq_res[0] = dst->bs_freq_res[dst->bs_num_env]; + dst->t_env_num_env_old = dst->t_env[dst->bs_num_env]; + dst->e_a[0] = -(dst->e_a[1] != dst->bs_num_env); + + //These variables are read from the bitstream and therefore copied + memcpy(dst->bs_freq_res+1, src->bs_freq_res+1, sizeof(dst->bs_freq_res)-sizeof(*dst->bs_freq_res)); + memcpy(dst->t_env, src->t_env, sizeof(dst->t_env)); + memcpy(dst->t_q, src->t_q, sizeof(dst->t_q)); + dst->bs_num_env = src->bs_num_env; + dst->bs_amp_res = src->bs_amp_res; + dst->bs_num_noise = src->bs_num_noise; + dst->bs_frame_class = src->bs_frame_class; + dst->e_a[1] = src->e_a[1]; +} + +/// Read how the envelope and noise floor data is delta coded +static void read_sbr_dtdf(SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data) +{ + get_bits1_vector(gb, ch_data->bs_df_env, ch_data->bs_num_env); + get_bits1_vector(gb, ch_data->bs_df_noise, ch_data->bs_num_noise); +} + +/// Read inverse filtering data +static void read_sbr_invf(SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data) +{ + int i; + + memcpy(ch_data->bs_invf_mode[1], ch_data->bs_invf_mode[0], 5 * sizeof(uint8_t)); + for (i = 0; i < sbr->n_q; i++) + ch_data->bs_invf_mode[0][i] = get_bits(gb, 2); +} + +static void read_sbr_envelope(SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data, int ch) +{ + int bits; + int i, j, k; + VLC_TYPE (*t_huff)[2], (*f_huff)[2]; + int t_lav, f_lav; + const int delta = (ch == 1 && sbr->bs_coupling == 1) + 1; + const int odd = sbr->n[1] & 1; + + if (sbr->bs_coupling && ch) { + if (ch_data->bs_amp_res) { + bits = 5; + t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB]; + } else { + bits = 6; + t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_1_5DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_1_5DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_1_5DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_1_5DB]; + } + } else { + if (ch_data->bs_amp_res) { + bits = 6; + t_huff = vlc_sbr[T_HUFFMAN_ENV_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB]; + } else { + bits = 7; + t_huff = vlc_sbr[T_HUFFMAN_ENV_1_5DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_1_5DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_1_5DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_1_5DB]; + } + } + + for (i = 0; i < ch_data->bs_num_env; i++) { + if (ch_data->bs_df_env[i]) { + // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame + if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) { + for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) + ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); + } else if (ch_data->bs_freq_res[i + 1]) { + for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { + k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1] + ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); + } + } else { + for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) { + k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j] + ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav); + } + } + } else { + ch_data->env_facs[i + 1][0] = delta * get_bits(gb, bits); // bs_env_start_value_balance + for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) + ch_data->env_facs[i + 1][j] = ch_data->env_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav); + } + } + + //assign 0th elements of env_facs from last elements + memcpy(ch_data->env_facs[0], ch_data->env_facs[ch_data->bs_num_env], + sizeof(ch_data->env_facs[0])); +} + +static void read_sbr_noise(SpectralBandReplication *sbr, GetBitContext *gb, + SBRData *ch_data, int ch) +{ + int i, j; + VLC_TYPE (*t_huff)[2], (*f_huff)[2]; + int t_lav, f_lav; + int delta = (ch == 1 && sbr->bs_coupling == 1) + 1; + + if (sbr->bs_coupling && ch) { + t_huff = vlc_sbr[T_HUFFMAN_NOISE_BAL_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_BAL_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB]; + } else { + t_huff = vlc_sbr[T_HUFFMAN_NOISE_3_0DB].table; + t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_3_0DB]; + f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table; + f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB]; + } + + for (i = 0; i < ch_data->bs_num_noise; i++) { + if (ch_data->bs_df_noise[i]) { + for (j = 0; j < sbr->n_q; j++) + ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav); + } else { + ch_data->noise_facs[i + 1][0] = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level + for (j = 1; j < sbr->n_q; j++) + ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav); + } + } + + //assign 0th elements of noise_facs from last elements + memcpy(ch_data->noise_facs[0], ch_data->noise_facs[ch_data->bs_num_noise], + sizeof(ch_data->noise_facs[0])); +} + +static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, + int bs_extension_id, int *num_bits_left) +{ + switch (bs_extension_id) { + case EXTENSION_ID_PS: + if (!ac->oc[1].m4ac.ps) { + av_log(ac->avctx, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n"); + skip_bits_long(gb, *num_bits_left); // bs_fill_bits + *num_bits_left = 0; + } else { +#if 1 + *num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left); +#else + avpriv_report_missing_feature(ac->avctx, "Parametric Stereo"); + skip_bits_long(gb, *num_bits_left); // bs_fill_bits + *num_bits_left = 0; +#endif + } + break; + default: + // some files contain 0-padding + if (bs_extension_id || *num_bits_left > 16 || show_bits(gb, *num_bits_left)) + avpriv_request_sample(ac->avctx, "Reserved SBR extensions"); + skip_bits_long(gb, *num_bits_left); // bs_fill_bits + *num_bits_left = 0; + break; + } +} + +static int read_sbr_single_channel_element(AACContext *ac, + SpectralBandReplication *sbr, + GetBitContext *gb) +{ + if (get_bits1(gb)) // bs_data_extra + skip_bits(gb, 4); // bs_reserved + + if (read_sbr_grid(ac, sbr, gb, &sbr->data[0])) + return -1; + read_sbr_dtdf(sbr, gb, &sbr->data[0]); + read_sbr_invf(sbr, gb, &sbr->data[0]); + read_sbr_envelope(sbr, gb, &sbr->data[0], 0); + read_sbr_noise(sbr, gb, &sbr->data[0], 0); + + if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb))) + get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]); + + return 0; +} + +static int read_sbr_channel_pair_element(AACContext *ac, + SpectralBandReplication *sbr, + GetBitContext *gb) +{ + if (get_bits1(gb)) // bs_data_extra + skip_bits(gb, 8); // bs_reserved + + if ((sbr->bs_coupling = get_bits1(gb))) { + if (read_sbr_grid(ac, sbr, gb, &sbr->data[0])) + return -1; + copy_sbr_grid(&sbr->data[1], &sbr->data[0]); + read_sbr_dtdf(sbr, gb, &sbr->data[0]); + read_sbr_dtdf(sbr, gb, &sbr->data[1]); + read_sbr_invf(sbr, gb, &sbr->data[0]); + memcpy(sbr->data[1].bs_invf_mode[1], sbr->data[1].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0])); + memcpy(sbr->data[1].bs_invf_mode[0], sbr->data[0].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0])); + read_sbr_envelope(sbr, gb, &sbr->data[0], 0); + read_sbr_noise(sbr, gb, &sbr->data[0], 0); + read_sbr_envelope(sbr, gb, &sbr->data[1], 1); + read_sbr_noise(sbr, gb, &sbr->data[1], 1); + } else { + if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) || + read_sbr_grid(ac, sbr, gb, &sbr->data[1])) + return -1; + read_sbr_dtdf(sbr, gb, &sbr->data[0]); + read_sbr_dtdf(sbr, gb, &sbr->data[1]); + read_sbr_invf(sbr, gb, &sbr->data[0]); + read_sbr_invf(sbr, gb, &sbr->data[1]); + read_sbr_envelope(sbr, gb, &sbr->data[0], 0); + read_sbr_envelope(sbr, gb, &sbr->data[1], 1); + read_sbr_noise(sbr, gb, &sbr->data[0], 0); + read_sbr_noise(sbr, gb, &sbr->data[1], 1); + } + + if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb))) + get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]); + if ((sbr->data[1].bs_add_harmonic_flag = get_bits1(gb))) + get_bits1_vector(gb, sbr->data[1].bs_add_harmonic, sbr->n[1]); + + return 0; +} + +static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, int id_aac) +{ + unsigned int cnt = get_bits_count(gb); + + if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) { + if (read_sbr_single_channel_element(ac, sbr, gb)) { + sbr_turnoff(sbr); + return get_bits_count(gb) - cnt; + } + } else if (id_aac == TYPE_CPE) { + if (read_sbr_channel_pair_element(ac, sbr, gb)) { + sbr_turnoff(sbr); + return get_bits_count(gb) - cnt; + } + } else { + av_log(ac->avctx, AV_LOG_ERROR, + "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac); + sbr_turnoff(sbr); + return get_bits_count(gb) - cnt; + } + if (get_bits1(gb)) { // bs_extended_data + int num_bits_left = get_bits(gb, 4); // bs_extension_size + if (num_bits_left == 15) + num_bits_left += get_bits(gb, 8); // bs_esc_count + + num_bits_left <<= 3; + while (num_bits_left > 7) { + num_bits_left -= 2; + read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), &num_bits_left); // bs_extension_id + } + if (num_bits_left < 0) { + av_log(ac->avctx, AV_LOG_ERROR, "SBR Extension over read.\n"); + } + if (num_bits_left > 0) + skip_bits(gb, num_bits_left); + } + + return get_bits_count(gb) - cnt; +} + +static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr) +{ + int err; + err = sbr_make_f_master(ac, sbr, &sbr->spectrum_params); + if (err >= 0) + err = sbr_make_f_derived(ac, sbr); + if (err < 0) { + av_log(ac->avctx, AV_LOG_ERROR, + "SBR reset failed. Switching SBR to pure upsampling mode.\n"); + sbr_turnoff(sbr); + } +} + +/** + * Decode Spectral Band Replication extension data; reference: table 4.55. + * + * @param crc flag indicating the presence of CRC checksum + * @param cnt length of TYPE_FIL syntactic element in bytes + * + * @return Returns number of bytes consumed from the TYPE_FIL element. + */ +int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb_host, int crc, int cnt, int id_aac) +{ + unsigned int num_sbr_bits = 0, num_align_bits; + unsigned bytes_read; + GetBitContext gbc = *gb_host, *gb = &gbc; + skip_bits_long(gb_host, cnt*8 - 4); + + sbr->reset = 0; + + if (!sbr->sample_rate) + sbr->sample_rate = 2 * ac->oc[1].m4ac.sample_rate; //TODO use the nominal sample rate for arbitrary sample rate support + if (!ac->oc[1].m4ac.ext_sample_rate) + ac->oc[1].m4ac.ext_sample_rate = 2 * ac->oc[1].m4ac.sample_rate; + + if (crc) { + skip_bits(gb, 10); // bs_sbr_crc_bits; TODO - implement CRC check + num_sbr_bits += 10; + } + + //Save some state from the previous frame. + sbr->kx[0] = sbr->kx[1]; + sbr->m[0] = sbr->m[1]; + sbr->kx_and_m_pushed = 1; + + num_sbr_bits++; + if (get_bits1(gb)) // bs_header_flag + num_sbr_bits += read_sbr_header(sbr, gb); + + if (sbr->reset) + sbr_reset(ac, sbr); + + if (sbr->start) + num_sbr_bits += read_sbr_data(ac, sbr, gb, id_aac); + + num_align_bits = ((cnt << 3) - 4 - num_sbr_bits) & 7; + bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3); + + if (bytes_read > cnt) { + av_log(ac->avctx, AV_LOG_ERROR, + "Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read); + } + return cnt; +} + +/// Dequantization and stereo decoding (14496-3 sp04 p203) +static void sbr_dequant(SpectralBandReplication *sbr, int id_aac) +{ + int k, e; + int ch; + + if (id_aac == TYPE_CPE && sbr->bs_coupling) { + float alpha = sbr->data[0].bs_amp_res ? 1.0f : 0.5f; + float pan_offset = sbr->data[0].bs_amp_res ? 12.0f : 24.0f; + for (e = 1; e <= sbr->data[0].bs_num_env; e++) { + for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) { + float temp1 = exp2f(sbr->data[0].env_facs[e][k] * alpha + 7.0f); + float temp2 = exp2f((pan_offset - sbr->data[1].env_facs[e][k]) * alpha); + float fac; + if (temp1 > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + temp1 = 1; + } + fac = temp1 / (1.0f + temp2); + sbr->data[0].env_facs[e][k] = fac; + sbr->data[1].env_facs[e][k] = fac * temp2; + } + } + for (e = 1; e <= sbr->data[0].bs_num_noise; e++) { + for (k = 0; k < sbr->n_q; k++) { + float temp1 = exp2f(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs[e][k] + 1); + float temp2 = exp2f(12 - sbr->data[1].noise_facs[e][k]); + float fac; + if (temp1 > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + temp1 = 1; + } + fac = temp1 / (1.0f + temp2); + sbr->data[0].noise_facs[e][k] = fac; + sbr->data[1].noise_facs[e][k] = fac * temp2; + } + } + } else { // SCE or one non-coupled CPE + for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) { + float alpha = sbr->data[ch].bs_amp_res ? 1.0f : 0.5f; + for (e = 1; e <= sbr->data[ch].bs_num_env; e++) + for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){ + sbr->data[ch].env_facs[e][k] = + exp2f(alpha * sbr->data[ch].env_facs[e][k] + 6.0f); + if (sbr->data[ch].env_facs[e][k] > 1E20) { + av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n"); + sbr->data[ch].env_facs[e][k] = 1; + } + } + + for (e = 1; e <= sbr->data[ch].bs_num_noise; e++) + for (k = 0; k < sbr->n_q; k++) + sbr->data[ch].noise_facs[e][k] = + exp2f(NOISE_FLOOR_OFFSET - sbr->data[ch].noise_facs[e][k]); + } + } +} + +/** + * Analysis QMF Bank (14496-3 sp04 p206) + * + * @param x pointer to the beginning of the first sample window + * @param W array of complex-valued samples split into subbands + */ +#ifndef sbr_qmf_analysis +static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct, + SBRDSPContext *sbrdsp, const float *in, float *x, + float z[320], float W[2][32][32][2], int buf_idx) +{ + int i; + memcpy(x , x+1024, (320-32)*sizeof(x[0])); + memcpy(x+288, in, 1024*sizeof(x[0])); + for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames + // are not supported + dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320); + sbrdsp->sum64x5(z); + sbrdsp->qmf_pre_shuffle(z); + mdct->imdct_half(mdct, z, z+64); + sbrdsp->qmf_post_shuffle(W[buf_idx][i], z); + x += 32; + } +} +#endif + +/** + * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank + * (14496-3 sp04 p206) + */ +#ifndef sbr_qmf_synthesis +static void sbr_qmf_synthesis(FFTContext *mdct, + SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp, + float *out, float X[2][38][64], + float mdct_buf[2][64], + float *v0, int *v_off, const unsigned int div) +{ + int i, n; + const float *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us; + const int step = 128 >> div; + float *v; + for (i = 0; i < 32; i++) { + if (*v_off < step) { + int saved_samples = (1280 - 128) >> div; + memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(float)); + *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step; + } else { + *v_off -= step; + } + v = v0 + *v_off; + if (div) { + for (n = 0; n < 32; n++) { + X[0][i][ n] = -X[0][i][n]; + X[0][i][32+n] = X[1][i][31-n]; + } + mdct->imdct_half(mdct, mdct_buf[0], X[0][i]); + sbrdsp->qmf_deint_neg(v, mdct_buf[0]); + } else { + sbrdsp->neg_odd_64(X[1][i]); + mdct->imdct_half(mdct, mdct_buf[0], X[0][i]); + mdct->imdct_half(mdct, mdct_buf[1], X[1][i]); + sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]); + } + dsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div); + dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out , 64 >> div); + dsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out , 64 >> div); + out += 64 >> div; + } +} +#endif + +/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering + * (14496-3 sp04 p214) + * Warning: This routine does not seem numerically stable. + */ +static void sbr_hf_inverse_filter(SBRDSPContext *dsp, + float (*alpha0)[2], float (*alpha1)[2], + const float X_low[32][40][2], int k0) +{ + int k; + for (k = 0; k < k0; k++) { + LOCAL_ALIGNED_16(float, phi, [3], [2][2]); + float dk; + + dsp->autocorrelate(X_low[k], phi); + + dk = phi[2][1][0] * phi[1][0][0] - + (phi[1][1][0] * phi[1][1][0] + phi[1][1][1] * phi[1][1][1]) / 1.000001f; + + if (!dk) { + alpha1[k][0] = 0; + alpha1[k][1] = 0; + } else { + float temp_real, temp_im; + temp_real = phi[0][0][0] * phi[1][1][0] - + phi[0][0][1] * phi[1][1][1] - + phi[0][1][0] * phi[1][0][0]; + temp_im = phi[0][0][0] * phi[1][1][1] + + phi[0][0][1] * phi[1][1][0] - + phi[0][1][1] * phi[1][0][0]; + + alpha1[k][0] = temp_real / dk; + alpha1[k][1] = temp_im / dk; + } + + if (!phi[1][0][0]) { + alpha0[k][0] = 0; + alpha0[k][1] = 0; + } else { + float temp_real, temp_im; + temp_real = phi[0][0][0] + alpha1[k][0] * phi[1][1][0] + + alpha1[k][1] * phi[1][1][1]; + temp_im = phi[0][0][1] + alpha1[k][1] * phi[1][1][0] - + alpha1[k][0] * phi[1][1][1]; + + alpha0[k][0] = -temp_real / phi[1][0][0]; + alpha0[k][1] = -temp_im / phi[1][0][0]; + } + + if (alpha1[k][0] * alpha1[k][0] + alpha1[k][1] * alpha1[k][1] >= 16.0f || + alpha0[k][0] * alpha0[k][0] + alpha0[k][1] * alpha0[k][1] >= 16.0f) { + alpha1[k][0] = 0; + alpha1[k][1] = 0; + alpha0[k][0] = 0; + alpha0[k][1] = 0; + } + } +} + +/// Chirp Factors (14496-3 sp04 p214) +static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data) +{ + int i; + float new_bw; + static const float bw_tab[] = { 0.0f, 0.75f, 0.9f, 0.98f }; + + for (i = 0; i < sbr->n_q; i++) { + if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1) { + new_bw = 0.6f; + } else + new_bw = bw_tab[ch_data->bs_invf_mode[0][i]]; + + if (new_bw < ch_data->bw_array[i]) { + new_bw = 0.75f * new_bw + 0.25f * ch_data->bw_array[i]; + } else + new_bw = 0.90625f * new_bw + 0.09375f * ch_data->bw_array[i]; + ch_data->bw_array[i] = new_bw < 0.015625f ? 0.0f : new_bw; + } +} + +/// Generate the subband filtered lowband +static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr, + float X_low[32][40][2], const float W[2][32][32][2], + int buf_idx) +{ + int i, k; + const int t_HFGen = 8; + const int i_f = 32; + memset(X_low, 0, 32*sizeof(*X_low)); + for (k = 0; k < sbr->kx[1]; k++) { + for (i = t_HFGen; i < i_f + t_HFGen; i++) { + X_low[k][i][0] = W[buf_idx][i - t_HFGen][k][0]; + X_low[k][i][1] = W[buf_idx][i - t_HFGen][k][1]; + } + } + buf_idx = 1-buf_idx; + for (k = 0; k < sbr->kx[0]; k++) { + for (i = 0; i < t_HFGen; i++) { + X_low[k][i][0] = W[buf_idx][i + i_f - t_HFGen][k][0]; + X_low[k][i][1] = W[buf_idx][i + i_f - t_HFGen][k][1]; + } + } + return 0; +} + +/// High Frequency Generator (14496-3 sp04 p215) +static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr, + float X_high[64][40][2], const float X_low[32][40][2], + const float (*alpha0)[2], const float (*alpha1)[2], + const float bw_array[5], const uint8_t *t_env, + int bs_num_env) +{ + int j, x; + int g = 0; + int k = sbr->kx[1]; + for (j = 0; j < sbr->num_patches; j++) { + for (x = 0; x < sbr->patch_num_subbands[j]; x++, k++) { + const int p = sbr->patch_start_subband[j] + x; + while (g <= sbr->n_q && k >= sbr->f_tablenoise[g]) + g++; + g--; + + if (g < 0) { + av_log(ac->avctx, AV_LOG_ERROR, + "ERROR : no subband found for frequency %d\n", k); + return -1; + } + + sbr->dsp.hf_gen(X_high[k] + ENVELOPE_ADJUSTMENT_OFFSET, + X_low[p] + ENVELOPE_ADJUSTMENT_OFFSET, + alpha0[p], alpha1[p], bw_array[g], + 2 * t_env[0], 2 * t_env[bs_num_env]); + } + } + if (k < sbr->m[1] + sbr->kx[1]) + memset(X_high + k, 0, (sbr->m[1] + sbr->kx[1] - k) * sizeof(*X_high)); + + return 0; +} + +/// Generate the subband filtered lowband +static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64], + const float Y0[38][64][2], const float Y1[38][64][2], + const float X_low[32][40][2], int ch) +{ + int k, i; + const int i_f = 32; + const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0); + memset(X, 0, 2*sizeof(*X)); + for (k = 0; k < sbr->kx[0]; k++) { + for (i = 0; i < i_Temp; i++) { + X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0]; + X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1]; + } + } + for (; k < sbr->kx[0] + sbr->m[0]; k++) { + for (i = 0; i < i_Temp; i++) { + X[0][i][k] = Y0[i + i_f][k][0]; + X[1][i][k] = Y0[i + i_f][k][1]; + } + } + + for (k = 0; k < sbr->kx[1]; k++) { + for (i = i_Temp; i < 38; i++) { + X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0]; + X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1]; + } + } + for (; k < sbr->kx[1] + sbr->m[1]; k++) { + for (i = i_Temp; i < i_f; i++) { + X[0][i][k] = Y1[i][k][0]; + X[1][i][k] = Y1[i][k][1]; + } + } + return 0; +} + +/** High Frequency Adjustment (14496-3 sp04 p217) and Mapping + * (14496-3 sp04 p217) + */ +static int sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, + SBRData *ch_data, int e_a[2]) +{ + int e, i, m; + + memset(ch_data->s_indexmapped[1], 0, 7*sizeof(ch_data->s_indexmapped[1])); + for (e = 0; e < ch_data->bs_num_env; e++) { + const unsigned int ilim = sbr->n[ch_data->bs_freq_res[e + 1]]; + uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; + int k; + + if (sbr->kx[1] != table[0]) { + av_log(ac->avctx, AV_LOG_ERROR, "kx != f_table{high,low}[0]. " + "Derived frequency tables were not regenerated.\n"); + sbr_turnoff(sbr); + return AVERROR_BUG; + } + for (i = 0; i < ilim; i++) + for (m = table[i]; m < table[i + 1]; m++) + sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; + + // ch_data->bs_num_noise > 1 => 2 noise floors + k = (ch_data->bs_num_noise > 1) && (ch_data->t_env[e] >= ch_data->t_q[1]); + for (i = 0; i < sbr->n_q; i++) + for (m = sbr->f_tablenoise[i]; m < sbr->f_tablenoise[i + 1]; m++) + sbr->q_mapped[e][m - sbr->kx[1]] = ch_data->noise_facs[k+1][i]; + + for (i = 0; i < sbr->n[1]; i++) { + if (ch_data->bs_add_harmonic_flag) { + const unsigned int m_midpoint = + (sbr->f_tablehigh[i] + sbr->f_tablehigh[i + 1]) >> 1; + + ch_data->s_indexmapped[e + 1][m_midpoint - sbr->kx[1]] = ch_data->bs_add_harmonic[i] * + (e >= e_a[1] || (ch_data->s_indexmapped[0][m_midpoint - sbr->kx[1]] == 1)); + } + } + + for (i = 0; i < ilim; i++) { + int additional_sinusoid_present = 0; + for (m = table[i]; m < table[i + 1]; m++) { + if (ch_data->s_indexmapped[e + 1][m - sbr->kx[1]]) { + additional_sinusoid_present = 1; + break; + } + } + memset(&sbr->s_mapped[e][table[i] - sbr->kx[1]], additional_sinusoid_present, + (table[i + 1] - table[i]) * sizeof(sbr->s_mapped[e][0])); + } + } + + memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0])); + return 0; +} + +/// Estimation of current envelope (14496-3 sp04 p218) +static void sbr_env_estimate(float (*e_curr)[48], float X_high[64][40][2], + SpectralBandReplication *sbr, SBRData *ch_data) +{ + int e, m; + int kx1 = sbr->kx[1]; + + if (sbr->bs_interpol_freq) { + for (e = 0; e < ch_data->bs_num_env; e++) { + const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]); + int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + + for (m = 0; m < sbr->m[1]; m++) { + float sum = sbr->dsp.sum_square(X_high[m+kx1] + ilb, iub - ilb); + e_curr[e][m] = sum * recip_env_size; + } + } + } else { + int k, p; + + for (e = 0; e < ch_data->bs_num_env; e++) { + const int env_size = 2 * (ch_data->t_env[e + 1] - ch_data->t_env[e]); + int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET; + const uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; + + for (p = 0; p < sbr->n[ch_data->bs_freq_res[e + 1]]; p++) { + float sum = 0.0f; + const int den = env_size * (table[p + 1] - table[p]); + + for (k = table[p]; k < table[p + 1]; k++) { + sum += sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb); + } + sum /= den; + for (k = table[p]; k < table[p + 1]; k++) { + e_curr[e][k - kx1] = sum; + } + } + } + } +} + +/** + * Calculation of levels of additional HF signal components (14496-3 sp04 p219) + * and Calculation of gain (14496-3 sp04 p219) + */ +static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr, + SBRData *ch_data, const int e_a[2]) +{ + int e, k, m; + // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off) + static const float limgain[4] = { 0.70795, 1.0, 1.41254, 10000000000 }; + + for (e = 0; e < ch_data->bs_num_env; e++) { + int delta = !((e == e_a[1]) || (e == e_a[0])); + for (k = 0; k < sbr->n_lim; k++) { + float gain_boost, gain_max; + float sum[2] = { 0.0f, 0.0f }; + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + const float temp = sbr->e_origmapped[e][m] / (1.0f + sbr->q_mapped[e][m]); + sbr->q_m[e][m] = sqrtf(temp * sbr->q_mapped[e][m]); + sbr->s_m[e][m] = sqrtf(temp * ch_data->s_indexmapped[e + 1][m]); + if (!sbr->s_mapped[e][m]) { + sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] / + ((1.0f + sbr->e_curr[e][m]) * + (1.0f + sbr->q_mapped[e][m] * delta))); + } else { + sbr->gain[e][m] = sqrtf(sbr->e_origmapped[e][m] * sbr->q_mapped[e][m] / + ((1.0f + sbr->e_curr[e][m]) * + (1.0f + sbr->q_mapped[e][m]))); + } + } + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sum[0] += sbr->e_origmapped[e][m]; + sum[1] += sbr->e_curr[e][m]; + } + gain_max = limgain[sbr->bs_limiter_gains] * sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); + gain_max = FFMIN(100000.f, gain_max); + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + float q_m_max = sbr->q_m[e][m] * gain_max / sbr->gain[e][m]; + sbr->q_m[e][m] = FFMIN(sbr->q_m[e][m], q_m_max); + sbr->gain[e][m] = FFMIN(sbr->gain[e][m], gain_max); + } + sum[0] = sum[1] = 0.0f; + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sum[0] += sbr->e_origmapped[e][m]; + sum[1] += sbr->e_curr[e][m] * sbr->gain[e][m] * sbr->gain[e][m] + + sbr->s_m[e][m] * sbr->s_m[e][m] + + (delta && !sbr->s_m[e][m]) * sbr->q_m[e][m] * sbr->q_m[e][m]; + } + gain_boost = sqrtf((FLT_EPSILON + sum[0]) / (FLT_EPSILON + sum[1])); + gain_boost = FFMIN(1.584893192f, gain_boost); + for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) { + sbr->gain[e][m] *= gain_boost; + sbr->q_m[e][m] *= gain_boost; + sbr->s_m[e][m] *= gain_boost; + } + } + } +} + +/// Assembling HF Signals (14496-3 sp04 p220) +static void sbr_hf_assemble(float Y1[38][64][2], + const float X_high[64][40][2], + SpectralBandReplication *sbr, SBRData *ch_data, + const int e_a[2]) +{ + int e, i, j, m; + const int h_SL = 4 * !sbr->bs_smoothing_mode; + const int kx = sbr->kx[1]; + const int m_max = sbr->m[1]; + static const float h_smooth[5] = { + 0.33333333333333, + 0.30150283239582, + 0.21816949906249, + 0.11516383427084, + 0.03183050093751, + }; + float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp; + int indexnoise = ch_data->f_indexnoise; + int indexsine = ch_data->f_indexsine; + + if (sbr->reset) { + for (i = 0; i < h_SL; i++) { + memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0])); + memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0])); + } + } else if (h_SL) { + memcpy(g_temp[2*ch_data->t_env[0]], g_temp[2*ch_data->t_env_num_env_old], 4*sizeof(g_temp[0])); + memcpy(q_temp[2*ch_data->t_env[0]], q_temp[2*ch_data->t_env_num_env_old], 4*sizeof(q_temp[0])); + } + + for (e = 0; e < ch_data->bs_num_env; e++) { + for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { + memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0])); + memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0])); + } + } + + for (e = 0; e < ch_data->bs_num_env; e++) { + for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) { + LOCAL_ALIGNED_16(float, g_filt_tab, [48]); + LOCAL_ALIGNED_16(float, q_filt_tab, [48]); + float *g_filt, *q_filt; + + if (h_SL && e != e_a[0] && e != e_a[1]) { + g_filt = g_filt_tab; + q_filt = q_filt_tab; + for (m = 0; m < m_max; m++) { + const int idx1 = i + h_SL; + g_filt[m] = 0.0f; + q_filt[m] = 0.0f; + for (j = 0; j <= h_SL; j++) { + g_filt[m] += g_temp[idx1 - j][m] * h_smooth[j]; + q_filt[m] += q_temp[idx1 - j][m] * h_smooth[j]; + } + } + } else { + g_filt = g_temp[i + h_SL]; + q_filt = q_temp[i]; + } + + sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max, + i + ENVELOPE_ADJUSTMENT_OFFSET); + + if (e != e_a[0] && e != e_a[1]) { + sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e], + q_filt, indexnoise, + kx, m_max); + } else { + int idx = indexsine&1; + int A = (1-((indexsine+(kx & 1))&2)); + int B = (A^(-idx)) + idx; + float *out = &Y1[i][kx][idx]; + float *in = sbr->s_m[e]; + for (m = 0; m+1 < m_max; m+=2) { + out[2*m ] += in[m ] * A; + out[2*m+2] += in[m+1] * B; + } + if(m_max&1) + out[2*m ] += in[m ] * A; + } + indexnoise = (indexnoise + m_max) & 0x1ff; + indexsine = (indexsine + 1) & 3; + } + } + ch_data->f_indexnoise = indexnoise; + ch_data->f_indexsine = indexsine; +} + +void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, + float* L, float* R) +{ + int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate; + int ch; + int nch = (id_aac == TYPE_CPE) ? 2 : 1; + int err; + + if (!sbr->kx_and_m_pushed) { + sbr->kx[0] = sbr->kx[1]; + sbr->m[0] = sbr->m[1]; + } else { + sbr->kx_and_m_pushed = 0; + } + + if (sbr->start) { + sbr_dequant(sbr, id_aac); + } + for (ch = 0; ch < nch; ch++) { + /* decode channel */ + sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, + (float*)sbr->qmf_filter_scratch, + sbr->data[ch].W, sbr->data[ch].Ypos); + sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos); + sbr->data[ch].Ypos ^= 1; + if (sbr->start) { + sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); + sbr_chirp(sbr, &sbr->data[ch]); + sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1, + sbr->data[ch].bw_array, sbr->data[ch].t_env, + sbr->data[ch].bs_num_env); + + // hf_adj + err = sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); + if (!err) { + sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]); + sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); + sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos], + sbr->X_high, sbr, &sbr->data[ch], + sbr->data[ch].e_a); + } + } + + /* synthesis */ + sbr->c.sbr_x_gen(sbr, sbr->X[ch], + sbr->data[ch].Y[1-sbr->data[ch].Ypos], + sbr->data[ch].Y[ sbr->data[ch].Ypos], + sbr->X_low, ch); + } + + if (ac->oc[1].m4ac.ps == 1) { + if (sbr->ps.start) { + ff_ps_apply(ac->avctx, &sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]); + } else { + memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0])); + } + nch = 2; + } + + sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp, + L, sbr->X[0], sbr->qmf_filter_scratch, + sbr->data[0].synthesis_filterbank_samples, + &sbr->data[0].synthesis_filterbank_samples_offset, + downsampled); + if (nch == 2) + sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp, + R, sbr->X[1], sbr->qmf_filter_scratch, + sbr->data[1].synthesis_filterbank_samples, + &sbr->data[1].synthesis_filterbank_samples_offset, + downsampled); +} + +static void aacsbr_func_ptr_init(AACSBRContext *c) +{ + c->sbr_lf_gen = sbr_lf_gen; + c->sbr_hf_assemble = sbr_hf_assemble; + c->sbr_x_gen = sbr_x_gen; + c->sbr_hf_inverse_filter = sbr_hf_inverse_filter; + + if(ARCH_MIPS) + ff_aacsbr_func_ptr_init_mips(c); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbr.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbr.h new file mode 100644 index 000000000..f5e33ab68 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbr.h @@ -0,0 +1,51 @@ +/* + * AAC Spectral Band Replication function declarations + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication function declarations + * @author Robert Swain ( rob opendot cl ) + */ + +#ifndef AVCODEC_AACSBR_H +#define AVCODEC_AACSBR_H + +#include "get_bits.h" +#include "aac.h" +#include "sbr.h" + +/** Initialize SBR. */ +void ff_aac_sbr_init(void); +/** Initialize one SBR context. */ +void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr); +/** Close one SBR context. */ +void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr); +/** Decode one SBR element. */ +int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, + GetBitContext *gb, int crc, int cnt, int id_aac); +/** Apply one SBR element to one AAC element. */ +void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, + float* L, float *R); + +void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c); + +#endif /* AVCODEC_AACSBR_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbrdata.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbrdata.h new file mode 100644 index 000000000..12575eeae --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacsbrdata.h @@ -0,0 +1,620 @@ +/* + * AAC Spectral Band Replication decoding data + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * AAC Spectral Band Replication decoding data + * @author Robert Swain ( rob opendot cl ) + */ + +#ifndef AVCODEC_AACSBRDATA_H +#define AVCODEC_AACSBRDATA_H + +#include +#include "libavutil/mem.h" + +///< Huffman tables for SBR + +static const uint8_t t_huffman_env_1_5dB_bits[121] = { + 18, 18, 18, 18, 18, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 17, 18, 16, 17, 18, 17, + 16, 16, 16, 16, 15, 14, 14, 13, + 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 12, 13, 14, + 14, 15, 16, 17, 16, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, +}; + +static const uint32_t t_huffman_env_1_5dB_codes[121] = { + 0x3ffd6, 0x3ffd7, 0x3ffd8, 0x3ffd9, 0x3ffda, 0x3ffdb, 0x7ffb8, 0x7ffb9, + 0x7ffba, 0x7ffbb, 0x7ffbc, 0x7ffbd, 0x7ffbe, 0x7ffbf, 0x7ffc0, 0x7ffc1, + 0x7ffc2, 0x7ffc3, 0x7ffc4, 0x7ffc5, 0x7ffc6, 0x7ffc7, 0x7ffc8, 0x7ffc9, + 0x7ffca, 0x7ffcb, 0x7ffcc, 0x7ffcd, 0x7ffce, 0x7ffcf, 0x7ffd0, 0x7ffd1, + 0x7ffd2, 0x7ffd3, 0x1ffe6, 0x3ffd4, 0x0fff0, 0x1ffe9, 0x3ffd5, 0x1ffe7, + 0x0fff1, 0x0ffec, 0x0ffed, 0x0ffee, 0x07ff4, 0x03ff9, 0x03ff7, 0x01ffa, + 0x01ff9, 0x00ffb, 0x007fc, 0x003fc, 0x001fd, 0x000fd, 0x0007d, 0x0003d, + 0x0001d, 0x0000d, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000c, 0x0001c, + 0x0003c, 0x0007c, 0x000fc, 0x001fc, 0x003fd, 0x00ffa, 0x01ff8, 0x03ff6, + 0x03ff8, 0x07ff5, 0x0ffef, 0x1ffe8, 0x0fff2, 0x7ffd4, 0x7ffd5, 0x7ffd6, + 0x7ffd7, 0x7ffd8, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, 0x7ffde, + 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffe6, + 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffec, 0x7ffed, 0x7ffee, + 0x7ffef, 0x7fff0, 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, + 0x7fff7, 0x7fff8, 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, + 0x7ffff, +}; + +static const uint8_t f_huffman_env_1_5dB_bits[121] = { + 19, 19, 20, 20, 20, 20, 20, 20, + 20, 19, 20, 20, 20, 20, 19, 20, + 19, 19, 20, 18, 20, 20, 20, 19, + 20, 20, 20, 19, 20, 19, 18, 19, + 18, 18, 17, 18, 17, 17, 17, 16, + 16, 16, 15, 15, 14, 13, 13, 12, + 12, 11, 10, 9, 9, 8, 7, 6, + 5, 4, 3, 2, 2, 3, 4, 5, + 6, 8, 8, 9, 10, 11, 11, 11, + 12, 12, 13, 13, 14, 14, 16, 16, + 17, 17, 18, 18, 18, 18, 18, 18, + 18, 20, 19, 20, 20, 20, 20, 20, + 20, 19, 20, 20, 20, 20, 19, 20, + 18, 20, 20, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, +}; + +static const uint32_t f_huffman_env_1_5dB_codes[121] = { + 0x7ffe7, 0x7ffe8, 0xfffd2, 0xfffd3, 0xfffd4, 0xfffd5, 0xfffd6, 0xfffd7, + 0xfffd8, 0x7ffda, 0xfffd9, 0xfffda, 0xfffdb, 0xfffdc, 0x7ffdb, 0xfffdd, + 0x7ffdc, 0x7ffdd, 0xfffde, 0x3ffe4, 0xfffdf, 0xfffe0, 0xfffe1, 0x7ffde, + 0xfffe2, 0xfffe3, 0xfffe4, 0x7ffdf, 0xfffe5, 0x7ffe0, 0x3ffe8, 0x7ffe1, + 0x3ffe0, 0x3ffe9, 0x1ffef, 0x3ffe5, 0x1ffec, 0x1ffed, 0x1ffee, 0x0fff4, + 0x0fff3, 0x0fff0, 0x07ff7, 0x07ff6, 0x03ffa, 0x01ffa, 0x01ff9, 0x00ffa, + 0x00ff8, 0x007f9, 0x003fb, 0x001fc, 0x001fa, 0x000fb, 0x0007c, 0x0003c, + 0x0001c, 0x0000c, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000d, 0x0001d, + 0x0003d, 0x000fa, 0x000fc, 0x001fb, 0x003fa, 0x007f8, 0x007fa, 0x007fb, + 0x00ff9, 0x00ffb, 0x01ff8, 0x01ffb, 0x03ff8, 0x03ff9, 0x0fff1, 0x0fff2, + 0x1ffea, 0x1ffeb, 0x3ffe1, 0x3ffe2, 0x3ffea, 0x3ffe3, 0x3ffe6, 0x3ffe7, + 0x3ffeb, 0xfffe6, 0x7ffe2, 0xfffe7, 0xfffe8, 0xfffe9, 0xfffea, 0xfffeb, + 0xfffec, 0x7ffe3, 0xfffed, 0xfffee, 0xfffef, 0xffff0, 0x7ffe4, 0xffff1, + 0x3ffec, 0xffff2, 0xffff3, 0x7ffe5, 0x7ffe6, 0xffff4, 0xffff5, 0xffff6, + 0xffff7, 0xffff8, 0xffff9, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, + 0xfffff, +}; + +static const uint8_t t_huffman_env_bal_1_5dB_bits[49] = { + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 12, 11, 9, 7, 5, 3, + 1, 2, 4, 6, 8, 11, 12, 15, + 16, 16, 16, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, +}; + +static const uint32_t t_huffman_env_bal_1_5dB_codes[49] = { + 0x0ffe4, 0x0ffe5, 0x0ffe6, 0x0ffe7, 0x0ffe8, 0x0ffe9, 0x0ffea, 0x0ffeb, + 0x0ffec, 0x0ffed, 0x0ffee, 0x0ffef, 0x0fff0, 0x0fff1, 0x0fff2, 0x0fff3, + 0x0fff4, 0x0ffe2, 0x00ffc, 0x007fc, 0x001fe, 0x0007e, 0x0001e, 0x00006, + 0x00000, 0x00002, 0x0000e, 0x0003e, 0x000fe, 0x007fd, 0x00ffd, 0x07ff0, + 0x0ffe3, 0x0fff5, 0x0fff6, 0x0fff7, 0x0fff8, 0x0fff9, 0x0fffa, 0x1fff6, + 0x1fff7, 0x1fff8, 0x1fff9, 0x1fffa, 0x1fffb, 0x1fffc, 0x1fffd, 0x1fffe, + 0x1ffff, +}; + +static const uint8_t f_huffman_env_bal_1_5dB_bits[49] = { + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 16, + 17, 14, 11, 11, 8, 7, 4, 2, + 1, 3, 5, 6, 9, 11, 12, 15, + 16, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, + 19, +}; + +static const uint32_t f_huffman_env_bal_1_5dB_codes[49] = { + 0x3ffe2, 0x3ffe3, 0x3ffe4, 0x3ffe5, 0x3ffe6, 0x3ffe7, 0x3ffe8, 0x3ffe9, + 0x3ffea, 0x3ffeb, 0x3ffec, 0x3ffed, 0x3ffee, 0x3ffef, 0x3fff0, 0x0fff7, + 0x1fff0, 0x03ffc, 0x007fe, 0x007fc, 0x000fe, 0x0007e, 0x0000e, 0x00002, + 0x00000, 0x00006, 0x0001e, 0x0003e, 0x001fe, 0x007fd, 0x00ffe, 0x07ffa, + 0x0fff6, 0x3fff1, 0x3fff2, 0x3fff3, 0x3fff4, 0x3fff5, 0x3fff6, 0x3fff7, + 0x3fff8, 0x3fff9, 0x3fffa, 0x3fffb, 0x3fffc, 0x3fffd, 0x3fffe, 0x7fffe, + 0x7ffff, +}; + +static const uint8_t t_huffman_env_3_0dB_bits[63] = { + 18, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 17, 16, 16, 16, 14, 14, 14, + 13, 12, 11, 8, 6, 4, 2, 1, + 3, 5, 7, 9, 11, 13, 14, 14, + 15, 16, 17, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, +}; + +static const uint32_t t_huffman_env_3_0dB_codes[63] = { + 0x3ffed, 0x3ffee, 0x7ffde, 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, + 0x7ffe4, 0x7ffe5, 0x7ffe6, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, + 0x7ffec, 0x1fff4, 0x0fff7, 0x0fff9, 0x0fff8, 0x03ffb, 0x03ffa, 0x03ff8, + 0x01ffa, 0x00ffc, 0x007fc, 0x000fe, 0x0003e, 0x0000e, 0x00002, 0x00000, + 0x00006, 0x0001e, 0x0007e, 0x001fe, 0x007fd, 0x01ffb, 0x03ff9, 0x03ffc, + 0x07ffa, 0x0fff6, 0x1fff5, 0x3ffec, 0x7ffed, 0x7ffee, 0x7ffef, 0x7fff0, + 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, 0x7fff7, 0x7fff8, + 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, 0x7ffff, +}; + +static const uint8_t f_huffman_env_3_0dB_bits[63] = { + 20, 20, 20, 20, 20, 20, 20, 18, + 19, 19, 19, 19, 18, 18, 20, 19, + 17, 18, 17, 16, 16, 15, 14, 12, + 11, 10, 9, 8, 6, 4, 2, 1, + 3, 5, 8, 9, 10, 11, 12, 13, + 14, 15, 15, 16, 16, 17, 17, 18, + 18, 18, 20, 19, 19, 19, 20, 19, + 19, 20, 20, 20, 20, 20, 20, +}; + +static const uint32_t f_huffman_env_3_0dB_codes[63] = { + 0xffff0, 0xffff1, 0xffff2, 0xffff3, 0xffff4, 0xffff5, 0xffff6, 0x3fff3, + 0x7fff5, 0x7ffee, 0x7ffef, 0x7fff6, 0x3fff4, 0x3fff2, 0xffff7, 0x7fff0, + 0x1fff5, 0x3fff0, 0x1fff4, 0x0fff7, 0x0fff6, 0x07ff8, 0x03ffb, 0x00ffd, + 0x007fd, 0x003fd, 0x001fd, 0x000fd, 0x0003e, 0x0000e, 0x00002, 0x00000, + 0x00006, 0x0001e, 0x000fc, 0x001fc, 0x003fc, 0x007fc, 0x00ffc, 0x01ffc, + 0x03ffa, 0x07ff9, 0x07ffa, 0x0fff8, 0x0fff9, 0x1fff6, 0x1fff7, 0x3fff5, + 0x3fff6, 0x3fff1, 0xffff8, 0x7fff1, 0x7fff2, 0x7fff3, 0xffff9, 0x7fff7, + 0x7fff4, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, 0xfffff, +}; + +static const uint8_t t_huffman_env_bal_3_0dB_bits[25] = { + 13, 13, 13, 13, 13, 13, 13, 12, + 8, 7, 4, 3, 1, 2, 5, 6, + 9, 13, 13, 13, 13, 13, 13, 14, + 14, +}; + +static const uint16_t t_huffman_env_bal_3_0dB_codes[25] = { + 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x0ff8, + 0x00fe, 0x007e, 0x000e, 0x0006, 0x0000, 0x0002, 0x001e, 0x003e, + 0x01fe, 0x1ff9, 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, + 0x3fff, +}; + +static const uint8_t f_huffman_env_bal_3_0dB_bits[25] = { + 13, 13, 13, 13, 13, 14, 14, 11, + 8, 7, 4, 2, 1, 3, 5, 6, + 9, 12, 13, 14, 14, 14, 14, 14, + 14, +}; + +static const uint16_t f_huffman_env_bal_3_0dB_codes[25] = { + 0x1ff7, 0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, 0x3ff8, 0x3ff9, 0x07fc, + 0x00fe, 0x007e, 0x000e, 0x0002, 0x0000, 0x0006, 0x001e, 0x003e, + 0x01fe, 0x0ffa, 0x1ff6, 0x3ffa, 0x3ffb, 0x3ffc, 0x3ffd, 0x3ffe, + 0x3fff, +}; + +static const uint8_t t_huffman_noise_3_0dB_bits[63] = { + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 11, 8, 6, 4, 3, 1, + 2, 5, 8, 10, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 14, 14, +}; + +static const uint16_t t_huffman_noise_3_0dB_codes[63] = { + 0x1fce, 0x1fcf, 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, + 0x1fd6, 0x1fd7, 0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, 0x1fdc, 0x1fdd, + 0x1fde, 0x1fdf, 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, + 0x1fe6, 0x1fe7, 0x07f2, 0x00fd, 0x003e, 0x000e, 0x0006, 0x0000, + 0x0002, 0x001e, 0x00fc, 0x03f8, 0x1fcc, 0x1fe8, 0x1fe9, 0x1fea, + 0x1feb, 0x1fec, 0x1fcd, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1, + 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x1ff9, + 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, 0x3fff, +}; + +static const uint8_t t_huffman_noise_bal_3_0dB_bits[25] = { + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 5, 2, 1, 3, 6, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, +}; + +static const uint8_t t_huffman_noise_bal_3_0dB_codes[25] = { + 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0x1c, 0x02, 0x00, 0x06, 0x3a, 0xf6, + 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, + 0xff, +}; + +static const int8_t sbr_offset[6][16] = { + {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // fs_sbr = 16000 Hz + {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}, // fs_sbr = 22050 Hz + {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 24000 Hz + {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 32000 Hz + {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}, // 44100 Hz <= fs_sbr <= 64000 Hz + {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}, // 64000 Hz < fs_sbr +}; + +///< window coefficients for analysis/synthesis QMF banks +static DECLARE_ALIGNED(32, float, sbr_qmf_window_ds)[320]; +static DECLARE_ALIGNED(32, float, sbr_qmf_window_us)[640] = { + 0.0000000000, -0.0005525286, -0.0005617692, -0.0004947518, + -0.0004875227, -0.0004893791, -0.0005040714, -0.0005226564, + -0.0005466565, -0.0005677802, -0.0005870930, -0.0006132747, + -0.0006312493, -0.0006540333, -0.0006777690, -0.0006941614, + -0.0007157736, -0.0007255043, -0.0007440941, -0.0007490598, + -0.0007681371, -0.0007724848, -0.0007834332, -0.0007779869, + -0.0007803664, -0.0007801449, -0.0007757977, -0.0007630793, + -0.0007530001, -0.0007319357, -0.0007215391, -0.0006917937, + -0.0006650415, -0.0006341594, -0.0005946118, -0.0005564576, + -0.0005145572, -0.0004606325, -0.0004095121, -0.0003501175, + -0.0002896981, -0.0002098337, -0.0001446380, -0.0000617334, + 0.0000134949, 0.0001094383, 0.0002043017, 0.0002949531, + 0.0004026540, 0.0005107388, 0.0006239376, 0.0007458025, + 0.0008608443, 0.0009885988, 0.0011250155, 0.0012577884, + 0.0013902494, 0.0015443219, 0.0016868083, 0.0018348265, + 0.0019841140, 0.0021461583, 0.0023017254, 0.0024625616, + 0.0026201758, 0.0027870464, 0.0029469447, 0.0031125420, + 0.0032739613, 0.0034418874, 0.0036008268, 0.0037603922, + 0.0039207432, 0.0040819753, 0.0042264269, 0.0043730719, + 0.0045209852, 0.0046606460, 0.0047932560, 0.0049137603, + 0.0050393022, 0.0051407353, 0.0052461166, 0.0053471681, + 0.0054196775, 0.0054876040, 0.0055475714, 0.0055938023, + 0.0056220643, 0.0056455196, 0.0056389199, 0.0056266114, + 0.0055917128, 0.0055404363, 0.0054753783, 0.0053838975, + 0.0052715758, 0.0051382275, 0.0049839687, 0.0048109469, + 0.0046039530, 0.0043801861, 0.0041251642, 0.0038456408, + 0.0035401246, 0.0032091885, 0.0028446757, 0.0024508540, + 0.0020274176, 0.0015784682, 0.0010902329, 0.0005832264, + 0.0000276045, -0.0005464280, -0.0011568135, -0.0018039472, + -0.0024826723, -0.0031933778, -0.0039401124, -0.0047222596, + -0.0055337211, -0.0063792293, -0.0072615816, -0.0081798233, + -0.0091325329, -0.0101150215, -0.0111315548, -0.0121849995, + 0.0132718220, 0.0143904666, 0.0155405553, 0.0167324712, + 0.0179433381, 0.0191872431, 0.0204531793, 0.0217467550, + 0.0230680169, 0.0244160992, 0.0257875847, 0.0271859429, + 0.0286072173, 0.0300502657, 0.0315017608, 0.0329754081, + 0.0344620948, 0.0359697560, 0.0374812850, 0.0390053679, + 0.0405349170, 0.0420649094, 0.0436097542, 0.0451488405, + 0.0466843027, 0.0482165720, 0.0497385755, 0.0512556155, + 0.0527630746, 0.0542452768, 0.0557173648, 0.0571616450, + 0.0585915683, 0.0599837480, 0.0613455171, 0.0626857808, + 0.0639715898, 0.0652247106, 0.0664367512, 0.0676075985, + 0.0687043828, 0.0697630244, 0.0707628710, 0.0717002673, + 0.0725682583, 0.0733620255, 0.0741003642, 0.0747452558, + 0.0753137336, 0.0758008358, 0.0761992479, 0.0764992170, + 0.0767093490, 0.0768173975, 0.0768230011, 0.0767204924, + 0.0765050718, 0.0761748321, 0.0757305756, 0.0751576255, + 0.0744664394, 0.0736406005, 0.0726774642, 0.0715826364, + 0.0703533073, 0.0689664013, 0.0674525021, 0.0657690668, + 0.0639444805, 0.0619602779, 0.0598166570, 0.0575152691, + 0.0550460034, 0.0524093821, 0.0495978676, 0.0466303305, + 0.0434768782, 0.0401458278, 0.0366418116, 0.0329583930, + 0.0290824006, 0.0250307561, 0.0207997072, 0.0163701258, + 0.0117623832, 0.0069636862, 0.0019765601, -0.0032086896, + -0.0085711749, -0.0141288827, -0.0198834129, -0.0258227288, + -0.0319531274, -0.0382776572, -0.0447806821, -0.0514804176, + -0.0583705326, -0.0654409853, -0.0726943300, -0.0801372934, + -0.0877547536, -0.0955533352, -0.1035329531, -0.1116826931, + -0.1200077984, -0.1285002850, -0.1371551761, -0.1459766491, + -0.1549607071, -0.1640958855, -0.1733808172, -0.1828172548, + -0.1923966745, -0.2021250176, -0.2119735853, -0.2219652696, + -0.2320690870, -0.2423016884, -0.2526480309, -0.2631053299, + -0.2736634040, -0.2843214189, -0.2950716717, -0.3059098575, + -0.3168278913, -0.3278113727, -0.3388722693, -0.3499914122, + 0.3611589903, 0.3723795546, 0.3836350013, 0.3949211761, + 0.4062317676, 0.4175696896, 0.4289119920, 0.4402553754, + 0.4515996535, 0.4629308085, 0.4742453214, 0.4855253091, + 0.4967708254, 0.5079817500, 0.5191234970, 0.5302240895, + 0.5412553448, 0.5522051258, 0.5630789140, 0.5738524131, + 0.5845403235, 0.5951123086, 0.6055783538, 0.6159109932, + 0.6261242695, 0.6361980107, 0.6461269695, 0.6559016302, + 0.6655139880, 0.6749663190, 0.6842353293, 0.6933282376, + 0.7022388719, 0.7109410426, 0.7194462634, 0.7277448900, + 0.7358211758, 0.7436827863, 0.7513137456, 0.7587080760, + 0.7658674865, 0.7727780881, 0.7794287519, 0.7858353120, + 0.7919735841, 0.7978466413, 0.8034485751, 0.8087695004, + 0.8138191270, 0.8185776004, 0.8230419890, 0.8272275347, + 0.8311038457, 0.8346937361, 0.8379717337, 0.8409541392, + 0.8436238281, 0.8459818469, 0.8480315777, 0.8497805198, + 0.8511971524, 0.8523047035, 0.8531020949, 0.8535720573, + 0.8537385600, +}; + +/* First eight entries repeated at end to simplify SIMD implementations. */ +const DECLARE_ALIGNED(16, float, ff_sbr_noise_table)[][2] = { +{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647}, +{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647}, +{ 0.80705063769351, 0.29653668284408}, {-0.38981478896926, 0.89572605717087}, +{-0.01053049862020, -0.66959058036166}, {-0.91266367957293, -0.11522938140034}, +{ 0.54840422910309, 0.75221367176302}, { 0.40009252867955, -0.98929400334421}, +{-0.99867974711855, -0.88147068645358}, {-0.95531076805040, 0.90908757154593}, +{-0.45725933317144, -0.56716323646760}, {-0.72929675029275, -0.98008272727324}, +{ 0.75622801399036, 0.20950329995549}, { 0.07069442601050, -0.78247898470706}, +{ 0.74496252926055, -0.91169004445807}, {-0.96440182703856, -0.94739918296622}, +{ 0.30424629369539, -0.49438267012479}, { 0.66565033746925, 0.64652935542491}, +{ 0.91697008020594, 0.17514097332009}, {-0.70774918760427, 0.52548653416543}, +{-0.70051415345560, -0.45340028808763}, {-0.99496513054797, -0.90071908066973}, +{ 0.98164490790123, -0.77463155528697}, {-0.54671580548181, -0.02570928536004}, +{-0.01689629065389, 0.00287506445732}, {-0.86110349531986, 0.42548583726477}, +{-0.98892980586032, -0.87881132267556}, { 0.51756627678691, 0.66926784710139}, +{-0.99635026409640, -0.58107730574765}, {-0.99969370862163, 0.98369989360250}, +{ 0.55266258627194, 0.59449057465591}, { 0.34581177741673, 0.94879421061866}, +{ 0.62664209577999, -0.74402970906471}, {-0.77149701404973, -0.33883658042801}, +{-0.91592244254432, 0.03687901376713}, {-0.76285492357887, -0.91371867919124}, +{ 0.79788337195331, -0.93180971199849}, { 0.54473080610200, -0.11919206037186}, +{-0.85639281671058, 0.42429854760451}, {-0.92882402971423, 0.27871809078609}, +{-0.11708371046774, -0.99800843444966}, { 0.21356749817493, -0.90716295627033}, +{-0.76191692573909, 0.99768118356265}, { 0.98111043100884, -0.95854459734407}, +{-0.85913269895572, 0.95766566168880}, {-0.93307242253692, 0.49431757696466}, +{ 0.30485754879632, -0.70540034357529}, { 0.85289650925190, 0.46766131791044}, +{ 0.91328082618125, -0.99839597361769}, {-0.05890199924154, 0.70741827819497}, +{ 0.28398686150148, 0.34633555702188}, { 0.95258164539612, -0.54893416026939}, +{-0.78566324168507, -0.75568541079691}, {-0.95789495447877, -0.20423194696966}, +{ 0.82411158711197, 0.96654618432562}, {-0.65185446735885, -0.88734990773289}, +{-0.93643603134666, 0.99870790442385}, { 0.91427159529618, -0.98290505544444}, +{-0.70395684036886, 0.58796798221039}, { 0.00563771969365, 0.61768196727244}, +{ 0.89065051931895, 0.52783352697585}, {-0.68683707712762, 0.80806944710339}, +{ 0.72165342518718, -0.69259857349564}, {-0.62928247730667, 0.13627037407335}, +{ 0.29938434065514, -0.46051329682246}, {-0.91781958879280, -0.74012716684186}, +{ 0.99298717043688, 0.40816610075661}, { 0.82368298622748, -0.74036047190173}, +{-0.98512833386833, -0.99972330709594}, {-0.95915368242257, -0.99237800466040}, +{-0.21411126572790, -0.93424819052545}, {-0.68821476106884, -0.26892306315457}, +{ 0.91851997982317, 0.09358228901785}, {-0.96062769559127, 0.36099095133739}, +{ 0.51646184922287, -0.71373332873917}, { 0.61130721139669, 0.46950141175917}, +{ 0.47336129371299, -0.27333178296162}, { 0.90998308703519, 0.96715662938132}, +{ 0.44844799194357, 0.99211574628306}, { 0.66614891079092, 0.96590176169121}, +{ 0.74922239129237, -0.89879858826087}, {-0.99571588506485, 0.52785521494349}, +{ 0.97401082477563, -0.16855870075190}, { 0.72683747733879, -0.48060774432251}, +{ 0.95432193457128, 0.68849603408441}, {-0.72962208425191, -0.76608443420917}, +{-0.85359479233537, 0.88738125901579}, {-0.81412430338535, -0.97480768049637}, +{-0.87930772356786, 0.74748307690436}, {-0.71573331064977, -0.98570608178923}, +{ 0.83524300028228, 0.83702537075163}, {-0.48086065601423, -0.98848504923531}, +{ 0.97139128574778, 0.80093621198236}, { 0.51992825347895, 0.80247631400510}, +{-0.00848591195325, -0.76670128000486}, {-0.70294374303036, 0.55359910445577}, +{-0.95894428168140, -0.43265504344783}, { 0.97079252950321, 0.09325857238682}, +{-0.92404293670797, 0.85507704027855}, {-0.69506469500450, 0.98633412625459}, +{ 0.26559203620024, 0.73314307966524}, { 0.28038443336943, 0.14537913654427}, +{-0.74138124825523, 0.99310339807762}, {-0.01752795995444, -0.82616635284178}, +{-0.55126773094930, -0.98898543862153}, { 0.97960898850996, -0.94021446752851}, +{-0.99196309146936, 0.67019017358456}, {-0.67684928085260, 0.12631491649378}, +{ 0.09140039465500, -0.20537731453108}, {-0.71658965751996, -0.97788200391224}, +{ 0.81014640078925, 0.53722648362443}, { 0.40616991671205, -0.26469008598449}, +{-0.67680188682972, 0.94502052337695}, { 0.86849774348749, -0.18333598647899}, +{-0.99500381284851, -0.02634122068550}, { 0.84329189340667, 0.10406957462213}, +{-0.09215968531446, 0.69540012101253}, { 0.99956173327206, -0.12358542001404}, +{-0.79732779473535, -0.91582524736159}, { 0.96349973642406, 0.96640458041000}, +{-0.79942778496547, 0.64323902822857}, {-0.11566039853896, 0.28587846253726}, +{-0.39922954514662, 0.94129601616966}, { 0.99089197565987, -0.92062625581587}, +{ 0.28631285179909, -0.91035047143603}, {-0.83302725605608, -0.67330410892084}, +{ 0.95404443402072, 0.49162765398743}, {-0.06449863579434, 0.03250560813135}, +{-0.99575054486311, 0.42389784469507}, {-0.65501142790847, 0.82546114655624}, +{-0.81254441908887, -0.51627234660629}, {-0.99646369485481, 0.84490533520752}, +{ 0.00287840603348, 0.64768261158166}, { 0.70176989408455, -0.20453028573322}, +{ 0.96361882270190, 0.40706967140989}, {-0.68883758192426, 0.91338958840772}, +{-0.34875585502238, 0.71472290693300}, { 0.91980081243087, 0.66507455644919}, +{-0.99009048343881, 0.85868021604848}, { 0.68865791458395, 0.55660316809678}, +{-0.99484402129368, -0.20052559254934}, { 0.94214511408023, -0.99696425367461}, +{-0.67414626793544, 0.49548221180078}, {-0.47339353684664, -0.85904328834047}, +{ 0.14323651387360, -0.94145598222488}, {-0.29268293575672, 0.05759224927952}, +{ 0.43793861458754, -0.78904969892724}, {-0.36345126374441, 0.64874435357162}, +{-0.08750604656825, 0.97686944362527}, {-0.96495267812511, -0.53960305946511}, +{ 0.55526940659947, 0.78891523734774}, { 0.73538215752630, 0.96452072373404}, +{-0.30889773919437, -0.80664389776860}, { 0.03574995626194, -0.97325616900959}, +{ 0.98720684660488, 0.48409133691962}, {-0.81689296271203, -0.90827703628298}, +{ 0.67866860118215, 0.81284503870856}, {-0.15808569732583, 0.85279555024382}, +{ 0.80723395114371, -0.24717418514605}, { 0.47788757329038, -0.46333147839295}, +{ 0.96367554763201, 0.38486749303242}, {-0.99143875716818, -0.24945277239809}, +{ 0.83081876925833, -0.94780851414763}, {-0.58753191905341, 0.01290772389163}, +{ 0.95538108220960, -0.85557052096538}, {-0.96490920476211, -0.64020970923102}, +{-0.97327101028521, 0.12378128133110}, { 0.91400366022124, 0.57972471346930}, +{-0.99925837363824, 0.71084847864067}, {-0.86875903507313, -0.20291699203564}, +{-0.26240034795124, -0.68264554369108}, {-0.24664412953388, -0.87642273115183}, +{ 0.02416275806869, 0.27192914288905}, { 0.82068619590515, -0.85087787994476}, +{ 0.88547373760759, -0.89636802901469}, {-0.18173078152226, -0.26152145156800}, +{ 0.09355476558534, 0.54845123045604}, {-0.54668414224090, 0.95980774020221}, +{ 0.37050990604091, -0.59910140383171}, {-0.70373594262891, 0.91227665827081}, +{-0.34600785879594, -0.99441426144200}, {-0.68774481731008, -0.30238837956299}, +{-0.26843291251234, 0.83115668004362}, { 0.49072334613242, -0.45359708737775}, +{ 0.38975993093975, 0.95515358099121}, {-0.97757125224150, 0.05305894580606}, +{-0.17325552859616, -0.92770672250494}, { 0.99948035025744, 0.58285545563426}, +{-0.64946246527458, 0.68645507104960}, {-0.12016920576437, -0.57147322153312}, +{-0.58947456517751, -0.34847132454388}, {-0.41815140454465, 0.16276422358861}, +{ 0.99885650204884, 0.11136095490444}, {-0.56649614128386, -0.90494866361587}, +{ 0.94138021032330, 0.35281916733018}, {-0.75725076534641, 0.53650549640587}, +{ 0.20541973692630, -0.94435144369918}, { 0.99980371023351, 0.79835913565599}, +{ 0.29078277605775, 0.35393777921520}, {-0.62858772103030, 0.38765693387102}, +{ 0.43440904467688, -0.98546330463232}, {-0.98298583762390, 0.21021524625209}, +{ 0.19513029146934, -0.94239832251867}, {-0.95476662400101, 0.98364554179143}, +{ 0.93379635304810, -0.70881994583682}, {-0.85235410573336, -0.08342347966410}, +{-0.86425093011245, -0.45795025029466}, { 0.38879779059045, 0.97274429344593}, +{ 0.92045124735495, -0.62433652524220}, { 0.89162532251878, 0.54950955570563}, +{-0.36834336949252, 0.96458298020975}, { 0.93891760988045, -0.89968353740388}, +{ 0.99267657565094, -0.03757034316958}, {-0.94063471614176, 0.41332338538963}, +{ 0.99740224117019, -0.16830494996370}, {-0.35899413170555, -0.46633226649613}, +{ 0.05237237274947, -0.25640361602661}, { 0.36703583957424, -0.38653265641875}, +{ 0.91653180367913, -0.30587628726597}, { 0.69000803499316, 0.90952171386132}, +{-0.38658751133527, 0.99501571208985}, {-0.29250814029851, 0.37444994344615}, +{-0.60182204677608, 0.86779651036123}, {-0.97418588163217, 0.96468523666475}, +{ 0.88461574003963, 0.57508405276414}, { 0.05198933055162, 0.21269661669964}, +{-0.53499621979720, 0.97241553731237}, {-0.49429560226497, 0.98183865291903}, +{-0.98935142339139, -0.40249159006933}, {-0.98081380091130, -0.72856895534041}, +{-0.27338148835532, 0.99950922447209}, { 0.06310802338302, -0.54539587529618}, +{-0.20461677199539, -0.14209977628489}, { 0.66223843141647, 0.72528579940326}, +{-0.84764345483665, 0.02372316801261}, {-0.89039863483811, 0.88866581484602}, +{ 0.95903308477986, 0.76744927173873}, { 0.73504123909879, -0.03747203173192}, +{-0.31744434966056, -0.36834111883652}, {-0.34110827591623, 0.40211222807691}, +{ 0.47803883714199, -0.39423219786288}, { 0.98299195879514, 0.01989791390047}, +{-0.30963073129751, -0.18076720599336}, { 0.99992588229018, -0.26281872094289}, +{-0.93149731080767, -0.98313162570490}, { 0.99923472302773, -0.80142993767554}, +{-0.26024169633417, -0.75999759855752}, {-0.35712514743563, 0.19298963768574}, +{-0.99899084509530, 0.74645156992493}, { 0.86557171579452, 0.55593866696299}, +{ 0.33408042438752, 0.86185953874709}, { 0.99010736374716, 0.04602397576623}, +{-0.66694269691195, -0.91643611810148}, { 0.64016792079480, 0.15649530836856}, +{ 0.99570534804836, 0.45844586038111}, {-0.63431466947340, 0.21079116459234}, +{-0.07706847005931, -0.89581437101329}, { 0.98590090577724, 0.88241721133981}, +{ 0.80099335254678, -0.36851896710853}, { 0.78368131392666, 0.45506999802597}, +{ 0.08707806671691, 0.80938994918745}, {-0.86811883080712, 0.39347308654705}, +{-0.39466529740375, -0.66809432114456}, { 0.97875325649683, -0.72467840967746}, +{-0.95038560288864, 0.89563219587625}, { 0.17005239424212, 0.54683053962658}, +{-0.76910792026848, -0.96226617549298}, { 0.99743281016846, 0.42697157037567}, +{ 0.95437383549973, 0.97002324109952}, { 0.99578905365569, -0.54106826257356}, +{ 0.28058259829990, -0.85361420634036}, { 0.85256524470573, -0.64567607735589}, +{-0.50608540105128, -0.65846015480300}, {-0.97210735183243, -0.23095213067791}, +{ 0.95424048234441, -0.99240147091219}, {-0.96926570524023, 0.73775654896574}, +{ 0.30872163214726, 0.41514960556126}, {-0.24523839572639, 0.63206633394807}, +{-0.33813265086024, -0.38661779441897}, {-0.05826828420146, -0.06940774188029}, +{-0.22898461455054, 0.97054853316316}, {-0.18509915019881, 0.47565762892084}, +{-0.10488238045009, -0.87769947402394}, {-0.71886586182037, 0.78030982480538}, +{ 0.99793873738654, 0.90041310491497}, { 0.57563307626120, -0.91034337352097}, +{ 0.28909646383717, 0.96307783970534}, { 0.42188998312520, 0.48148651230437}, +{ 0.93335049681047, -0.43537023883588}, {-0.97087374418267, 0.86636445711364}, +{ 0.36722871286923, 0.65291654172961}, {-0.81093025665696, 0.08778370229363}, +{-0.26240603062237, -0.92774095379098}, { 0.83996497984604, 0.55839849139647}, +{-0.99909615720225, -0.96024605713970}, { 0.74649464155061, 0.12144893606462}, +{-0.74774595569805, -0.26898062008959}, { 0.95781667469567, -0.79047927052628}, +{ 0.95472308713099, -0.08588776019550}, { 0.48708332746299, 0.99999041579432}, +{ 0.46332038247497, 0.10964126185063}, {-0.76497004940162, 0.89210929242238}, +{ 0.57397389364339, 0.35289703373760}, { 0.75374316974495, 0.96705214651335}, +{-0.59174397685714, -0.89405370422752}, { 0.75087906691890, -0.29612672982396}, +{-0.98607857336230, 0.25034911730023}, {-0.40761056640505, -0.90045573444695}, +{ 0.66929266740477, 0.98629493401748}, {-0.97463695257310, -0.00190223301301}, +{ 0.90145509409859, 0.99781390365446}, {-0.87259289048043, 0.99233587353666}, +{-0.91529461447692, -0.15698707534206}, {-0.03305738840705, -0.37205262859764}, +{ 0.07223051368337, -0.88805001733626}, { 0.99498012188353, 0.97094358113387}, +{-0.74904939500519, 0.99985483641521}, { 0.04585228574211, 0.99812337444082}, +{-0.89054954257993, -0.31791913188064}, {-0.83782144651251, 0.97637632547466}, +{ 0.33454804933804, -0.86231516800408}, {-0.99707579362824, 0.93237990079441}, +{-0.22827527843994, 0.18874759397997}, { 0.67248046289143, -0.03646211390569}, +{-0.05146538187944, -0.92599700120679}, { 0.99947295749905, 0.93625229707912}, +{ 0.66951124390363, 0.98905825623893}, {-0.99602956559179, -0.44654715757688}, +{ 0.82104905483590, 0.99540741724928}, { 0.99186510988782, 0.72023001312947}, +{-0.65284592392918, 0.52186723253637}, { 0.93885443798188, -0.74895312615259}, +{ 0.96735248738388, 0.90891816978629}, {-0.22225968841114, 0.57124029781228}, +{-0.44132783753414, -0.92688840659280}, {-0.85694974219574, 0.88844532719844}, +{ 0.91783042091762, -0.46356892383970}, { 0.72556974415690, -0.99899555770747}, +{-0.99711581834508, 0.58211560180426}, { 0.77638976371966, 0.94321834873819}, +{ 0.07717324253925, 0.58638399856595}, {-0.56049829194163, 0.82522301569036}, +{ 0.98398893639988, 0.39467440420569}, { 0.47546946844938, 0.68613044836811}, +{ 0.65675089314631, 0.18331637134880}, { 0.03273375457980, -0.74933109564108}, +{-0.38684144784738, 0.51337349030406}, {-0.97346267944545, -0.96549364384098}, +{-0.53282156061942, -0.91423265091354}, { 0.99817310731176, 0.61133572482148}, +{-0.50254500772635, -0.88829338134294}, { 0.01995873238855, 0.85223515096765}, +{ 0.99930381973804, 0.94578896296649}, { 0.82907767600783, -0.06323442598128}, +{-0.58660709669728, 0.96840773806582}, {-0.17573736667267, -0.48166920859485}, +{ 0.83434292401346, -0.13023450646997}, { 0.05946491307025, 0.20511047074866}, +{ 0.81505484574602, -0.94685947861369}, {-0.44976380954860, 0.40894572671545}, +{-0.89746474625671, 0.99846578838537}, { 0.39677256130792, -0.74854668609359}, +{-0.07588948563079, 0.74096214084170}, { 0.76343198951445, 0.41746629422634}, +{-0.74490104699626, 0.94725911744610}, { 0.64880119792759, 0.41336660830571}, +{ 0.62319537462542, -0.93098313552599}, { 0.42215817594807, -0.07712787385208}, +{ 0.02704554141885, -0.05417518053666}, { 0.80001773566818, 0.91542195141039}, +{-0.79351832348816, -0.36208897989136}, { 0.63872359151636, 0.08128252493444}, +{ 0.52890520960295, 0.60048872455592}, { 0.74238552914587, 0.04491915291044}, +{ 0.99096131449250, -0.19451182854402}, {-0.80412329643109, -0.88513818199457}, +{-0.64612616129736, 0.72198674804544}, { 0.11657770663191, -0.83662833815041}, +{-0.95053182488101, -0.96939905138082}, {-0.62228872928622, 0.82767262846661}, +{ 0.03004475787316, -0.99738896333384}, {-0.97987214341034, 0.36526129686425}, +{-0.99986980746200, -0.36021610299715}, { 0.89110648599879, -0.97894250343044}, +{ 0.10407960510582, 0.77357793811619}, { 0.95964737821728, -0.35435818285502}, +{ 0.50843233159162, 0.96107691266205}, { 0.17006334670615, -0.76854025314829}, +{ 0.25872675063360, 0.99893303933816}, {-0.01115998681937, 0.98496019742444}, +{-0.79598702973261, 0.97138411318894}, {-0.99264708948101, -0.99542822402536}, +{-0.99829663752818, 0.01877138824311}, {-0.70801016548184, 0.33680685948117}, +{-0.70467057786826, 0.93272777501857}, { 0.99846021905254, -0.98725746254433}, +{-0.63364968534650, -0.16473594423746}, {-0.16258217500792, -0.95939125400802}, +{-0.43645594360633, -0.94805030113284}, {-0.99848471702976, 0.96245166923809}, +{-0.16796458968998, -0.98987511890470}, {-0.87979225745213, -0.71725725041680}, +{ 0.44183099021786, -0.93568974498761}, { 0.93310180125532, -0.99913308068246}, +{-0.93941931782002, -0.56409379640356}, {-0.88590003188677, 0.47624600491382}, +{ 0.99971463703691, -0.83889954253462}, {-0.75376385639978, 0.00814643438625}, +{ 0.93887685615875, -0.11284528204636}, { 0.85126435782309, 0.52349251543547}, +{ 0.39701421446381, 0.81779634174316}, {-0.37024464187437, -0.87071656222959}, +{-0.36024828242896, 0.34655735648287}, {-0.93388812549209, -0.84476541096429}, +{-0.65298804552119, -0.18439575450921}, { 0.11960319006843, 0.99899346780168}, +{ 0.94292565553160, 0.83163906518293}, { 0.75081145286948, -0.35533223142265}, +{ 0.56721979748394, -0.24076836414499}, { 0.46857766746029, -0.30140233457198}, +{ 0.97312313923635, -0.99548191630031}, {-0.38299976567017, 0.98516909715427}, +{ 0.41025800019463, 0.02116736935734}, { 0.09638062008048, 0.04411984381457}, +{-0.85283249275397, 0.91475563922421}, { 0.88866808958124, -0.99735267083226}, +{-0.48202429536989, -0.96805608884164}, { 0.27572582416567, 0.58634753335832}, +{-0.65889129659168, 0.58835634138583}, { 0.98838086953732, 0.99994349600236}, +{-0.20651349620689, 0.54593044066355}, {-0.62126416356920, -0.59893681700392}, +{ 0.20320105410437, -0.86879180355289}, {-0.97790548600584, 0.96290806999242}, +{ 0.11112534735126, 0.21484763313301}, {-0.41368337314182, 0.28216837680365}, +{ 0.24133038992960, 0.51294362630238}, {-0.66393410674885, -0.08249679629081}, +{-0.53697829178752, -0.97649903936228}, {-0.97224737889348, 0.22081333579837}, +{ 0.87392477144549, -0.12796173740361}, { 0.19050361015753, 0.01602615387195}, +{-0.46353441212724, -0.95249041539006}, {-0.07064096339021, -0.94479803205886}, +{-0.92444085484466, -0.10457590187436}, {-0.83822593578728, -0.01695043208885}, +{ 0.75214681811150, -0.99955681042665}, {-0.42102998829339, 0.99720941999394}, +{-0.72094786237696, -0.35008961934255}, { 0.78843311019251, 0.52851398958271}, +{ 0.97394027897442, -0.26695944086561}, { 0.99206463477946, -0.57010120849429}, +{ 0.76789609461795, -0.76519356730966}, {-0.82002421836409, -0.73530179553767}, +{ 0.81924990025724, 0.99698425250579}, {-0.26719850873357, 0.68903369776193}, +{-0.43311260380975, 0.85321815947490}, { 0.99194979673836, 0.91876249766422}, +{-0.80692001248487, -0.32627540663214}, { 0.43080003649976, -0.21919095636638}, +{ 0.67709491937357, -0.95478075822906}, { 0.56151770568316, -0.70693811747778}, +{ 0.10831862810749, -0.08628837174592}, { 0.91229417540436, -0.65987351408410}, +{-0.48972893932274, 0.56289246362686}, {-0.89033658689697, -0.71656563987082}, +{ 0.65269447475094, 0.65916004833932}, { 0.67439478141121, -0.81684380846796}, +{-0.47770832416973, -0.16789556203025}, {-0.99715979260878, -0.93565784007648}, +{-0.90889593602546, 0.62034397054380}, {-0.06618622548177, -0.23812217221359}, +{ 0.99430266919728, 0.18812555317553}, { 0.97686402381843, -0.28664534366620}, +{ 0.94813650221268, -0.97506640027128}, {-0.95434497492853, -0.79607978501983}, +{-0.49104783137150, 0.32895214359663}, { 0.99881175120751, 0.88993983831354}, +{ 0.50449166760303, -0.85995072408434}, { 0.47162891065108, -0.18680204049569}, +{-0.62081581361840, 0.75000676218956}, {-0.43867015250812, 0.99998069244322}, +{ 0.98630563232075, -0.53578899600662}, {-0.61510362277374, -0.89515019899997}, +{-0.03841517601843, -0.69888815681179}, {-0.30102157304644, -0.07667808922205}, +{ 0.41881284182683, 0.02188098922282}, {-0.86135454941237, 0.98947480909359}, +{ 0.67226861393788, -0.13494389011014}, {-0.70737398842068, -0.76547349325992}, +{ 0.94044946687963, 0.09026201157416}, {-0.82386352534327, 0.08924768823676}, +{-0.32070666698656, 0.50143421908753}, { 0.57593163224487, -0.98966422921509}, +{-0.36326018419965, 0.07440243123228}, { 0.99979044674350, -0.14130287347405}, +{-0.92366023326932, -0.97979298068180}, {-0.44607178518598, -0.54233252016394}, +{ 0.44226800932956, 0.71326756742752}, { 0.03671907158312, 0.63606389366675}, +{ 0.52175424682195, -0.85396826735705}, {-0.94701139690956, -0.01826348194255}, +{-0.98759606946049, 0.82288714303073}, { 0.87434794743625, 0.89399495655433}, +{-0.93412041758744, 0.41374052024363}, { 0.96063943315511, 0.93116709541280}, +{ 0.97534253457837, 0.86150930812689}, { 0.99642466504163, 0.70190043427512}, +{-0.94705089665984, -0.29580042814306}, { 0.91599807087376, -0.98147830385781}, +// Start of duplicated table +{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647}, +{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647}, +{ 0.80705063769351, 0.29653668284408}, {-0.38981478896926, 0.89572605717087}, +{-0.01053049862020, -0.66959058036166}, {-0.91266367957293, -0.11522938140034}, +}; + +#endif /* AVCODEC_AACSBRDATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c index f91ded0fc..48b82e1c8 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c @@ -31,6 +31,7 @@ #include "libavutil/crc.h" #include "libavutil/opt.h" +#include "libavutil/internal.h" #include "internal.h" #include "aac_ac3_parser.h" #include "ac3_parser.h" @@ -178,11 +179,13 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo or mono */ + AV_NOWARN_DEPRECATED( if (avctx->channels > 0 && avctx->request_channels > 0 && avctx->request_channels < avctx->channels && avctx->request_channels <= 2) { avctx->channels = avctx->request_channels; } + ); s->downmixed = 1; for (i = 0; i < AC3_MAX_CHANNELS; i++) { @@ -1347,12 +1350,14 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, s->output_mode = s->channel_mode; if (s->lfe_on) s->output_mode |= AC3_OUTPUT_LFEON; + AV_NOWARN_DEPRECATED( if (avctx->request_channels > 0 && avctx->request_channels <= 2 && avctx->request_channels < s->channels) { s->out_channels = avctx->request_channels; s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode]; } + ); avctx->channels = s->out_channels; avctx->channel_layout = s->channel_layout; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.c new file mode 100644 index 000000000..44f481ddb --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.c @@ -0,0 +1,1583 @@ +/* + * Copyright (c) 2001-2003 The ffmpeg Project + * + * first version by Francois Revol (revol@free.fr) + * fringe ADPCM codecs (e.g., DK3, DK4, Westwood) + * by Mike Melanson (melanson@pcisys.net) + * CD-ROM XA ADPCM codec by BERO + * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com) + * EA ADPCM R1/R2/R3 decoder by Peter Ross (pross@xvid.org) + * EA IMA EACS decoder by Peter Ross (pross@xvid.org) + * EA IMA SEAD decoder by Peter Ross (pross@xvid.org) + * EA ADPCM XAS decoder by Peter Ross (pross@xvid.org) + * MAXIS EA ADPCM decoder by Robert Marston (rmarston@gmail.com) + * THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avcodec.h" +#include "get_bits.h" +#include "bytestream.h" +#include "adpcm.h" +#include "adpcm_data.h" +#include "internal.h" +#include "libavutil/internal.h" + +/** + * @file + * ADPCM decoders + * Features and limitations: + * + * Reference documents: + * http://wiki.multimedia.cx/index.php?title=Category:ADPCM_Audio_Codecs + * http://www.pcisys.net/~melanson/codecs/simpleaudio.html [dead] + * http://www.geocities.com/SiliconValley/8682/aud3.txt [dead] + * http://openquicktime.sourceforge.net/ + * XAnim sources (xa_codec.c) http://xanim.polter.net/ + * http://www.cs.ucla.edu/~leec/mediabench/applications.html [dead] + * SoX source code http://sox.sourceforge.net/ + * + * CD-ROM XA: + * http://ku-www.ss.titech.ac.jp/~yatsushi/xaadpcm.html [dead] + * vagpack & depack http://homepages.compuserve.de/bITmASTER32/psx-index.html [dead] + * readstr http://www.geocities.co.jp/Playtown/2004/ + */ + +/* These are for CD-ROM XA ADPCM */ +static const int xa_adpcm_table[5][2] = { + { 0, 0 }, + { 60, 0 }, + { 115, -52 }, + { 98, -55 }, + { 122, -60 } +}; + +static const int ea_adpcm_table[] = { + 0, 240, 460, 392, + 0, 0, -208, -220, + 0, 1, 3, 4, + 7, 8, 10, 11, + 0, -1, -3, -4 +}; + +// padded to zero where table size is less then 16 +static const int swf_index_tables[4][16] = { + /*2*/ { -1, 2 }, + /*3*/ { -1, -1, 2, 4 }, + /*4*/ { -1, -1, -1, -1, 2, 4, 6, 8 }, + /*5*/ { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 } +}; + +/* end of tables */ + +typedef struct ADPCMDecodeContext { + ADPCMChannelStatus status[6]; + int vqa_version; /**< VQA version. Used for ADPCM_IMA_WS */ +} ADPCMDecodeContext; + +static av_cold int adpcm_decode_init(AVCodecContext * avctx) +{ + ADPCMDecodeContext *c = avctx->priv_data; + unsigned int min_channels = 1; + unsigned int max_channels = 2; + + switch(avctx->codec->id) { + case AV_CODEC_ID_ADPCM_DTK: + case AV_CODEC_ID_ADPCM_EA: + min_channels = 2; + break; + case AV_CODEC_ID_ADPCM_AFC: + case AV_CODEC_ID_ADPCM_EA_R1: + case AV_CODEC_ID_ADPCM_EA_R2: + case AV_CODEC_ID_ADPCM_EA_R3: + case AV_CODEC_ID_ADPCM_EA_XAS: + case AV_CODEC_ID_ADPCM_THP: + max_channels = 6; + break; + default: break; + } + if (avctx->channels < min_channels || avctx->channels > max_channels) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); + return AVERROR(EINVAL); + } + + switch(avctx->codec->id) { + case AV_CODEC_ID_ADPCM_CT: + c->status[0].step = c->status[1].step = 511; + break; + case AV_CODEC_ID_ADPCM_IMA_WAV: + if (avctx->bits_per_coded_sample < 2 || avctx->bits_per_coded_sample > 5) + return AVERROR_INVALIDDATA; + break; + case AV_CODEC_ID_ADPCM_IMA_APC: + if (avctx->extradata && avctx->extradata_size >= 8) { + c->status[0].predictor = AV_RL32(avctx->extradata); + c->status[1].predictor = AV_RL32(avctx->extradata + 4); + } + break; + case AV_CODEC_ID_ADPCM_IMA_WS: + if (avctx->extradata && avctx->extradata_size >= 2) + c->vqa_version = AV_RL16(avctx->extradata); + break; + default: + break; + } + + switch(avctx->codec->id) { + case AV_CODEC_ID_ADPCM_IMA_QT: + case AV_CODEC_ID_ADPCM_IMA_WAV: + case AV_CODEC_ID_ADPCM_4XM: + case AV_CODEC_ID_ADPCM_XA: + case AV_CODEC_ID_ADPCM_EA_R1: + case AV_CODEC_ID_ADPCM_EA_R2: + case AV_CODEC_ID_ADPCM_EA_R3: + case AV_CODEC_ID_ADPCM_EA_XAS: + case AV_CODEC_ID_ADPCM_THP: + case AV_CODEC_ID_ADPCM_AFC: + case AV_CODEC_ID_ADPCM_DTK: + avctx->sample_fmt = AV_SAMPLE_FMT_S16P; + break; + case AV_CODEC_ID_ADPCM_IMA_WS: + avctx->sample_fmt = c->vqa_version == 3 ? AV_SAMPLE_FMT_S16P : + AV_SAMPLE_FMT_S16; + break; + default: + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + } + + return 0; +} + +static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble, int shift) +{ + int step_index; + int predictor; + int sign, delta, diff, step; + + step = ff_adpcm_step_table[c->step_index]; + step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble]; + step_index = av_clip(step_index, 0, 88); + + sign = nibble & 8; + delta = nibble & 7; + /* perform direct multiplication instead of series of jumps proposed by + * the reference ADPCM implementation since modern CPUs can do the mults + * quickly enough */ + diff = ((2 * delta + 1) * step) >> shift; + predictor = c->predictor; + if (sign) predictor -= diff; + else predictor += diff; + + c->predictor = av_clip_int16(predictor); + c->step_index = step_index; + + return (short)c->predictor; +} + +static inline int16_t adpcm_ima_wav_expand_nibble(ADPCMChannelStatus *c, GetBitContext *gb, int bps) +{ + int nibble, step_index, predictor, sign, delta, diff, step, shift; + + shift = bps - 1; + nibble = get_bits_le(gb, bps), + step = ff_adpcm_step_table[c->step_index]; + step_index = c->step_index + ff_adpcm_index_tables[bps - 2][nibble]; + step_index = av_clip(step_index, 0, 88); + + sign = nibble & (1 << shift); + delta = nibble & ((1 << shift) - 1); + diff = ((2 * delta + 1) * step) >> shift; + predictor = c->predictor; + if (sign) predictor -= diff; + else predictor += diff; + + c->predictor = av_clip_int16(predictor); + c->step_index = step_index; + + return (int16_t)c->predictor; +} + +static inline int adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble, int shift) +{ + int step_index; + int predictor; + int diff, step; + + step = ff_adpcm_step_table[c->step_index]; + step_index = c->step_index + ff_adpcm_index_table[nibble]; + step_index = av_clip(step_index, 0, 88); + + diff = step >> 3; + if (nibble & 4) diff += step; + if (nibble & 2) diff += step >> 1; + if (nibble & 1) diff += step >> 2; + + if (nibble & 8) + predictor = c->predictor - diff; + else + predictor = c->predictor + diff; + + c->predictor = av_clip_int16(predictor); + c->step_index = step_index; + + return c->predictor; +} + +static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, int nibble) +{ + int predictor; + + predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 64; + predictor += ((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; + + c->sample2 = c->sample1; + c->sample1 = av_clip_int16(predictor); + c->idelta = (ff_adpcm_AdaptationTable[(int)nibble] * c->idelta) >> 8; + if (c->idelta < 16) c->idelta = 16; + + return c->sample1; +} + +static inline short adpcm_ima_oki_expand_nibble(ADPCMChannelStatus *c, int nibble) +{ + int step_index, predictor, sign, delta, diff, step; + + step = ff_adpcm_oki_step_table[c->step_index]; + step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble]; + step_index = av_clip(step_index, 0, 48); + + sign = nibble & 8; + delta = nibble & 7; + diff = ((2 * delta + 1) * step) >> 3; + predictor = c->predictor; + if (sign) predictor -= diff; + else predictor += diff; + + c->predictor = av_clip(predictor, -2048, 2047); + c->step_index = step_index; + + return c->predictor << 4; +} + +static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble) +{ + int sign, delta, diff; + int new_step; + + sign = nibble & 8; + delta = nibble & 7; + /* perform direct multiplication instead of series of jumps proposed by + * the reference ADPCM implementation since modern CPUs can do the mults + * quickly enough */ + diff = ((2 * delta + 1) * c->step) >> 3; + /* predictor update is not so trivial: predictor is multiplied on 254/256 before updating */ + c->predictor = ((c->predictor * 254) >> 8) + (sign ? -diff : diff); + c->predictor = av_clip_int16(c->predictor); + /* calculate new step and clamp it to range 511..32767 */ + new_step = (ff_adpcm_AdaptationTable[nibble & 7] * c->step) >> 8; + c->step = av_clip(new_step, 511, 32767); + + return (short)c->predictor; +} + +static inline short adpcm_sbpro_expand_nibble(ADPCMChannelStatus *c, char nibble, int size, int shift) +{ + int sign, delta, diff; + + sign = nibble & (1<<(size-1)); + delta = nibble & ((1<<(size-1))-1); + diff = delta << (7 + c->step + shift); + + /* clamp result */ + c->predictor = av_clip(c->predictor + (sign ? -diff : diff), -16384,16256); + + /* calculate new step */ + if (delta >= (2*size - 3) && c->step < 3) + c->step++; + else if (delta == 0 && c->step > 0) + c->step--; + + return (short) c->predictor; +} + +static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned char nibble) +{ + if(!c->step) { + c->predictor = 0; + c->step = 127; + } + + c->predictor += (c->step * ff_adpcm_yamaha_difflookup[nibble]) / 8; + c->predictor = av_clip_int16(c->predictor); + c->step = (c->step * ff_adpcm_yamaha_indexscale[nibble]) >> 8; + c->step = av_clip(c->step, 127, 24567); + return c->predictor; +} + +static int xa_decode(AVCodecContext *avctx, int16_t *out0, int16_t *out1, + const uint8_t *in, ADPCMChannelStatus *left, + ADPCMChannelStatus *right, int channels, int sample_offset) +{ + int i, j; + int shift,filter,f0,f1; + int s_1,s_2; + int d,s,t; + + out0 += sample_offset; + if (channels == 1) + out1 = out0 + 28; + else + out1 += sample_offset; + + for(i=0;i<4;i++) { + shift = 12 - (in[4+i*2] & 15); + filter = in[4+i*2] >> 4; + if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) { + avpriv_request_sample(avctx, "unknown XA-ADPCM filter %d", filter); + filter=0; + } + f0 = xa_adpcm_table[filter][0]; + f1 = xa_adpcm_table[filter][1]; + + s_1 = left->sample1; + s_2 = left->sample2; + + for(j=0;j<28;j++) { + d = in[16+i+j*4]; + + t = sign_extend(d, 4); + s = ( t<>6); + s_2 = s_1; + s_1 = av_clip_int16(s); + out0[j] = s_1; + } + + if (channels == 2) { + left->sample1 = s_1; + left->sample2 = s_2; + s_1 = right->sample1; + s_2 = right->sample2; + } + + shift = 12 - (in[5+i*2] & 15); + filter = in[5+i*2] >> 4; + if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) { + avpriv_request_sample(avctx, "unknown XA-ADPCM filter %d", filter); + filter=0; + } + + f0 = xa_adpcm_table[filter][0]; + f1 = xa_adpcm_table[filter][1]; + + for(j=0;j<28;j++) { + d = in[16+i+j*4]; + + t = sign_extend(d >> 4, 4); + s = ( t<>6); + s_2 = s_1; + s_1 = av_clip_int16(s); + out1[j] = s_1; + } + + if (channels == 2) { + right->sample1 = s_1; + right->sample2 = s_2; + } else { + left->sample1 = s_1; + left->sample2 = s_2; + } + + out0 += 28 * (3 - channels); + out1 += 28 * (3 - channels); + } + + return 0; +} + +static void adpcm_swf_decode(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int16_t *samples) +{ + ADPCMDecodeContext *c = avctx->priv_data; + GetBitContext gb; + const int *table; + int k0, signmask, nb_bits, count; + int size = buf_size*8; + int i; + + init_get_bits(&gb, buf, size); + + //read bits & initial values + nb_bits = get_bits(&gb, 2)+2; + table = swf_index_tables[nb_bits-2]; + k0 = 1 << (nb_bits-2); + signmask = 1 << (nb_bits-1); + + while (get_bits_count(&gb) <= size - 22*avctx->channels) { + for (i = 0; i < avctx->channels; i++) { + *samples++ = c->status[i].predictor = get_sbits(&gb, 16); + c->status[i].step_index = get_bits(&gb, 6); + } + + for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) { + int i; + + for (i = 0; i < avctx->channels; i++) { + // similar to IMA adpcm + int delta = get_bits(&gb, nb_bits); + int step = ff_adpcm_step_table[c->status[i].step_index]; + long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 + int k = k0; + + do { + if (delta & k) + vpdiff += step; + step >>= 1; + k >>= 1; + } while(k); + vpdiff += step; + + if (delta & signmask) + c->status[i].predictor -= vpdiff; + else + c->status[i].predictor += vpdiff; + + c->status[i].step_index += table[delta & (~signmask)]; + + c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88); + c->status[i].predictor = av_clip_int16(c->status[i].predictor); + + *samples++ = c->status[i].predictor; + } + } + } +} + +/** + * Get the number of samples that will be decoded from the packet. + * In one case, this is actually the maximum number of samples possible to + * decode with the given buf_size. + * + * @param[out] coded_samples set to the number of samples as coded in the + * packet, or 0 if the codec does not encode the + * number of samples in each frame. + */ +static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, + int buf_size, int *coded_samples) +{ + ADPCMDecodeContext *s = avctx->priv_data; + int nb_samples = 0; + int ch = avctx->channels; + int has_coded_samples = 0; + int header_size; + + *coded_samples = 0; + + if(ch <= 0) + return 0; + + switch (avctx->codec->id) { + /* constant, only check buf_size */ + case AV_CODEC_ID_ADPCM_EA_XAS: + if (buf_size < 76 * ch) + return 0; + nb_samples = 128; + break; + case AV_CODEC_ID_ADPCM_IMA_QT: + if (buf_size < 34 * ch) + return 0; + nb_samples = 64; + break; + /* simple 4-bit adpcm */ + case AV_CODEC_ID_ADPCM_CT: + case AV_CODEC_ID_ADPCM_IMA_APC: + case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: + case AV_CODEC_ID_ADPCM_IMA_OKI: + case AV_CODEC_ID_ADPCM_IMA_WS: + case AV_CODEC_ID_ADPCM_YAMAHA: + nb_samples = buf_size * 2 / ch; + break; + default: break; + } + if (nb_samples) + return nb_samples; + + /* simple 4-bit adpcm, with header */ + header_size = 0; + switch (avctx->codec->id) { + case AV_CODEC_ID_ADPCM_4XM: + case AV_CODEC_ID_ADPCM_IMA_ISS: header_size = 4 * ch; break; + case AV_CODEC_ID_ADPCM_IMA_AMV: header_size = 8; break; + case AV_CODEC_ID_ADPCM_IMA_SMJPEG: header_size = 4 * ch; break; + default: break; + } + if (header_size > 0) + return (buf_size - header_size) * 2 / ch; + + /* more complex formats */ + switch (avctx->codec->id) { + case AV_CODEC_ID_ADPCM_EA: + has_coded_samples = 1; + *coded_samples = bytestream2_get_le32(gb); + *coded_samples -= *coded_samples % 28; + nb_samples = (buf_size - 12) / 30 * 28; + break; + case AV_CODEC_ID_ADPCM_IMA_EA_EACS: + has_coded_samples = 1; + *coded_samples = bytestream2_get_le32(gb); + nb_samples = (buf_size - (4 + 8 * ch)) * 2 / ch; + break; + case AV_CODEC_ID_ADPCM_EA_MAXIS_XA: + nb_samples = (buf_size - ch) / ch * 2; + break; + case AV_CODEC_ID_ADPCM_EA_R1: + case AV_CODEC_ID_ADPCM_EA_R2: + case AV_CODEC_ID_ADPCM_EA_R3: + /* maximum number of samples */ + /* has internal offsets and a per-frame switch to signal raw 16-bit */ + has_coded_samples = 1; + switch (avctx->codec->id) { + case AV_CODEC_ID_ADPCM_EA_R1: + header_size = 4 + 9 * ch; + *coded_samples = bytestream2_get_le32(gb); + break; + case AV_CODEC_ID_ADPCM_EA_R2: + header_size = 4 + 5 * ch; + *coded_samples = bytestream2_get_le32(gb); + break; + case AV_CODEC_ID_ADPCM_EA_R3: + header_size = 4 + 5 * ch; + *coded_samples = bytestream2_get_be32(gb); + break; + default: break; + } + *coded_samples -= *coded_samples % 28; + nb_samples = (buf_size - header_size) * 2 / ch; + nb_samples -= nb_samples % 28; + break; + case AV_CODEC_ID_ADPCM_IMA_DK3: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = ((buf_size - 16) * 2 / 3 * 4) / ch; + break; + case AV_CODEC_ID_ADPCM_IMA_DK4: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch; + break; + case AV_CODEC_ID_ADPCM_IMA_RAD: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = (buf_size - 4 * ch) * 2 / ch; + break; + case AV_CODEC_ID_ADPCM_IMA_WAV: + { + int bsize = ff_adpcm_ima_block_sizes[avctx->bits_per_coded_sample - 2]; + int bsamples = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2]; + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = 1 + (buf_size - 4 * ch) / (bsize * ch) * bsamples; + break; + } + case AV_CODEC_ID_ADPCM_MS: + if (avctx->block_align > 0) + buf_size = FFMIN(buf_size, avctx->block_align); + nb_samples = 2 + (buf_size - 7 * ch) * 2 / ch; + break; + case AV_CODEC_ID_ADPCM_SBPRO_2: + case AV_CODEC_ID_ADPCM_SBPRO_3: + case AV_CODEC_ID_ADPCM_SBPRO_4: + { + int samples_per_byte; + switch (avctx->codec->id) { + case AV_CODEC_ID_ADPCM_SBPRO_2: samples_per_byte = 4; break; + case AV_CODEC_ID_ADPCM_SBPRO_3: samples_per_byte = 3; break; + case AV_CODEC_ID_ADPCM_SBPRO_4: samples_per_byte = 2; break; + default: break; + } + if (!s->status[0].step_index) { + nb_samples++; + buf_size -= ch; + } + nb_samples += buf_size * samples_per_byte / ch; + break; + } + case AV_CODEC_ID_ADPCM_SWF: + { + int buf_bits = buf_size * 8 - 2; + int nbits = (bytestream2_get_byte(gb) >> 6) + 2; + int block_hdr_size = 22 * ch; + int block_size = block_hdr_size + nbits * ch * 4095; + int nblocks = buf_bits / block_size; + int bits_left = buf_bits - nblocks * block_size; + nb_samples = nblocks * 4096; + if (bits_left >= block_hdr_size) + nb_samples += 1 + (bits_left - block_hdr_size) / (nbits * ch); + break; + } + case AV_CODEC_ID_ADPCM_THP: + if (avctx->extradata) { + nb_samples = buf_size / (8 * ch) * 14; + break; + } + has_coded_samples = 1; + bytestream2_skip(gb, 4); // channel size + *coded_samples = bytestream2_get_be32(gb); + *coded_samples -= *coded_samples % 14; + nb_samples = (buf_size - (8 + 36 * ch)) / (8 * ch) * 14; + break; + case AV_CODEC_ID_ADPCM_AFC: + nb_samples = buf_size / (9 * ch) * 16; + break; + case AV_CODEC_ID_ADPCM_XA: + nb_samples = (buf_size / 128) * 224 / ch; + break; + case AV_CODEC_ID_ADPCM_DTK: + nb_samples = buf_size / (16 * ch) * 28; + break; + default: break; + } + + /* validate coded sample count */ + if (has_coded_samples && (*coded_samples <= 0 || *coded_samples > nb_samples)) + return AVERROR_INVALIDDATA; + + return nb_samples; +} + +static int adpcm_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + ADPCMDecodeContext *c = avctx->priv_data; + ADPCMChannelStatus *cs; + int n, m, channel, i; + short *samples; + int16_t **samples_p; + int st; /* stereo */ + int count1, count2; + int nb_samples, coded_samples, ret; + GetByteContext gb; + + bytestream2_init(&gb, buf, buf_size); + nb_samples = get_nb_samples(avctx, &gb, buf_size, &coded_samples); + if (nb_samples <= 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of samples in packet\n"); + return AVERROR_INVALIDDATA; + } + + /* get output buffer */ + frame->nb_samples = nb_samples; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + samples = (short *)frame->data[0]; + samples_p = (int16_t **)frame->extended_data; + + /* use coded_samples when applicable */ + /* it is always <= nb_samples, so the output buffer will be large enough */ + if (coded_samples) { + if (coded_samples != nb_samples) + av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n"); + frame->nb_samples = nb_samples = coded_samples; + } + + st = avctx->channels == 2 ? 1 : 0; + + switch(avctx->codec->id) { + case AV_CODEC_ID_ADPCM_IMA_QT: + /* In QuickTime, IMA is encoded by chunks of 34 bytes (=64 samples). + Channel data is interleaved per-chunk. */ + for (channel = 0; channel < avctx->channels; channel++) { + int predictor; + int step_index; + cs = &(c->status[channel]); + /* (pppppp) (piiiiiii) */ + + /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */ + predictor = sign_extend(bytestream2_get_be16u(&gb), 16); + step_index = predictor & 0x7F; + predictor &= ~0x7F; + + if (cs->step_index == step_index) { + int diff = predictor - cs->predictor; + if (diff < 0) + diff = - diff; + if (diff > 0x7f) + goto update; + } else { + update: + cs->step_index = step_index; + cs->predictor = predictor; + } + + if (cs->step_index > 88u){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + channel, cs->step_index); + return AVERROR_INVALIDDATA; + } + + samples = samples_p[channel]; + + for (m = 0; m < 64; m += 2) { + int byte = bytestream2_get_byteu(&gb); + samples[m ] = adpcm_ima_qt_expand_nibble(cs, byte & 0x0F, 3); + samples[m + 1] = adpcm_ima_qt_expand_nibble(cs, byte >> 4 , 3); + } + } + break; + case AV_CODEC_ID_ADPCM_IMA_WAV: + for(i=0; ichannels; i++){ + cs = &(c->status[i]); + cs->predictor = samples_p[i][0] = sign_extend(bytestream2_get_le16u(&gb), 16); + + cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16); + if (cs->step_index > 88u){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + i, cs->step_index); + return AVERROR_INVALIDDATA; + } + } + + if (avctx->bits_per_coded_sample != 4) { + int samples_per_block = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2]; + GetBitContext g; + + init_get_bits8(&g, gb.buffer, bytestream2_get_bytes_left(&gb)); + for (n = 0; n < (nb_samples - 1) / samples_per_block; n++) { + for (i = 0; i < avctx->channels; i++) { + cs = &c->status[i]; + samples = &samples_p[i][1 + n * samples_per_block]; + for (m = 0; m < samples_per_block; m++) { + samples[m] = adpcm_ima_wav_expand_nibble(cs, &g, + avctx->bits_per_coded_sample); + } + } + } + bytestream2_skip(&gb, avctx->block_align - avctx->channels * 4); + } else { + for (n = 0; n < (nb_samples - 1) / 8; n++) { + for (i = 0; i < avctx->channels; i++) { + cs = &c->status[i]; + samples = &samples_p[i][1 + n * 8]; + for (m = 0; m < 8; m += 2) { + int v = bytestream2_get_byteu(&gb); + samples[m ] = adpcm_ima_expand_nibble(cs, v & 0x0F, 3); + samples[m + 1] = adpcm_ima_expand_nibble(cs, v >> 4 , 3); + } + } + } + } + break; + case AV_CODEC_ID_ADPCM_4XM: + for (i = 0; i < avctx->channels; i++) + c->status[i].predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + + for (i = 0; i < avctx->channels; i++) { + c->status[i].step_index = sign_extend(bytestream2_get_le16u(&gb), 16); + if (c->status[i].step_index > 88u) { + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + i, c->status[i].step_index); + return AVERROR_INVALIDDATA; + } + } + + for (i = 0; i < avctx->channels; i++) { + samples = (int16_t *)frame->data[i]; + cs = &c->status[i]; + for (n = nb_samples >> 1; n > 0; n--) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(cs, v & 0x0F, 4); + *samples++ = adpcm_ima_expand_nibble(cs, v >> 4 , 4); + } + } + break; + case AV_CODEC_ID_ADPCM_MS: + { + int block_predictor; + + block_predictor = bytestream2_get_byteu(&gb); + if (block_predictor > 6) { + av_log(avctx, AV_LOG_ERROR, "ERROR: block_predictor[0] = %d\n", + block_predictor); + return AVERROR_INVALIDDATA; + } + c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor]; + c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor]; + if (st) { + block_predictor = bytestream2_get_byteu(&gb); + if (block_predictor > 6) { + av_log(avctx, AV_LOG_ERROR, "ERROR: block_predictor[1] = %d\n", + block_predictor); + return AVERROR_INVALIDDATA; + } + c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor]; + c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor]; + } + c->status[0].idelta = sign_extend(bytestream2_get_le16u(&gb), 16); + if (st){ + c->status[1].idelta = sign_extend(bytestream2_get_le16u(&gb), 16); + } + + c->status[0].sample1 = sign_extend(bytestream2_get_le16u(&gb), 16); + if (st) c->status[1].sample1 = sign_extend(bytestream2_get_le16u(&gb), 16); + c->status[0].sample2 = sign_extend(bytestream2_get_le16u(&gb), 16); + if (st) c->status[1].sample2 = sign_extend(bytestream2_get_le16u(&gb), 16); + + *samples++ = c->status[0].sample2; + if (st) *samples++ = c->status[1].sample2; + *samples++ = c->status[0].sample1; + if (st) *samples++ = c->status[1].sample1; + for(n = (nb_samples - 2) >> (1 - st); n > 0; n--) { + int byte = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ms_expand_nibble(&c->status[0 ], byte >> 4 ); + *samples++ = adpcm_ms_expand_nibble(&c->status[st], byte & 0x0F); + } + break; + } + case AV_CODEC_ID_ADPCM_IMA_DK4: + for (channel = 0; channel < avctx->channels; channel++) { + cs = &c->status[channel]; + cs->predictor = *samples++ = sign_extend(bytestream2_get_le16u(&gb), 16); + cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16); + if (cs->step_index > 88u){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + channel, cs->step_index); + return AVERROR_INVALIDDATA; + } + } + for (n = (nb_samples - 1) >> (1 - st); n > 0; n--) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 , 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); + } + break; + case AV_CODEC_ID_ADPCM_IMA_DK3: + { + int last_byte = 0; + int nibble; + int decode_top_nibble_next = 0; + int diff_channel; + const int16_t *samples_end = samples + avctx->channels * nb_samples; + + bytestream2_skipu(&gb, 10); + c->status[0].predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + c->status[1].predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + c->status[0].step_index = bytestream2_get_byteu(&gb); + c->status[1].step_index = bytestream2_get_byteu(&gb); + if (c->status[0].step_index > 88u || c->status[1].step_index > 88u){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i/%i\n", + c->status[0].step_index, c->status[1].step_index); + return AVERROR_INVALIDDATA; + } + /* sign extend the predictors */ + diff_channel = c->status[1].predictor; + + /* DK3 ADPCM support macro */ +#define DK3_GET_NEXT_NIBBLE() \ + if (decode_top_nibble_next) { \ + nibble = last_byte >> 4; \ + decode_top_nibble_next = 0; \ + } else { \ + last_byte = bytestream2_get_byteu(&gb); \ + nibble = last_byte & 0x0F; \ + decode_top_nibble_next = 1; \ + } + + while (samples < samples_end) { + + /* for this algorithm, c->status[0] is the sum channel and + * c->status[1] is the diff channel */ + + /* process the first predictor of the sum channel */ + DK3_GET_NEXT_NIBBLE(); + adpcm_ima_expand_nibble(&c->status[0], nibble, 3); + + /* process the diff channel predictor */ + DK3_GET_NEXT_NIBBLE(); + adpcm_ima_expand_nibble(&c->status[1], nibble, 3); + + /* process the first pair of stereo PCM samples */ + diff_channel = (diff_channel + c->status[1].predictor) / 2; + *samples++ = c->status[0].predictor + c->status[1].predictor; + *samples++ = c->status[0].predictor - c->status[1].predictor; + + /* process the second predictor of the sum channel */ + DK3_GET_NEXT_NIBBLE(); + adpcm_ima_expand_nibble(&c->status[0], nibble, 3); + + /* process the second pair of stereo PCM samples */ + diff_channel = (diff_channel + c->status[1].predictor) / 2; + *samples++ = c->status[0].predictor + c->status[1].predictor; + *samples++ = c->status[0].predictor - c->status[1].predictor; + } + break; + } + case AV_CODEC_ID_ADPCM_IMA_ISS: + for (channel = 0; channel < avctx->channels; channel++) { + cs = &c->status[channel]; + cs->predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16); + if (cs->step_index > 88u){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + channel, cs->step_index); + return AVERROR_INVALIDDATA; + } + } + + for (n = nb_samples >> (1 - st); n > 0; n--) { + int v1, v2; + int v = bytestream2_get_byteu(&gb); + /* nibbles are swapped for mono */ + if (st) { + v1 = v >> 4; + v2 = v & 0x0F; + } else { + v2 = v >> 4; + v1 = v & 0x0F; + } + *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v1, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], v2, 3); + } + break; + case AV_CODEC_ID_ADPCM_IMA_APC: + while (bytestream2_get_bytes_left(&gb) > 0) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4 , 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); + } + break; + case AV_CODEC_ID_ADPCM_IMA_OKI: + while (bytestream2_get_bytes_left(&gb) > 0) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_oki_expand_nibble(&c->status[0], v >> 4 ); + *samples++ = adpcm_ima_oki_expand_nibble(&c->status[st], v & 0x0F); + } + break; + case AV_CODEC_ID_ADPCM_IMA_RAD: + for (channel = 0; channel < avctx->channels; channel++) { + cs = &c->status[channel]; + cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16); + cs->predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + if (cs->step_index > 88u){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + channel, cs->step_index); + return AVERROR_INVALIDDATA; + } + } + for (n = 0; n < nb_samples / 2; n++) { + int byte[2]; + + byte[0] = bytestream2_get_byteu(&gb); + if (st) + byte[1] = bytestream2_get_byteu(&gb); + for(channel = 0; channel < avctx->channels; channel++) { + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] & 0x0F, 3); + } + for(channel = 0; channel < avctx->channels; channel++) { + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], byte[channel] >> 4 , 3); + } + } + break; + case AV_CODEC_ID_ADPCM_IMA_WS: + if (c->vqa_version == 3) { + for (channel = 0; channel < avctx->channels; channel++) { + int16_t *smp = samples_p[channel]; + + for (n = nb_samples / 2; n > 0; n--) { + int v = bytestream2_get_byteu(&gb); + *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); + *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); + } + } + } else { + for (n = nb_samples / 2; n > 0; n--) { + for (channel = 0; channel < avctx->channels; channel++) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); + samples[st] = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); + } + samples += avctx->channels; + } + } + bytestream2_seek(&gb, 0, SEEK_END); + break; + case AV_CODEC_ID_ADPCM_XA: + { + int16_t *out0 = samples_p[0]; + int16_t *out1 = samples_p[1]; + int samples_per_block = 28 * (3 - avctx->channels) * 4; + int sample_offset = 0; + while (bytestream2_get_bytes_left(&gb) >= 128) { + if ((ret = xa_decode(avctx, out0, out1, buf + bytestream2_tell(&gb), + &c->status[0], &c->status[1], + avctx->channels, sample_offset)) < 0) + return ret; + bytestream2_skipu(&gb, 128); + sample_offset += samples_per_block; + } + break; + } + case AV_CODEC_ID_ADPCM_IMA_EA_EACS: + for (i=0; i<=st; i++) { + c->status[i].step_index = bytestream2_get_le32u(&gb); + if (c->status[i].step_index > 88u) { + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index[%d] = %i\n", + i, c->status[i].step_index); + return AVERROR_INVALIDDATA; + } + } + for (i=0; i<=st; i++) + c->status[i].predictor = bytestream2_get_le32u(&gb); + + for (n = nb_samples >> (1 - st); n > 0; n--) { + int byte = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], byte >> 4, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], byte & 0x0F, 3); + } + break; + case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: + for (n = nb_samples >> (1 - st); n > 0; n--) { + int byte = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], byte >> 4, 6); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], byte & 0x0F, 6); + } + break; + case AV_CODEC_ID_ADPCM_EA: + { + int previous_left_sample, previous_right_sample; + int current_left_sample, current_right_sample; + int next_left_sample, next_right_sample; + int coeff1l, coeff2l, coeff1r, coeff2r; + int shift_left, shift_right; + + /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces, + each coding 28 stereo samples. */ + + if(avctx->channels != 2) + return AVERROR_INVALIDDATA; + + current_left_sample = sign_extend(bytestream2_get_le16u(&gb), 16); + previous_left_sample = sign_extend(bytestream2_get_le16u(&gb), 16); + current_right_sample = sign_extend(bytestream2_get_le16u(&gb), 16); + previous_right_sample = sign_extend(bytestream2_get_le16u(&gb), 16); + + for (count1 = 0; count1 < nb_samples / 28; count1++) { + int byte = bytestream2_get_byteu(&gb); + coeff1l = ea_adpcm_table[ byte >> 4 ]; + coeff2l = ea_adpcm_table[(byte >> 4 ) + 4]; + coeff1r = ea_adpcm_table[ byte & 0x0F]; + coeff2r = ea_adpcm_table[(byte & 0x0F) + 4]; + + byte = bytestream2_get_byteu(&gb); + shift_left = 20 - (byte >> 4); + shift_right = 20 - (byte & 0x0F); + + for (count2 = 0; count2 < 28; count2++) { + byte = bytestream2_get_byteu(&gb); + next_left_sample = sign_extend(byte >> 4, 4) << shift_left; + next_right_sample = sign_extend(byte, 4) << shift_right; + + next_left_sample = (next_left_sample + + (current_left_sample * coeff1l) + + (previous_left_sample * coeff2l) + 0x80) >> 8; + next_right_sample = (next_right_sample + + (current_right_sample * coeff1r) + + (previous_right_sample * coeff2r) + 0x80) >> 8; + + previous_left_sample = current_left_sample; + current_left_sample = av_clip_int16(next_left_sample); + previous_right_sample = current_right_sample; + current_right_sample = av_clip_int16(next_right_sample); + *samples++ = current_left_sample; + *samples++ = current_right_sample; + } + } + + bytestream2_skip(&gb, 2); // Skip terminating 0x0000 + + break; + } + case AV_CODEC_ID_ADPCM_EA_MAXIS_XA: + { + int coeff[2][2], shift[2]; + + for(channel = 0; channel < avctx->channels; channel++) { + int byte = bytestream2_get_byteu(&gb); + for (i=0; i<2; i++) + coeff[channel][i] = ea_adpcm_table[(byte >> 4) + 4*i]; + shift[channel] = 20 - (byte & 0x0F); + } + for (count1 = 0; count1 < nb_samples / 2; count1++) { + int byte[2]; + + byte[0] = bytestream2_get_byteu(&gb); + if (st) byte[1] = bytestream2_get_byteu(&gb); + for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */ + for(channel = 0; channel < avctx->channels; channel++) { + int sample = sign_extend(byte[channel] >> i, 4) << shift[channel]; + sample = (sample + + c->status[channel].sample1 * coeff[channel][0] + + c->status[channel].sample2 * coeff[channel][1] + 0x80) >> 8; + c->status[channel].sample2 = c->status[channel].sample1; + c->status[channel].sample1 = av_clip_int16(sample); + *samples++ = c->status[channel].sample1; + } + } + } + bytestream2_seek(&gb, 0, SEEK_END); + break; + } + case AV_CODEC_ID_ADPCM_EA_R1: + case AV_CODEC_ID_ADPCM_EA_R2: + case AV_CODEC_ID_ADPCM_EA_R3: { + /* channel numbering + 2chan: 0=fl, 1=fr + 4chan: 0=fl, 1=rl, 2=fr, 3=rr + 6chan: 0=fl, 1=c, 2=fr, 3=rl, 4=rr, 5=sub */ + const int big_endian = avctx->codec->id == AV_CODEC_ID_ADPCM_EA_R3; + int previous_sample, current_sample, next_sample; + int coeff1, coeff2; + int shift; + unsigned int channel; + uint16_t *samplesC; + int count = 0; + int offsets[6]; + + for (channel=0; channelchannels; channel++) + offsets[channel] = (big_endian ? bytestream2_get_be32(&gb) : + bytestream2_get_le32(&gb)) + + (avctx->channels + 1) * 4; + + for (channel=0; channelchannels; channel++) { + bytestream2_seek(&gb, offsets[channel], SEEK_SET); + samplesC = (uint16_t *) samples_p[channel]; + + if (avctx->codec->id == AV_CODEC_ID_ADPCM_EA_R1) { + current_sample = sign_extend(bytestream2_get_le16(&gb), 16); + previous_sample = sign_extend(bytestream2_get_le16(&gb), 16); + } else { + current_sample = c->status[channel].predictor; + previous_sample = c->status[channel].prev_sample; + } + + for (count1 = 0; count1 < nb_samples / 28; count1++) { + int byte = bytestream2_get_byte(&gb); + if (byte == 0xEE) { /* only seen in R2 and R3 */ + current_sample = sign_extend(bytestream2_get_be16(&gb), 16); + previous_sample = sign_extend(bytestream2_get_be16(&gb), 16); + + for (count2=0; count2<28; count2++) + *samplesC++ = sign_extend(bytestream2_get_be16(&gb), 16); + } else { + coeff1 = ea_adpcm_table[ byte >> 4 ]; + coeff2 = ea_adpcm_table[(byte >> 4) + 4]; + shift = 20 - (byte & 0x0F); + + for (count2=0; count2<28; count2++) { + if (count2 & 1) + next_sample = sign_extend(byte, 4) << shift; + else { + byte = bytestream2_get_byte(&gb); + next_sample = sign_extend(byte >> 4, 4) << shift; + } + + next_sample += (current_sample * coeff1) + + (previous_sample * coeff2); + next_sample = av_clip_int16(next_sample >> 8); + + previous_sample = current_sample; + current_sample = next_sample; + *samplesC++ = current_sample; + } + } + } + if (!count) { + count = count1; + } else if (count != count1) { + av_log(avctx, AV_LOG_WARNING, "per-channel sample count mismatch\n"); + count = FFMAX(count, count1); + } + + if (avctx->codec->id != AV_CODEC_ID_ADPCM_EA_R1) { + c->status[channel].predictor = current_sample; + c->status[channel].prev_sample = previous_sample; + } + } + + frame->nb_samples = count * 28; + bytestream2_seek(&gb, 0, SEEK_END); + break; + } + case AV_CODEC_ID_ADPCM_EA_XAS: + for (channel=0; channelchannels; channel++) { + int coeff[2][4], shift[4]; + int16_t *s = samples_p[channel]; + for (n = 0; n < 4; n++, s += 32) { + int val = sign_extend(bytestream2_get_le16u(&gb), 16); + for (i=0; i<2; i++) + coeff[i][n] = ea_adpcm_table[(val&0x0F)+4*i]; + s[0] = val & ~0x0F; + + val = sign_extend(bytestream2_get_le16u(&gb), 16); + shift[n] = 20 - (val & 0x0F); + s[1] = val & ~0x0F; + } + + for (m=2; m<32; m+=2) { + s = &samples_p[channel][m]; + for (n = 0; n < 4; n++, s += 32) { + int level, pred; + int byte = bytestream2_get_byteu(&gb); + + level = sign_extend(byte >> 4, 4) << shift[n]; + pred = s[-1] * coeff[0][n] + s[-2] * coeff[1][n]; + s[0] = av_clip_int16((level + pred + 0x80) >> 8); + + level = sign_extend(byte, 4) << shift[n]; + pred = s[0] * coeff[0][n] + s[-1] * coeff[1][n]; + s[1] = av_clip_int16((level + pred + 0x80) >> 8); + } + } + } + break; + case AV_CODEC_ID_ADPCM_IMA_AMV: + c->status[0].predictor = sign_extend(bytestream2_get_le16u(&gb), 16); + c->status[0].step_index = bytestream2_get_le16u(&gb); + bytestream2_skipu(&gb, 4); + if (c->status[0].step_index > 88u) { + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", + c->status[0].step_index); + return AVERROR_INVALIDDATA; + } + + for (n = nb_samples >> (1 - st); n > 0; n--) { + int v = bytestream2_get_byteu(&gb); + + *samples++ = adpcm_ima_expand_nibble(&c->status[0], v >> 4, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], v & 0xf, 3); + } + break; + case AV_CODEC_ID_ADPCM_IMA_SMJPEG: + for (i = 0; i < avctx->channels; i++) { + c->status[i].predictor = sign_extend(bytestream2_get_be16u(&gb), 16); + c->status[i].step_index = bytestream2_get_byteu(&gb); + bytestream2_skipu(&gb, 1); + if (c->status[i].step_index > 88u) { + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", + c->status[i].step_index); + return AVERROR_INVALIDDATA; + } + } + + for (n = nb_samples >> (1 - st); n > 0; n--) { + int v = bytestream2_get_byteu(&gb); + + *samples++ = adpcm_ima_qt_expand_nibble(&c->status[0 ], v >> 4, 3); + *samples++ = adpcm_ima_qt_expand_nibble(&c->status[st], v & 0xf, 3); + } + break; + case AV_CODEC_ID_ADPCM_CT: + for (n = nb_samples >> (1 - st); n > 0; n--) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_ct_expand_nibble(&c->status[0 ], v >> 4 ); + *samples++ = adpcm_ct_expand_nibble(&c->status[st], v & 0x0F); + } + break; + case AV_CODEC_ID_ADPCM_SBPRO_4: + case AV_CODEC_ID_ADPCM_SBPRO_3: + case AV_CODEC_ID_ADPCM_SBPRO_2: + if (!c->status[0].step_index) { + /* the first byte is a raw sample */ + *samples++ = 128 * (bytestream2_get_byteu(&gb) - 0x80); + if (st) + *samples++ = 128 * (bytestream2_get_byteu(&gb) - 0x80); + c->status[0].step_index = 1; + nb_samples--; + } + if (avctx->codec->id == AV_CODEC_ID_ADPCM_SBPRO_4) { + for (n = nb_samples >> (1 - st); n > 0; n--) { + int byte = bytestream2_get_byteu(&gb); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + byte >> 4, 4, 0); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], + byte & 0x0F, 4, 0); + } + } else if (avctx->codec->id == AV_CODEC_ID_ADPCM_SBPRO_3) { + for (n = nb_samples / 3; n > 0; n--) { + int byte = bytestream2_get_byteu(&gb); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + byte >> 5 , 3, 0); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + (byte >> 2) & 0x07, 3, 0); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + byte & 0x03, 2, 0); + } + } else { + for (n = nb_samples >> (2 - st); n > 0; n--) { + int byte = bytestream2_get_byteu(&gb); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + byte >> 6 , 2, 2); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], + (byte >> 4) & 0x03, 2, 2); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + (byte >> 2) & 0x03, 2, 2); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], + byte & 0x03, 2, 2); + } + } + break; + case AV_CODEC_ID_ADPCM_SWF: + adpcm_swf_decode(avctx, buf, buf_size, samples); + bytestream2_seek(&gb, 0, SEEK_END); + break; + case AV_CODEC_ID_ADPCM_YAMAHA: + for (n = nb_samples >> (1 - st); n > 0; n--) { + int v = bytestream2_get_byteu(&gb); + *samples++ = adpcm_yamaha_expand_nibble(&c->status[0 ], v & 0x0F); + *samples++ = adpcm_yamaha_expand_nibble(&c->status[st], v >> 4 ); + } + break; + case AV_CODEC_ID_ADPCM_AFC: + { + int samples_per_block; + int blocks; + + if (avctx->extradata && avctx->extradata_size == 1 && avctx->extradata[0]) { + samples_per_block = avctx->extradata[0] / 16; + blocks = nb_samples / avctx->extradata[0]; + } else { + samples_per_block = nb_samples / 16; + blocks = 1; + } + + for (m = 0; m < blocks; m++) { + for (channel = 0; channel < avctx->channels; channel++) { + int prev1 = c->status[channel].sample1; + int prev2 = c->status[channel].sample2; + + samples = samples_p[channel] + m * 16; + /* Read in every sample for this channel. */ + for (i = 0; i < samples_per_block; i++) { + int byte = bytestream2_get_byteu(&gb); + int scale = 1 << (byte >> 4); + int index = byte & 0xf; + int factor1 = ff_adpcm_afc_coeffs[0][index]; + int factor2 = ff_adpcm_afc_coeffs[1][index]; + + /* Decode 16 samples. */ + for (n = 0; n < 16; n++) { + int32_t sampledat; + + if (n & 1) { + sampledat = sign_extend(byte, 4); + } else { + byte = bytestream2_get_byteu(&gb); + sampledat = sign_extend(byte >> 4, 4); + } + + sampledat = ((prev1 * factor1 + prev2 * factor2) + + ((sampledat * scale) << 11)) >> 11; + *samples = av_clip_int16(sampledat); + prev2 = prev1; + prev1 = *samples++; + } + } + + c->status[channel].sample1 = prev1; + c->status[channel].sample2 = prev2; + } + } + bytestream2_seek(&gb, 0, SEEK_END); + break; + } + case AV_CODEC_ID_ADPCM_THP: + { + int table[6][16]; + int ch; + + if (avctx->extradata) { + GetByteContext tb; + if (avctx->extradata_size < 32 * avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "Missing coeff table\n"); + return AVERROR_INVALIDDATA; + } + + bytestream2_init(&tb, avctx->extradata, avctx->extradata_size); + for (i = 0; i < avctx->channels; i++) + for (n = 0; n < 16; n++) + table[i][n] = sign_extend(bytestream2_get_be16u(&tb), 16); + } else { + for (i = 0; i < avctx->channels; i++) + for (n = 0; n < 16; n++) + table[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16); + + /* Initialize the previous sample. */ + for (i = 0; i < avctx->channels; i++) { + c->status[i].sample1 = sign_extend(bytestream2_get_be16u(&gb), 16); + c->status[i].sample2 = sign_extend(bytestream2_get_be16u(&gb), 16); + } + } + + for (ch = 0; ch < avctx->channels; ch++) { + samples = samples_p[ch]; + + /* Read in every sample for this channel. */ + for (i = 0; i < nb_samples / 14; i++) { + int byte = bytestream2_get_byteu(&gb); + int index = (byte >> 4) & 7; + unsigned int exp = byte & 0x0F; + int factor1 = table[ch][index * 2]; + int factor2 = table[ch][index * 2 + 1]; + + /* Decode 14 samples. */ + for (n = 0; n < 14; n++) { + int32_t sampledat; + + if (n & 1) { + sampledat = sign_extend(byte, 4); + } else { + byte = bytestream2_get_byteu(&gb); + sampledat = sign_extend(byte >> 4, 4); + } + + sampledat = ((c->status[ch].sample1 * factor1 + + c->status[ch].sample2 * factor2) >> 11) + (sampledat << exp); + *samples = av_clip_int16(sampledat); + c->status[ch].sample2 = c->status[ch].sample1; + c->status[ch].sample1 = *samples++; + } + } + } + break; + } + case AV_CODEC_ID_ADPCM_DTK: + for (channel = 0; channel < avctx->channels; channel++) { + samples = samples_p[channel]; + + /* Read in every sample for this channel. */ + for (i = 0; i < nb_samples / 28; i++) { + int byte, header; + if (channel) + bytestream2_skipu(&gb, 1); + header = bytestream2_get_byteu(&gb); + bytestream2_skipu(&gb, 3 - channel); + + /* Decode 28 samples. */ + for (n = 0; n < 28; n++) { + int32_t sampledat, prev; + + switch (header >> 4) { + case 1: + prev = (c->status[channel].sample1 * 0x3c); + break; + case 2: + prev = (c->status[channel].sample1 * 0x73) - (c->status[channel].sample2 * 0x34); + break; + case 3: + prev = (c->status[channel].sample1 * 0x62) - (c->status[channel].sample2 * 0x37); + break; + default: + prev = 0; + } + + prev = av_clip((prev + 0x20) >> 6, -0x200000, 0x1fffff); + + byte = bytestream2_get_byteu(&gb); + if (!channel) + sampledat = sign_extend(byte, 4); + else + sampledat = sign_extend(byte >> 4, 4); + + sampledat = (((sampledat << 12) >> (header & 0xf)) << 6) + prev; + *samples++ = av_clip_int16(sampledat >> 6); + c->status[channel].sample2 = c->status[channel].sample1; + c->status[channel].sample1 = sampledat; + } + } + if (!channel) + bytestream2_seek(&gb, 0, SEEK_SET); + } + break; + + default: + return -1; + } + + if (avpkt->size && bytestream2_tell(&gb) == 0) { + av_log(avctx, AV_LOG_ERROR, "Nothing consumed\n"); + return AVERROR_INVALIDDATA; + } + + *got_frame_ptr = 1; + + return bytestream2_tell(&gb); +} + + +static const enum AVSampleFormat sample_fmts_s16[] = { AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }; +static const enum AVSampleFormat sample_fmts_s16p[] = { AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }; +static const enum AVSampleFormat sample_fmts_both[] = { AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }; + +#define ADPCM_DECODER(id_, sample_fmts_, name_, long_name_) \ +AVCodec ff_ ## name_ ## _decoder = { \ + .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ + .type = AVMEDIA_TYPE_AUDIO, \ + .id = id_, \ + .priv_data_size = sizeof(ADPCMDecodeContext), \ + .init = adpcm_decode_init, \ + .decode = adpcm_decode_frame, \ + .capabilities = CODEC_CAP_DR1, \ + .sample_fmts = sample_fmts_, \ +} + +/* Note: Do not forget to add new entries to the Makefile as well. */ +ADPCM_DECODER(AV_CODEC_ID_ADPCM_4XM, sample_fmts_s16p, adpcm_4xm, "ADPCM 4X Movie"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_AFC, sample_fmts_s16p, adpcm_afc, "ADPCM Nintendo Gamecube AFC"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_CT, sample_fmts_s16, adpcm_ct, "ADPCM Creative Technology"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_DTK, sample_fmts_s16p, adpcm_dtk, "ADPCM Nintendo Gamecube DTK"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA, sample_fmts_s16, adpcm_ea, "ADPCM Electronic Arts"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_MAXIS_XA, sample_fmts_s16, adpcm_ea_maxis_xa, "ADPCM Electronic Arts Maxis CDROM XA"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R1, sample_fmts_s16p, adpcm_ea_r1, "ADPCM Electronic Arts R1"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R2, sample_fmts_s16p, adpcm_ea_r2, "ADPCM Electronic Arts R2"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R3, sample_fmts_s16p, adpcm_ea_r3, "ADPCM Electronic Arts R3"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_XAS, sample_fmts_s16p, adpcm_ea_xas, "ADPCM Electronic Arts XAS"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_AMV, sample_fmts_s16, adpcm_ima_amv, "ADPCM IMA AMV"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_APC, sample_fmts_s16, adpcm_ima_apc, "ADPCM IMA CRYO APC"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK3, sample_fmts_s16, adpcm_ima_dk3, "ADPCM IMA Duck DK3"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK4, sample_fmts_s16, adpcm_ima_dk4, "ADPCM IMA Duck DK4"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_EACS, sample_fmts_s16, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_OKI, sample_fmts_s16, adpcm_ima_oki, "ADPCM IMA Dialogic OKI"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_RAD, sample_fmts_s16, adpcm_ima_rad, "ADPCM IMA Radical"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_MS, sample_fmts_s16, adpcm_ms, "ADPCM Microsoft"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_2, sample_fmts_s16, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_3, sample_fmts_s16, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_4, sample_fmts_s16, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_SWF, sample_fmts_s16, adpcm_swf, "ADPCM Shockwave Flash"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_THP, sample_fmts_s16p, adpcm_thp, "ADPCM Nintendo Gamecube THP"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_XA, sample_fmts_s16p, adpcm_xa, "ADPCM CDROM XA"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_YAMAHA, sample_fmts_s16, adpcm_yamaha, "ADPCM Yamaha"); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.h new file mode 100644 index 000000000..f43a28caf --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2001-2003 The ffmpeg Project + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * ADPCM encoder/decoder common header. + */ + +#ifndef AVCODEC_ADPCM_H +#define AVCODEC_ADPCM_H + +#include + +#define BLKSIZE 1024 + +typedef struct ADPCMChannelStatus { + int predictor; + int16_t step_index; + int step; + /* for encoding */ + int prev_sample; + + /* MS version */ + int sample1; + int sample2; + int coeff1; + int coeff2; + int idelta; +} ADPCMChannelStatus; + +#endif /* AVCODEC_ADPCM_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.c new file mode 100644 index 000000000..022836207 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001-2003 The ffmpeg Project + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * ADPCM tables + */ + +#include + +/* ff_adpcm_step_table[] and ff_adpcm_index_table[] are from the ADPCM + reference source */ +static const int8_t adpcm_index_table2[4] = { + -1, 2, + -1, 2, +}; + +static const int8_t adpcm_index_table3[8] = { + -1, -1, 1, 2, + -1, -1, 1, 2, +}; + +const int8_t ff_adpcm_index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +static const int8_t adpcm_index_table5[32] = { + -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, + -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, +}; + +const int8_t *ff_adpcm_index_tables[4] = { + &adpcm_index_table2[0], + &adpcm_index_table3[0], + &ff_adpcm_index_table[0], + &adpcm_index_table5[0], +}; + +/** + * This is the step table. Note that many programs use slight deviations from + * this table, but such deviations are negligible: + */ +const int16_t ff_adpcm_step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +const int16_t ff_adpcm_oki_step_table[49] = { + 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, + 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, + 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, + 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 +}; + +/* These are for MS-ADPCM */ +/* ff_adpcm_AdaptationTable[], ff_adpcm_AdaptCoeff1[], and + ff_adpcm_AdaptCoeff2[] are from libsndfile */ +const int16_t ff_adpcm_AdaptationTable[] = { + 230, 230, 230, 230, 307, 409, 512, 614, + 768, 614, 512, 409, 307, 230, 230, 230 +}; + +/** Divided by 4 to fit in 8-bit integers */ +const uint8_t ff_adpcm_AdaptCoeff1[] = { + 64, 128, 0, 48, 60, 115, 98 +}; + +/** Divided by 4 to fit in 8-bit integers */ +const int8_t ff_adpcm_AdaptCoeff2[] = { + 0, -64, 0, 16, 0, -52, -58 +}; + +const int16_t ff_adpcm_yamaha_indexscale[] = { + 230, 230, 230, 230, 307, 409, 512, 614, + 230, 230, 230, 230, 307, 409, 512, 614 +}; + +const int8_t ff_adpcm_yamaha_difflookup[] = { + 1, 3, 5, 7, 9, 11, 13, 15, + -1, -3, -5, -7, -9, -11, -13, -15 +}; + +const int16_t ff_adpcm_afc_coeffs[2][16] = { + { 0, 2048, 0, 1024, 4096, 3584, 3072, 4608, 4200, 4800, 5120, 2048, 1024, 64512, 64512, 63488 }, + { 0, 0, 2048, 1024, 63488, 64000, 64512, 62976, 63288, 63236, 62464, 63488, 64512, 1024, 0, 0 } +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.h new file mode 100644 index 000000000..a14d52088 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2001-2003 The ffmpeg Project + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * ADPCM tables + */ + +#ifndef AVCODEC_ADPCM_DATA_H +#define AVCODEC_ADPCM_DATA_H + +#include + +static const uint8_t ff_adpcm_ima_block_sizes[4] = { 4, 12, 4, 20 }; +static const uint8_t ff_adpcm_ima_block_samples[4] = { 16, 32, 8, 32 }; + +extern const int8_t const *ff_adpcm_index_tables[4]; +extern const int8_t ff_adpcm_index_table[16]; +extern const int16_t ff_adpcm_step_table[89]; +extern const int16_t ff_adpcm_oki_step_table[49]; +extern const int16_t ff_adpcm_AdaptationTable[]; +extern const uint8_t ff_adpcm_AdaptCoeff1[]; +extern const int8_t ff_adpcm_AdaptCoeff2[]; +extern const int16_t ff_adpcm_yamaha_indexscale[]; +extern const int8_t ff_adpcm_yamaha_difflookup[]; +extern const int16_t ff_adpcm_afc_coeffs[2][16]; + +#endif /* AVCODEC_ADPCM_DATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac.c new file mode 100644 index 000000000..12e8997db --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac.c @@ -0,0 +1,165 @@ +/* + * common functions for the ATRAC family of decoders + * + * Copyright (c) 2006-2013 Maxim Poliakovski + * Copyright (c) 2006-2008 Benjamin Larsson + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + */ + +#include +#include +#include +#include + +#include "avcodec.h" +#include "atrac.h" + +float ff_atrac_sf_table[64]; +static float qmf_window[48]; + +static const float qmf_48tap_half[24] = { + -0.00001461907, -0.00009205479,-0.000056157569,0.00030117269, + 0.0002422519, -0.00085293897,-0.0005205574, 0.0020340169, + 0.00078333891, -0.0042153862, -0.00075614988, 0.0078402944, + -0.000061169922,-0.01344162, 0.0024626821, 0.021736089, + -0.007801671, -0.034090221, 0.01880949, 0.054326009, + -0.043596379, -0.099384367, 0.13207909, 0.46424159 +}; + +av_cold void ff_atrac_generate_tables(void) +{ + int i; + float s; + + /* Generate scale factors */ + if (!ff_atrac_sf_table[63]) + for (i=0 ; i<64 ; i++) + ff_atrac_sf_table[i] = pow(2.0, (i - 15) / 3.0); + + /* Generate the QMF window. */ + if (!qmf_window[47]) + for (i=0 ; i<24; i++) { + s = qmf_48tap_half[i] * 2.0; + qmf_window[i] = qmf_window[47 - i] = s; + } +} + +av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset, + int loc_scale) +{ + int i; + + gctx->loc_scale = loc_scale; + gctx->loc_size = 1 << loc_scale; + gctx->id2exp_offset = id2exp_offset; + + /* Generate gain level table. */ + for (i = 0; i < 16; i++) + gctx->gain_tab1[i] = powf(2.0, id2exp_offset - i); + + /* Generate gain interpolation table. */ + for (i = -15; i < 16; i++) + gctx->gain_tab2[i + 15] = powf(2.0, -1.0f / gctx->loc_size * i); +} + +void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev, + AtracGainInfo *gc_now, AtracGainInfo *gc_next, + int num_samples, float *out) +{ + float lev, gc_scale, gain_inc; + int i, pos, lastpos; + + gc_scale = gc_next->num_points ? gctx->gain_tab1[gc_next->lev_code[0]] + : 1.0f; + + if (!gc_now->num_points) { + for (pos = 0; pos < num_samples; pos++) + out[pos] = in[pos] * gc_scale + prev[pos]; + } else { + pos = 0; + + for (i = 0; i < gc_now->num_points; i++) { + lastpos = gc_now->loc_code[i] << gctx->loc_scale; + + lev = gctx->gain_tab1[gc_now->lev_code[i]]; + gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? gc_now->lev_code[i + 1] + : gctx->id2exp_offset) - + gc_now->lev_code[i] + 15]; + + /* apply constant gain level and overlap */ + for (; pos < lastpos; pos++) + out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; + + /* interpolate between two different gain levels */ + for (; pos < lastpos + gctx->loc_size; pos++) { + out[pos] = (in[pos] * gc_scale + prev[pos]) * lev; + lev *= gain_inc; + } + } + + for (; pos < num_samples; pos++) + out[pos] = in[pos] * gc_scale + prev[pos]; + } + + /* copy the overlapping part into the delay buffer */ + memcpy(prev, &in[num_samples], num_samples * sizeof(float)); +} + +void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut, + float *delayBuf, float *temp) +{ + int i, j; + float *p1, *p3; + + memcpy(temp, delayBuf, 46*sizeof(float)); + + p3 = temp + 46; + + /* loop1 */ + for(i=0; i +#include +#include + +#include "libavutil/attributes.h" +#include "libavutil/float_dsp.h" +#include "libavutil/libm.h" +#include "libavutil/internal.h" +#include "avcodec.h" +#include "bytestream.h" +#include "fft.h" +#include "fmtconvert.h" +#include "get_bits.h" +#include "internal.h" + +#include "atrac.h" +#include "atrac3data.h" + +#define JOINT_STEREO 0x12 +#define STEREO 0x2 + +#define SAMPLES_PER_FRAME 1024 +#define MDCT_SIZE 512 + +typedef struct GainBlock { + AtracGainInfo g_block[4]; +} GainBlock; + +typedef struct TonalComponent { + int pos; + int num_coefs; + float coef[8]; +} TonalComponent; + +typedef struct ChannelUnit { + int bands_coded; + int num_components; + float prev_frame[SAMPLES_PER_FRAME]; + int gc_blk_switch; + TonalComponent components[64]; + GainBlock gain_block[2]; + + DECLARE_ALIGNED(32, float, spectrum)[SAMPLES_PER_FRAME]; + DECLARE_ALIGNED(32, float, imdct_buf)[SAMPLES_PER_FRAME]; + + float delay_buf1[46]; ///mdct_ctx.imdct_calc(&q->mdct_ctx, output, input); + + /* Perform windowing on the output. */ + q->fdsp.vector_fmul(output, output, mdct_window, MDCT_SIZE); +} + +/* + * indata descrambling, only used for data coming from the rm container + */ +static int decode_bytes(const uint8_t *input, uint8_t *out, int bytes) +{ + int i, off; + uint32_t c; + const uint32_t *buf; + uint32_t *output = (uint32_t *)out; + + off = (intptr_t)input & 3; + buf = (const uint32_t *)(input - off); + if (off) + c = av_be2ne32((0x537F6103U >> (off * 8)) | (0x537F6103U << (32 - (off * 8)))); + else + c = av_be2ne32(0x537F6103U); + bytes += 3 + off; + for (i = 0; i < bytes / 4; i++) + output[i] = c ^ buf[i]; + + if (off) + avpriv_request_sample(NULL, "Offset of %d", off); + + return off; +} + +static av_cold void init_atrac3_window(void) +{ + int i, j; + + /* generate the mdct window, for details see + * http://wiki.multimedia.cx/index.php?title=RealAudio_atrc#Windows */ + for (i = 0, j = 255; i < 128; i++, j--) { + float wi = sin(((i + 0.5) / 256.0 - 0.5) * M_PI) + 1.0; + float wj = sin(((j + 0.5) / 256.0 - 0.5) * M_PI) + 1.0; + float w = 0.5 * (wi * wi + wj * wj); + mdct_window[i] = mdct_window[511 - i] = wi / w; + mdct_window[j] = mdct_window[511 - j] = wj / w; + } +} + +static av_cold int atrac3_decode_close(AVCodecContext *avctx) +{ + ATRAC3Context *q = avctx->priv_data; + + av_free(q->units); + av_free(q->decoded_bytes_buffer); + + ff_mdct_end(&q->mdct_ctx); + + return 0; +} + +/** + * Mantissa decoding + * + * @param selector which table the output values are coded with + * @param coding_flag constant length coding or variable length coding + * @param mantissas mantissa output table + * @param num_codes number of values to get + */ +static void read_quant_spectral_coeffs(GetBitContext *gb, int selector, + int coding_flag, int *mantissas, + int num_codes) +{ + int i, code, huff_symb; + + if (selector == 1) + num_codes /= 2; + + if (coding_flag != 0) { + /* constant length coding (CLC) */ + int num_bits = clc_length_tab[selector]; + + if (selector > 1) { + for (i = 0; i < num_codes; i++) { + if (num_bits) + code = get_sbits(gb, num_bits); + else + code = 0; + mantissas[i] = code; + } + } else { + for (i = 0; i < num_codes; i++) { + if (num_bits) + code = get_bits(gb, num_bits); // num_bits is always 4 in this case + else + code = 0; + mantissas[i * 2 ] = mantissa_clc_tab[code >> 2]; + mantissas[i * 2 + 1] = mantissa_clc_tab[code & 3]; + } + } + } else { + /* variable length coding (VLC) */ + if (selector != 1) { + for (i = 0; i < num_codes; i++) { + huff_symb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, + spectral_coeff_tab[selector-1].bits, 3); + huff_symb += 1; + code = huff_symb >> 1; + if (huff_symb & 1) + code = -code; + mantissas[i] = code; + } + } else { + for (i = 0; i < num_codes; i++) { + huff_symb = get_vlc2(gb, spectral_coeff_tab[selector - 1].table, + spectral_coeff_tab[selector - 1].bits, 3); + mantissas[i * 2 ] = mantissa_vlc_tab[huff_symb * 2 ]; + mantissas[i * 2 + 1] = mantissa_vlc_tab[huff_symb * 2 + 1]; + } + } + } +} + +/** + * Restore the quantized band spectrum coefficients + * + * @return subband count, fix for broken specification/files + */ +static int decode_spectrum(GetBitContext *gb, float *output) +{ + int num_subbands, coding_mode, i, j, first, last, subband_size; + int subband_vlc_index[32], sf_index[32]; + int mantissas[128]; + float scale_factor; + + num_subbands = get_bits(gb, 5); // number of coded subbands + coding_mode = get_bits1(gb); // coding Mode: 0 - VLC/ 1-CLC + + /* get the VLC selector table for the subbands, 0 means not coded */ + for (i = 0; i <= num_subbands; i++) + subband_vlc_index[i] = get_bits(gb, 3); + + /* read the scale factor indexes from the stream */ + for (i = 0; i <= num_subbands; i++) { + if (subband_vlc_index[i] != 0) + sf_index[i] = get_bits(gb, 6); + } + + for (i = 0; i <= num_subbands; i++) { + first = subband_tab[i ]; + last = subband_tab[i + 1]; + + subband_size = last - first; + + if (subband_vlc_index[i] != 0) { + /* decode spectral coefficients for this subband */ + /* TODO: This can be done faster is several blocks share the + * same VLC selector (subband_vlc_index) */ + read_quant_spectral_coeffs(gb, subband_vlc_index[i], coding_mode, + mantissas, subband_size); + + /* decode the scale factor for this subband */ + scale_factor = ff_atrac_sf_table[sf_index[i]] * + inv_max_quant[subband_vlc_index[i]]; + + /* inverse quantize the coefficients */ + for (j = 0; first < last; first++, j++) + output[first] = mantissas[j] * scale_factor; + } else { + /* this subband was not coded, so zero the entire subband */ + memset(output + first, 0, subband_size * sizeof(*output)); + } + } + + /* clear the subbands that were not coded */ + first = subband_tab[i]; + memset(output + first, 0, (SAMPLES_PER_FRAME - first) * sizeof(*output)); + return num_subbands; +} + +/** + * Restore the quantized tonal components + * + * @param components tonal components + * @param num_bands number of coded bands + */ +static int decode_tonal_components(GetBitContext *gb, + TonalComponent *components, int num_bands) +{ + int i, b, c, m; + int nb_components, coding_mode_selector, coding_mode; + int band_flags[4], mantissa[8]; + int component_count = 0; + + nb_components = get_bits(gb, 5); + + /* no tonal components */ + if (nb_components == 0) + return 0; + + coding_mode_selector = get_bits(gb, 2); + if (coding_mode_selector == 2) + return AVERROR_INVALIDDATA; + + coding_mode = coding_mode_selector & 1; + + for (i = 0; i < nb_components; i++) { + int coded_values_per_component, quant_step_index; + + for (b = 0; b <= num_bands; b++) + band_flags[b] = get_bits1(gb); + + coded_values_per_component = get_bits(gb, 3); + + quant_step_index = get_bits(gb, 3); + if (quant_step_index <= 1) + return AVERROR_INVALIDDATA; + + if (coding_mode_selector == 3) + coding_mode = get_bits1(gb); + + for (b = 0; b < (num_bands + 1) * 4; b++) { + int coded_components; + + if (band_flags[b >> 2] == 0) + continue; + + coded_components = get_bits(gb, 3); + + for (c = 0; c < coded_components; c++) { + TonalComponent *cmp = &components[component_count]; + int sf_index, coded_values, max_coded_values; + float scale_factor; + + sf_index = get_bits(gb, 6); + if (component_count >= 64) + return AVERROR_INVALIDDATA; + + cmp->pos = b * 64 + get_bits(gb, 6); + + max_coded_values = SAMPLES_PER_FRAME - cmp->pos; + coded_values = coded_values_per_component + 1; + coded_values = FFMIN(max_coded_values, coded_values); + + scale_factor = ff_atrac_sf_table[sf_index] * + inv_max_quant[quant_step_index]; + + read_quant_spectral_coeffs(gb, quant_step_index, coding_mode, + mantissa, coded_values); + + cmp->num_coefs = coded_values; + + /* inverse quant */ + for (m = 0; m < coded_values; m++) + cmp->coef[m] = mantissa[m] * scale_factor; + + component_count++; + } + } + } + + return component_count; +} + +/** + * Decode gain parameters for the coded bands + * + * @param block the gainblock for the current band + * @param num_bands amount of coded bands + */ +static int decode_gain_control(GetBitContext *gb, GainBlock *block, + int num_bands) +{ + int b, j; + int *level, *loc; + + AtracGainInfo *gain = block->g_block; + + for (b = 0; b <= num_bands; b++) { + gain[b].num_points = get_bits(gb, 3); + level = gain[b].lev_code; + loc = gain[b].loc_code; + + for (j = 0; j < gain[b].num_points; j++) { + level[j] = get_bits(gb, 4); + loc[j] = get_bits(gb, 5); + if (j && loc[j] <= loc[j - 1]) + return AVERROR_INVALIDDATA; + } + } + + /* Clear the unused blocks. */ + for (; b < 4 ; b++) + gain[b].num_points = 0; + + return 0; +} + +/** + * Combine the tonal band spectrum and regular band spectrum + * + * @param spectrum output spectrum buffer + * @param num_components number of tonal components + * @param components tonal components for this band + * @return position of the last tonal coefficient + */ +static int add_tonal_components(float *spectrum, int num_components, + TonalComponent *components) +{ + int i, j, last_pos = -1; + float *input, *output; + + for (i = 0; i < num_components; i++) { + last_pos = FFMAX(components[i].pos + components[i].num_coefs, last_pos); + input = components[i].coef; + output = &spectrum[components[i].pos]; + + for (j = 0; j < components[i].num_coefs; j++) + output[j] += input[j]; + } + + return last_pos; +} + +#define INTERPOLATE(old, new, nsample) \ + ((old) + (nsample) * 0.125 * ((new) - (old))) + +static void reverse_matrixing(float *su1, float *su2, int *prev_code, + int *curr_code) +{ + int i, nsample, band; + float mc1_l, mc1_r, mc2_l, mc2_r; + + for (i = 0, band = 0; band < 4 * 256; band += 256, i++) { + int s1 = prev_code[i]; + int s2 = curr_code[i]; + nsample = band; + + if (s1 != s2) { + /* Selector value changed, interpolation needed. */ + mc1_l = matrix_coeffs[s1 * 2 ]; + mc1_r = matrix_coeffs[s1 * 2 + 1]; + mc2_l = matrix_coeffs[s2 * 2 ]; + mc2_r = matrix_coeffs[s2 * 2 + 1]; + + /* Interpolation is done over the first eight samples. */ + for (; nsample < band + 8; nsample++) { + float c1 = su1[nsample]; + float c2 = su2[nsample]; + c2 = c1 * INTERPOLATE(mc1_l, mc2_l, nsample - band) + + c2 * INTERPOLATE(mc1_r, mc2_r, nsample - band); + su1[nsample] = c2; + su2[nsample] = c1 * 2.0 - c2; + } + } + + /* Apply the matrix without interpolation. */ + switch (s2) { + case 0: /* M/S decoding */ + for (; nsample < band + 256; nsample++) { + float c1 = su1[nsample]; + float c2 = su2[nsample]; + su1[nsample] = c2 * 2.0; + su2[nsample] = (c1 - c2) * 2.0; + } + break; + case 1: + for (; nsample < band + 256; nsample++) { + float c1 = su1[nsample]; + float c2 = su2[nsample]; + su1[nsample] = (c1 + c2) * 2.0; + su2[nsample] = c2 * -2.0; + } + break; + case 2: + case 3: + for (; nsample < band + 256; nsample++) { + float c1 = su1[nsample]; + float c2 = su2[nsample]; + su1[nsample] = c1 + c2; + su2[nsample] = c1 - c2; + } + break; + default: + av_assert1(0); + } + } +} + +static void get_channel_weights(int index, int flag, float ch[2]) +{ + if (index == 7) { + ch[0] = 1.0; + ch[1] = 1.0; + } else { + ch[0] = (index & 7) / 7.0; + ch[1] = sqrt(2 - ch[0] * ch[0]); + if (flag) + FFSWAP(float, ch[0], ch[1]); + } +} + +static void channel_weighting(float *su1, float *su2, int *p3) +{ + int band, nsample; + /* w[x][y] y=0 is left y=1 is right */ + float w[2][2]; + + if (p3[1] != 7 || p3[3] != 7) { + get_channel_weights(p3[1], p3[0], w[0]); + get_channel_weights(p3[3], p3[2], w[1]); + + for (band = 256; band < 4 * 256; band += 256) { + for (nsample = band; nsample < band + 8; nsample++) { + su1[nsample] *= INTERPOLATE(w[0][0], w[0][1], nsample - band); + su2[nsample] *= INTERPOLATE(w[1][0], w[1][1], nsample - band); + } + for(; nsample < band + 256; nsample++) { + su1[nsample] *= w[1][0]; + su2[nsample] *= w[1][1]; + } + } + } +} + +/** + * Decode a Sound Unit + * + * @param snd the channel unit to be used + * @param output the decoded samples before IQMF in float representation + * @param channel_num channel number + * @param coding_mode the coding mode (JOINT_STEREO or regular stereo/mono) + */ +static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb, + ChannelUnit *snd, float *output, + int channel_num, int coding_mode) +{ + int band, ret, num_subbands, last_tonal, num_bands; + GainBlock *gain1 = &snd->gain_block[ snd->gc_blk_switch]; + GainBlock *gain2 = &snd->gain_block[1 - snd->gc_blk_switch]; + + if (coding_mode == JOINT_STEREO && channel_num == 1) { + if (get_bits(gb, 2) != 3) { + av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n"); + return AVERROR_INVALIDDATA; + } + } else { + if (get_bits(gb, 6) != 0x28) { + av_log(NULL,AV_LOG_ERROR,"Sound Unit id != 0x28.\n"); + return AVERROR_INVALIDDATA; + } + } + + /* number of coded QMF bands */ + snd->bands_coded = get_bits(gb, 2); + + ret = decode_gain_control(gb, gain2, snd->bands_coded); + if (ret) + return ret; + + snd->num_components = decode_tonal_components(gb, snd->components, + snd->bands_coded); + if (snd->num_components < 0) + return snd->num_components; + + num_subbands = decode_spectrum(gb, snd->spectrum); + + /* Merge the decoded spectrum and tonal components. */ + last_tonal = add_tonal_components(snd->spectrum, snd->num_components, + snd->components); + + + /* calculate number of used MLT/QMF bands according to the amount of coded + spectral lines */ + num_bands = (subband_tab[num_subbands] - 1) >> 8; + if (last_tonal >= 0) + num_bands = FFMAX((last_tonal + 256) >> 8, num_bands); + + + /* Reconstruct time domain samples. */ + for (band = 0; band < 4; band++) { + /* Perform the IMDCT step without overlapping. */ + if (band <= num_bands) + imlt(q, &snd->spectrum[band * 256], snd->imdct_buf, band & 1); + else + memset(snd->imdct_buf, 0, 512 * sizeof(*snd->imdct_buf)); + + /* gain compensation and overlapping */ + ff_atrac_gain_compensation(&q->gainc_ctx, snd->imdct_buf, + &snd->prev_frame[band * 256], + &gain1->g_block[band], &gain2->g_block[band], + 256, &output[band * 256]); + } + + /* Swap the gain control buffers for the next frame. */ + snd->gc_blk_switch ^= 1; + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf, + float **out_samples) +{ + ATRAC3Context *q = avctx->priv_data; + int ret, i; + uint8_t *ptr1; + + if (q->coding_mode == JOINT_STEREO) { + /* channel coupling mode */ + /* decode Sound Unit 1 */ + init_get_bits(&q->gb, databuf, avctx->block_align * 8); + + ret = decode_channel_sound_unit(q, &q->gb, q->units, out_samples[0], 0, + JOINT_STEREO); + if (ret != 0) + return ret; + + /* Framedata of the su2 in the joint-stereo mode is encoded in + * reverse byte order so we need to swap it first. */ + if (databuf == q->decoded_bytes_buffer) { + uint8_t *ptr2 = q->decoded_bytes_buffer + avctx->block_align - 1; + ptr1 = q->decoded_bytes_buffer; + for (i = 0; i < avctx->block_align / 2; i++, ptr1++, ptr2--) + FFSWAP(uint8_t, *ptr1, *ptr2); + } else { + const uint8_t *ptr2 = databuf + avctx->block_align - 1; + for (i = 0; i < avctx->block_align; i++) + q->decoded_bytes_buffer[i] = *ptr2--; + } + + /* Skip the sync codes (0xF8). */ + ptr1 = q->decoded_bytes_buffer; + for (i = 4; *ptr1 == 0xF8; i++, ptr1++) { + if (i >= avctx->block_align) + return AVERROR_INVALIDDATA; + } + + + /* set the bitstream reader at the start of the second Sound Unit*/ + init_get_bits8(&q->gb, ptr1, q->decoded_bytes_buffer + avctx->block_align - ptr1); + + /* Fill the Weighting coeffs delay buffer */ + memmove(q->weighting_delay, &q->weighting_delay[2], + 4 * sizeof(*q->weighting_delay)); + q->weighting_delay[4] = get_bits1(&q->gb); + q->weighting_delay[5] = get_bits(&q->gb, 3); + + for (i = 0; i < 4; i++) { + q->matrix_coeff_index_prev[i] = q->matrix_coeff_index_now[i]; + q->matrix_coeff_index_now[i] = q->matrix_coeff_index_next[i]; + q->matrix_coeff_index_next[i] = get_bits(&q->gb, 2); + } + + /* Decode Sound Unit 2. */ + ret = decode_channel_sound_unit(q, &q->gb, &q->units[1], + out_samples[1], 1, JOINT_STEREO); + if (ret != 0) + return ret; + + /* Reconstruct the channel coefficients. */ + reverse_matrixing(out_samples[0], out_samples[1], + q->matrix_coeff_index_prev, + q->matrix_coeff_index_now); + + channel_weighting(out_samples[0], out_samples[1], q->weighting_delay); + } else { + /* normal stereo mode or mono */ + /* Decode the channel sound units. */ + for (i = 0; i < avctx->channels; i++) { + /* Set the bitstream reader at the start of a channel sound unit. */ + init_get_bits(&q->gb, + databuf + i * avctx->block_align / avctx->channels, + avctx->block_align * 8 / avctx->channels); + + ret = decode_channel_sound_unit(q, &q->gb, &q->units[i], + out_samples[i], i, q->coding_mode); + if (ret != 0) + return ret; + } + } + + /* Apply the iQMF synthesis filter. */ + for (i = 0; i < avctx->channels; i++) { + float *p1 = out_samples[i]; + float *p2 = p1 + 256; + float *p3 = p2 + 256; + float *p4 = p3 + 256; + ff_atrac_iqmf(p1, p2, 256, p1, q->units[i].delay_buf1, q->temp_buf); + ff_atrac_iqmf(p4, p3, 256, p3, q->units[i].delay_buf2, q->temp_buf); + ff_atrac_iqmf(p1, p3, 512, p1, q->units[i].delay_buf3, q->temp_buf); + } + + return 0; +} + +static int atrac3_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + ATRAC3Context *q = avctx->priv_data; + int ret; + const uint8_t *databuf; + + if (buf_size < avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, + "Frame too small (%d bytes). Truncated file?\n", buf_size); + return AVERROR_INVALIDDATA; + } + + /* get output buffer */ + frame->nb_samples = SAMPLES_PER_FRAME; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + /* Check if we need to descramble and what buffer to pass on. */ + if (q->scrambled_stream) { + decode_bytes(buf, q->decoded_bytes_buffer, avctx->block_align); + databuf = q->decoded_bytes_buffer; + } else { + databuf = buf; + } + + ret = decode_frame(avctx, databuf, (float **)frame->extended_data); + if (ret) { + av_log(NULL, AV_LOG_ERROR, "Frame decoding error!\n"); + return ret; + } + + *got_frame_ptr = 1; + + return avctx->block_align; +} + +static av_cold void atrac3_init_static_data(void) +{ + int i; + + init_atrac3_window(); + ff_atrac_generate_tables(); + + /* Initialize the VLC tables. */ + for (i = 0; i < 7; i++) { + spectral_coeff_tab[i].table = &atrac3_vlc_table[atrac3_vlc_offs[i]]; + spectral_coeff_tab[i].table_allocated = atrac3_vlc_offs[i + 1] - + atrac3_vlc_offs[i ]; + init_vlc(&spectral_coeff_tab[i], 9, huff_tab_sizes[i], + huff_bits[i], 1, 1, + huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + } + + /* Generate gain tables */ + for (i = 0; i < 16; i++) + gain_tab1[i] = exp2f (4 - i); + + for (i = -15; i < 16; i++) + gain_tab2[i + 15] = exp2f (i * -0.125); +} + +static av_cold int atrac3_decode_init(AVCodecContext *avctx) +{ + static int static_init_done; + int i, ret; + int version, delay, samples_per_frame, frame_factor; + const uint8_t *edata_ptr = avctx->extradata; + ATRAC3Context *q = avctx->priv_data; + + if (avctx->channels <= 0 || avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "Channel configuration error!\n"); + return AVERROR(EINVAL); + } + + if (!static_init_done) + atrac3_init_static_data(); + static_init_done = 1; + + /* Take care of the codec-specific extradata. */ + if (avctx->extradata_size == 14) { + /* Parse the extradata, WAV format */ + av_log(avctx, AV_LOG_DEBUG, "[0-1] %d\n", + bytestream_get_le16(&edata_ptr)); // Unknown value always 1 + edata_ptr += 4; // samples per channel + q->coding_mode = bytestream_get_le16(&edata_ptr); + av_log(avctx, AV_LOG_DEBUG,"[8-9] %d\n", + bytestream_get_le16(&edata_ptr)); //Dupe of coding mode + frame_factor = bytestream_get_le16(&edata_ptr); // Unknown always 1 + av_log(avctx, AV_LOG_DEBUG,"[12-13] %d\n", + bytestream_get_le16(&edata_ptr)); // Unknown always 0 + + /* setup */ + samples_per_frame = SAMPLES_PER_FRAME * avctx->channels; + version = 4; + delay = 0x88E; + q->coding_mode = q->coding_mode ? JOINT_STEREO : STEREO; + q->scrambled_stream = 0; + + if (avctx->block_align != 96 * avctx->channels * frame_factor && + avctx->block_align != 152 * avctx->channels * frame_factor && + avctx->block_align != 192 * avctx->channels * frame_factor) { + av_log(avctx, AV_LOG_ERROR, "Unknown frame/channel/frame_factor " + "configuration %d/%d/%d\n", avctx->block_align, + avctx->channels, frame_factor); + return AVERROR_INVALIDDATA; + } + } else if (avctx->extradata_size == 12 || avctx->extradata_size == 10) { + /* Parse the extradata, RM format. */ + version = bytestream_get_be32(&edata_ptr); + samples_per_frame = bytestream_get_be16(&edata_ptr); + delay = bytestream_get_be16(&edata_ptr); + q->coding_mode = bytestream_get_be16(&edata_ptr); + q->scrambled_stream = 1; + + } else { + av_log(NULL, AV_LOG_ERROR, "Unknown extradata size %d.\n", + avctx->extradata_size); + return AVERROR(EINVAL); + } + + /* Check the extradata */ + + if (version != 4) { + av_log(avctx, AV_LOG_ERROR, "Version %d != 4.\n", version); + return AVERROR_INVALIDDATA; + } + + if (samples_per_frame != SAMPLES_PER_FRAME && + samples_per_frame != SAMPLES_PER_FRAME * 2) { + av_log(avctx, AV_LOG_ERROR, "Unknown amount of samples per frame %d.\n", + samples_per_frame); + return AVERROR_INVALIDDATA; + } + + if (delay != 0x88E) { + av_log(avctx, AV_LOG_ERROR, "Unknown amount of delay %x != 0x88E.\n", + delay); + return AVERROR_INVALIDDATA; + } + + if (q->coding_mode == STEREO) + av_log(avctx, AV_LOG_DEBUG, "Normal stereo detected.\n"); + else if (q->coding_mode == JOINT_STEREO) { + if (avctx->channels != 2) { + av_log(avctx, AV_LOG_ERROR, "Invalid coding mode\n"); + return AVERROR_INVALIDDATA; + } + av_log(avctx, AV_LOG_DEBUG, "Joint stereo detected.\n"); + } else { + av_log(avctx, AV_LOG_ERROR, "Unknown channel coding mode %x!\n", + q->coding_mode); + return AVERROR_INVALIDDATA; + } + + if (avctx->block_align >= UINT_MAX / 2) + return AVERROR(EINVAL); + + q->decoded_bytes_buffer = av_mallocz(FFALIGN(avctx->block_align, 4) + + FF_INPUT_BUFFER_PADDING_SIZE); + if (q->decoded_bytes_buffer == NULL) + return AVERROR(ENOMEM); + + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + + /* initialize the MDCT transform */ + if ((ret = ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); + av_freep(&q->decoded_bytes_buffer); + return ret; + } + + /* init the joint-stereo decoding data */ + q->weighting_delay[0] = 0; + q->weighting_delay[1] = 7; + q->weighting_delay[2] = 0; + q->weighting_delay[3] = 7; + q->weighting_delay[4] = 0; + q->weighting_delay[5] = 7; + + for (i = 0; i < 4; i++) { + q->matrix_coeff_index_prev[i] = 3; + q->matrix_coeff_index_now[i] = 3; + q->matrix_coeff_index_next[i] = 3; + } + + ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3); + avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); + ff_fmt_convert_init(&q->fmt_conv, avctx); + + q->units = av_mallocz(sizeof(*q->units) * avctx->channels); + if (!q->units) { + atrac3_decode_close(avctx); + return AVERROR(ENOMEM); + } + + return 0; +} + +AVCodec ff_atrac3_decoder = { + .name = "atrac3", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ATRAC3, + .priv_data_size = sizeof(ATRAC3Context), + .init = atrac3_decode_init, + .close = atrac3_decode_close, + .decode = atrac3_decode_frame, + .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3data.h new file mode 100644 index 000000000..5d91274f4 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3data.h @@ -0,0 +1,141 @@ +/* + * ATRAC3 compatible decoder data + * Copyright (c) 2006-2007 Maxim Poliakovski + * Copyright (c) 2006-2007 Benjamin Larsson + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * ATRAC3 AKA RealAudio 8 compatible decoder data + */ + +#ifndef AVCODEC_ATRAC3DATA_H +#define AVCODEC_ATRAC3DATA_H + +#include + +/* VLC tables */ + +static const uint8_t huffcode1[9] = { + 0x0, 0x4, 0x5, 0xC, 0xD, 0x1C, 0x1D, 0x1E, 0x1F +}; + +static const uint8_t huffbits1[9] = { 1, 3, 3, 4, 4, 5, 5, 5, 5 }; + +static const uint8_t huffcode2[5] = { 0x0, 0x4, 0x5, 0x6, 0x7 }; + +static const uint8_t huffbits2[5] = { 1, 3, 3, 3, 3 }; + +static const uint8_t huffcode3[7] = { 0x0, 0x4, 0x5, 0xC, 0xD, 0xE, 0xF }; + +static const uint8_t huffbits3[7] = { 1, 3, 3, 4, 4, 4, 4 }; + +static const uint8_t huffcode4[9] = { + 0x0, 0x4, 0x5, 0xC, 0xD, 0x1C, 0x1D, 0x1E, 0x1F +}; + +static const uint8_t huffbits4[9] = { 1, 3, 3, 4, 4, 5, 5, 5, 5 }; + +static const uint8_t huffcode5[15] = { + 0x00, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x1C, + 0x1D, 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x0D +}; + +static const uint8_t huffbits5[15] = { + 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 4, 4 +}; + +static const uint8_t huffcode6[31] = { + 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x78, 0x79, 0x7A, + 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x08, 0x09 +}; + +static const uint8_t huffbits6[31] = { + 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4 +}; + +static const uint8_t huffcode7[63] = { + 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x68, 0x69, 0x6A, 0x6B, 0x6C, + 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, + 0x75, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, + 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, + 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x02, 0x03 +}; + +static const uint8_t huffbits7[63] = { + 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4 +}; + +static const uint8_t huff_tab_sizes[7] = { + 9, 5, 7, 9, 15, 31, 63, +}; + +static const uint8_t* const huff_codes[7] = { + huffcode1, huffcode2, huffcode3, huffcode4, huffcode5, huffcode6, huffcode7 +}; + +static const uint8_t* const huff_bits[7] = { + huffbits1, huffbits2, huffbits3, huffbits4, huffbits5, huffbits6, huffbits7, +}; + +static const uint16_t atrac3_vlc_offs[9] = { + 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096 +}; + +/* selector tables */ + +static const uint8_t clc_length_tab[8] = { 0, 4, 3, 3, 4, 4, 5, 6 }; + +static const int8_t mantissa_clc_tab[4] = { 0, 1, -2, -1 }; + +static const int8_t mantissa_vlc_tab[18] = { + 0, 0, 0, 1, 0, -1, 1, 0, -1, 0, 1, 1, 1, -1, -1, 1, -1, -1 +}; + + +/* tables for the scalefactor decoding */ + +static const float inv_max_quant[8] = { + 0.0, 1.0 / 1.5, 1.0 / 2.5, 1.0 / 3.5, + 1.0 / 4.5, 1.0 / 7.5, 1.0 / 15.5, 1.0 / 31.5 +}; + +static const uint16_t subband_tab[33] = { + 0, 8, 16, 24, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 144, 160, 176, + 192, 224, 256, 288, 320, 352, 384, 416, + 448, 480, 512, 576, 640, 704, 768, 896, + 1024 +}; + +/* joint stereo related tables */ +static const float matrix_coeffs[8] = { + 0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0 +}; + +#endif /* AVCODEC_ATRAC3DATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/cbrt_tablegen.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/cbrt_tablegen.h new file mode 100644 index 000000000..a9d34dc75 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/cbrt_tablegen.h @@ -0,0 +1,51 @@ +/* + * Header file for hardcoded AAC cube-root table + * + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_CBRT_TABLEGEN_H +#define AVCODEC_CBRT_TABLEGEN_H + +#include +#include + +#if CONFIG_HARDCODED_TABLES +#define cbrt_tableinit() +#include "libavcodec/cbrt_tables.h" +#else +static uint32_t cbrt_tab[1 << 13]; + +static void cbrt_tableinit(void) +{ + if (!cbrt_tab[(1<<13) - 1]) { + int i; + for (i = 0; i < 1<<13; i++) { + union { + float f; + uint32_t i; + } f; + f.f = cbrtf(i) * i; + cbrt_tab[i] = f.i; + } + } +} +#endif /* CONFIG_HARDCODED_TABLES */ + +#endif /* AVCODEC_CBRT_TABLEGEN_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c index 613e60b02..07aaf68c1 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c @@ -1437,6 +1437,7 @@ static int dca_filter_channels(DCAContext *s, int block_index) { float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index]; int k; + int request_channels; /* 32 subbands QMF */ for (k = 0; k < s->prim_channels; k++) { @@ -1449,7 +1450,8 @@ static int dca_filter_channels(DCAContext *s, int block_index) } /* Down mixing */ - if (s->avctx->request_channels == 2 && s->prim_channels > 2) { + AV_NOWARN_DEPRECATED( request_channels = s->avctx->request_channels; ); + if (request_channels == 2 && s->prim_channels > 2) { dca_downmix(s->samples_chanptr, s->amode, s->downmix_coef, s->channel_order_tab); } @@ -2077,6 +2079,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, DCAContext *s = avctx->priv_data; int core_ss_end; int channels, full_channels; + int request_channels; float scale; int achan; int chset; @@ -2223,19 +2226,21 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, avctx->profile = s->profile; full_channels = channels = s->prim_channels + !!s->lfe; + + AV_NOWARN_DEPRECATED( request_channels = avctx->request_channels; ); /* If we have XXCH then the channel layout is managed differently */ /* note that XLL will also have another way to do things */ if (!(s->core_ext_mask & DCA_EXT_XXCH) - || (s->core_ext_mask & DCA_EXT_XXCH && avctx->request_channels > 0 - && avctx->request_channels + || (s->core_ext_mask & DCA_EXT_XXCH && request_channels > 0 + && request_channels < num_core_channels + !!s->lfe + s->xxch_chset_nch[0])) { /* xxx should also do MA extensions */ if (s->amode < 16) { avctx->channel_layout = dca_core_channel_layout[s->amode]; - if (s->xch_present && (!avctx->request_channels || - avctx->request_channels + if (s->xch_present && (!request_channels || + request_channels > num_core_channels + !!s->lfe)) { avctx->channel_layout |= AV_CH_BACK_CENTER; if (s->lfe) { @@ -2265,7 +2270,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (avctx->request_channels == 2 && s->prim_channels > 2) { + if (request_channels == 2 && s->prim_channels > 2) { channels = 2; s->output = DCA_STEREO; avctx->channel_layout = AV_CH_LAYOUT_STEREO; @@ -2286,11 +2291,11 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, /* we only get here if an XXCH channel set can be added to the mix */ channel_mask = s->xxch_core_spkmask; - if (avctx->request_channels > 0 - && avctx->request_channels < s->prim_channels) { + if (request_channels > 0 + && request_channels < s->prim_channels) { channels = num_core_channels + !!s->lfe; for (i = 0; i < s->xxch_chset && channels + s->xxch_chset_nch[i] - <= avctx->request_channels; i++) { + <= request_channels; i++) { channels += s->xxch_chset_nch[i]; channel_mask |= s->xxch_spk_masks[i]; } @@ -2467,6 +2472,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, static av_cold int dca_decode_init(AVCodecContext *avctx) { DCAContext *s = avctx->priv_data; + int request_channels; s->avctx = avctx; dca_init_vlcs(); @@ -2480,9 +2486,10 @@ static av_cold int dca_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo */ - if (avctx->channels > 0 && avctx->request_channels < avctx->channels && - avctx->request_channels == 2) { - avctx->channels = avctx->request_channels; + AV_NOWARN_DEPRECATED( request_channels = avctx->request_channels; ); + if (avctx->channels > 0 && request_channels < avctx->channels && + request_channels == 2) { + avctx->channels = request_channels; } return 0; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c index e132acc44..d65ac9af4 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c @@ -314,10 +314,10 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, /* [DIRAC_STD] 10.3 Source Parameters * Override the defaults. */ - if (ret = parse_source_parameters(avctx, gb, source)) + if ((ret = parse_source_parameters(avctx, gb, source))) return ret; - if (ret = av_image_check_size(source->width, source->height, 0, avctx)) + if ((ret = av_image_check_size(source->width, source->height, 0, avctx))) return ret; avcodec_set_dimensions(avctx, source->width, source->height); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_parser.c index a2a22ee5b..6df3df877 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_parser.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_parser.c @@ -136,7 +136,7 @@ static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, if ( next == -1) { /* Found a possible frame start but not a frame end */ - void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, + void *new_buffer = av_fast_realloc(pc->buffer, (unsigned int *) &pc->buffer_size, pc->index + (*buf_size - pc->sync_offset)); pc->buffer = new_buffer; @@ -147,7 +147,7 @@ static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, } else { /* Found a possible frame start and a possible frame end */ DiracParseUnit pu1, pu; - void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, + void *new_buffer = av_fast_realloc(pc->buffer, (unsigned int *) &pc->buffer_size, pc->index + next); pc->buffer = new_buffer; memcpy(pc->buffer + pc->index, *buf, next); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c index 15baf7510..e92139388 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c @@ -616,7 +616,7 @@ static void decode_component(DiracContext *s, int comp) /* Unpack all subbands at all levels. */ for (level = 0; level < s->wavelet_depth; level++) { - for (orientation = !!level; orientation < 4; orientation++) { + for (orientation = !!level; (int)orientation < 4; orientation++) { SubBand *b = &s->plane[comp].band[level][orientation]; bands[num_bands++] = b; @@ -707,7 +707,7 @@ static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg) /* [DIRAC_STD] 13.5.5.2 luma_slice_band */ for (level = 0; level < s->wavelet_depth; level++) - for (orientation = !!level; orientation < 4; orientation++) { + for (orientation = !!level; (int)orientation < 4; orientation++) { quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0); lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, luma_end, &s->plane[0].band[level][orientation], NULL); @@ -720,7 +720,7 @@ static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg) chroma_end = get_bits_count(gb) + FFMIN(chroma_bits, get_bits_left(gb)); /* [DIRAC_STD] 13.5.5.3 chroma_slice_band */ for (level = 0; level < s->wavelet_depth; level++) - for (orientation = !!level; orientation < 4; orientation++) { + for (orientation = !!level; (int)orientation < 4; orientation++) { quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0); lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, chroma_end, &s->plane[1].band[level][orientation], @@ -1678,6 +1678,7 @@ static int dirac_decode_picture_header(DiracContext *s) } /* retire the reference frames that are not used anymore */ + AV_NOWARN_DEPRECATED( if (s->current_picture->avframe.reference) { retire = picnum + dirac_get_se_golomb(gb); if (retire != picnum) { @@ -1695,6 +1696,7 @@ static int dirac_decode_picture_header(DiracContext *s) remove_frame(s->ref_frames, s->ref_frames[0]->avframe.display_picture_number)->avframe.reference &= DELAYED_PIC_REF; } } + ); if (s->num_refs) { if (dirac_unpack_prediction_parameters(s)) /* [DIRAC_STD] 11.2 Picture Prediction Data. picture_prediction() */ @@ -1726,7 +1728,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame) s->delay_frames[i] = s->delay_frames[i+1]; if (out) { - out->avframe.reference ^= DELAYED_PIC_REF; + AV_NOWARN_DEPRECATED( out->avframe.reference ^= DELAYED_PIC_REF; ); *got_frame = 1; if((ret = av_frame_ref(picture, &out->avframe)) < 0) return ret; @@ -1778,7 +1780,7 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int int ver[3]; /* versions older than 1.0.8 don't store quant delta for subbands with only one codeblock */ - if (sscanf(buf+14, "Schroedinger %d.%d.%d", ver, ver+1, ver+2) == 3) + if (sscanf((const char *) buf+14, "Schroedinger %d.%d.%d", ver, ver+1, ver+2) == 3) if (ver[0] == 1 && ver[1] == 0 && ver[2] <= 7) s->old_delta_quant = 1; } @@ -1808,7 +1810,7 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int s->num_refs = tmp; s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */ s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */ - pic->avframe.reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */ + AV_NOWARN_DEPRECATED( pic->avframe.reference = (parse_code & 0x0C) == 0x0C; ); /* [DIRAC_STD] is_reference() */ pic->avframe.key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ pic->avframe.pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ @@ -1841,10 +1843,12 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* release unused frames */ for (i = 0; i < MAX_FRAMES; i++) + AV_NOWARN_DEPRECATED( if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) { av_frame_unref(&s->all_frames[i].avframe); memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); } + ); s->current_picture = NULL; *got_frame = 0; @@ -1890,7 +1894,7 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (s->current_picture->avframe.display_picture_number > s->frame_number) { DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number); - s->current_picture->avframe.reference |= DELAYED_PIC_REF; + AV_NOWARN_DEPRECATED( s->current_picture->avframe.reference |= DELAYED_PIC_REF; ); if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) { int min_num = s->delay_frames[0]->avframe.display_picture_number; @@ -1907,7 +1911,7 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (delayed_frame) { - delayed_frame->avframe.reference ^= DELAYED_PIC_REF; + AV_NOWARN_DEPRECATED( delayed_frame->avframe.reference ^= DELAYED_PIC_REF; ); if((ret=av_frame_ref(data, &delayed_frame->avframe)) < 0) return ret; *got_frame = 1; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c index b55ee2a34..4afffcf6c 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c @@ -52,6 +52,7 @@ #include "ac3dec.h" #include "ac3dec_data.h" #include "eac3_data.h" +#include "libavutil/internal.h" /** gain adaptive quantization mode */ typedef enum { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722.c new file mode 100644 index 000000000..2c04c40b5 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722.c @@ -0,0 +1,171 @@ +/* + * G.722 ADPCM audio encoder/decoder + * + * Copyright (c) CMU 1993 Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * Copyright (c) 2005 Steve Underwood + * Copyright (c) 2009 Kenan Gillet + * Copyright (c) 2010 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * G.722 ADPCM audio codec + * + * This G.722 decoder is a bit-exact implementation of the ITU G.722 + * specification for all three specified bitrates - 64000bps, 56000bps + * and 48000bps. It passes the ITU tests. + * + * @note For the 56000bps and 48000bps bitrates, the lowest 1 or 2 bits + * respectively of each byte are ignored. + */ + +#include "mathops.h" +#include "g722.h" + +static const int8_t sign_lookup[2] = { -1, 1 }; + +static const int16_t inv_log2_table[32] = { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, + 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834, + 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, + 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008 +}; +static const int16_t high_log_factor_step[2] = { 798, -214 }; +const int16_t ff_g722_high_inv_quant[4] = { -926, -202, 926, 202 }; +/** + * low_log_factor_step[index] == wl[rl42[index]] + */ +static const int16_t low_log_factor_step[16] = { + -60, 3042, 1198, 538, 334, 172, 58, -30, + 3042, 1198, 538, 334, 172, 58, -30, -60 +}; +const int16_t ff_g722_low_inv_quant4[16] = { + 0, -2557, -1612, -1121, -786, -530, -323, -150, + 2557, 1612, 1121, 786, 530, 323, 150, 0 +}; +const int16_t ff_g722_low_inv_quant6[64] = { + -17, -17, -17, -17, -3101, -2738, -2376, -2088, + -1873, -1689, -1535, -1399, -1279, -1170, -1072, -982, + -899, -822, -750, -682, -618, -558, -501, -447, + -396, -347, -300, -254, -211, -170, -130, -91, + 3101, 2738, 2376, 2088, 1873, 1689, 1535, 1399, + 1279, 1170, 1072, 982, 899, 822, 750, 682, + 618, 558, 501, 447, 396, 347, 300, 254, + 211, 170, 130, 91, 54, 17, -54, -17 +}; + +/** + * quadrature mirror filter (QMF) coefficients + * + * ITU-T G.722 Table 11 + */ +static const int16_t qmf_coeffs[12] = { + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, +}; + + +/** + * adaptive predictor + * + * @param cur_diff the dequantized and scaled delta calculated from the + * current codeword + */ +static void do_adaptive_prediction(struct G722Band *band, const int cur_diff) +{ + int sg[2], limit, i, cur_qtzd_reconst; + + const int cur_part_reconst = band->s_zero + cur_diff < 0; + + sg[0] = sign_lookup[cur_part_reconst != band->part_reconst_mem[0]]; + sg[1] = sign_lookup[cur_part_reconst == band->part_reconst_mem[1]]; + band->part_reconst_mem[1] = band->part_reconst_mem[0]; + band->part_reconst_mem[0] = cur_part_reconst; + + band->pole_mem[1] = av_clip((sg[0] * av_clip(band->pole_mem[0], -8191, 8191) >> 5) + + (sg[1] << 7) + (band->pole_mem[1] * 127 >> 7), -12288, 12288); + + limit = 15360 - band->pole_mem[1]; + band->pole_mem[0] = av_clip(-192 * sg[0] + (band->pole_mem[0] * 255 >> 8), -limit, limit); + + + if (cur_diff) { + for (i = 0; i < 6; i++) + band->zero_mem[i] = ((band->zero_mem[i]*255) >> 8) + + ((band->diff_mem[i]^cur_diff) < 0 ? -128 : 128); + } else + for (i = 0; i < 6; i++) + band->zero_mem[i] = (band->zero_mem[i]*255) >> 8; + + for (i = 5; i > 0; i--) + band->diff_mem[i] = band->diff_mem[i-1]; + band->diff_mem[0] = av_clip_int16(cur_diff << 1); + + band->s_zero = 0; + for (i = 5; i >= 0; i--) + band->s_zero += (band->zero_mem[i]*band->diff_mem[i]) >> 15; + + + cur_qtzd_reconst = av_clip_int16((band->s_predictor + cur_diff) << 1); + band->s_predictor = av_clip_int16(band->s_zero + + (band->pole_mem[0] * cur_qtzd_reconst >> 15) + + (band->pole_mem[1] * band->prev_qtzd_reconst >> 15)); + band->prev_qtzd_reconst = cur_qtzd_reconst; +} + +static inline int linear_scale_factor(const int log_factor) +{ + const int wd1 = inv_log2_table[(log_factor >> 6) & 31]; + const int shift = log_factor >> 11; + return shift < 0 ? wd1 >> -shift : wd1 << shift; +} + +void ff_g722_update_low_predictor(struct G722Band *band, const int ilow) +{ + do_adaptive_prediction(band, + band->scale_factor * ff_g722_low_inv_quant4[ilow] >> 10); + + // quantizer adaptation + band->log_factor = av_clip((band->log_factor * 127 >> 7) + + low_log_factor_step[ilow], 0, 18432); + band->scale_factor = linear_scale_factor(band->log_factor - (8 << 11)); +} + +void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh, + const int ihigh) +{ + do_adaptive_prediction(band, dhigh); + + // quantizer adaptation + band->log_factor = av_clip((band->log_factor * 127 >> 7) + + high_log_factor_step[ihigh&1], 0, 22528); + band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11)); +} + +void ff_g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2) +{ + int i; + + *xout1 = 0; + *xout2 = 0; + for (i = 0; i < 12; i++) { + MAC16(*xout2, prev_samples[2*i ], qmf_coeffs[i ]); + MAC16(*xout1, prev_samples[2*i+1], qmf_coeffs[11-i]); + } +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722.h new file mode 100644 index 000000000..3f8982767 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) CMU 1993 Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * Copyright (c) 2005 Steve Underwood + * Copyright (c) 2009 Kenan Gillet + * Copyright (c) 2010 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_G722_H +#define AVCODEC_G722_H + +#include +#include "avcodec.h" + +#define PREV_SAMPLES_BUF_SIZE 1024 + +typedef struct G722Context { + const AVClass *class; + int bits_per_codeword; + int16_t prev_samples[PREV_SAMPLES_BUF_SIZE]; ///< memory of past decoded samples + int prev_samples_pos; ///< the number of values in prev_samples + + /** + * The band[0] and band[1] correspond respectively to the lower band and higher band. + */ + struct G722Band { + int16_t s_predictor; ///< predictor output value + int32_t s_zero; ///< previous output signal from zero predictor + int8_t part_reconst_mem[2]; ///< signs of previous partially reconstructed signals + int16_t prev_qtzd_reconst; ///< previous quantized reconstructed signal (internal value, using low_inv_quant4) + int16_t pole_mem[2]; ///< second-order pole section coefficient buffer + int32_t diff_mem[6]; ///< quantizer difference signal memory + int16_t zero_mem[6]; ///< Seventh-order zero section coefficient buffer + int16_t log_factor; ///< delayed 2-logarithmic quantizer factor + int16_t scale_factor; ///< delayed quantizer scale factor + } band[2]; + + struct TrellisNode { + struct G722Band state; + uint32_t ssd; + int path; + } *node_buf[2], **nodep_buf[2]; + + struct TrellisPath { + int value; + int prev; + } *paths[2]; +} G722Context; + +extern const int16_t ff_g722_high_inv_quant[4]; +extern const int16_t ff_g722_low_inv_quant4[16]; +extern const int16_t ff_g722_low_inv_quant6[64]; + +void ff_g722_update_low_predictor(struct G722Band *band, const int ilow); + +void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh, + const int ihigh); + +void ff_g722_apply_qmf(const int16_t *prev_samples, int *xout1, int *xout2); + +#endif /* AVCODEC_G722_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722dec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722dec.c new file mode 100644 index 000000000..d3b89fffc --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g722dec.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) CMU 1993 Computer Science, Speech Group + * Chengxiang Lu and Alex Hauptmann + * Copyright (c) 2005 Steve Underwood + * Copyright (c) 2009 Kenan Gillet + * Copyright (c) 2010 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * G.722 ADPCM audio decoder + * + * This G.722 decoder is a bit-exact implementation of the ITU G.722 + * specification for all three specified bitrates - 64000bps, 56000bps + * and 48000bps. It passes the ITU tests. + * + * @note For the 56000bps and 48000bps bitrates, the lowest 1 or 2 bits + * respectively of each byte are ignored. + */ + +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "get_bits.h" +#include "g722.h" +#include "internal.h" + +#define OFFSET(x) offsetof(G722Context, x) +#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + { "bits_per_codeword", "Bits per G722 codeword", OFFSET(bits_per_codeword), AV_OPT_TYPE_FLAGS, { .i64 = 8 }, 6, 8, AD }, + { NULL } +}; + +static const AVClass g722_decoder_class = { + .class_name = "g722 decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static av_cold int g722_decode_init(AVCodecContext * avctx) +{ + G722Context *c = avctx->priv_data; + + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + c->band[0].scale_factor = 8; + c->band[1].scale_factor = 2; + c->prev_samples_pos = 22; + + return 0; +} + +static const int16_t low_inv_quant5[32] = { + -35, -35, -2919, -2195, -1765, -1458, -1219, -1023, + -858, -714, -587, -473, -370, -276, -190, -110, + 2919, 2195, 1765, 1458, 1219, 1023, 858, 714, + 587, 473, 370, 276, 190, 110, 35, -35 +}; + +static const int16_t *low_inv_quants[3] = { ff_g722_low_inv_quant6, + low_inv_quant5, + ff_g722_low_inv_quant4 }; + +static int g722_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + G722Context *c = avctx->priv_data; + AVFrame *frame = data; + int16_t *out_buf; + int j, ret; + const int skip = 8 - c->bits_per_codeword; + const int16_t *quantizer_table = low_inv_quants[skip]; + GetBitContext gb; + + /* get output buffer */ + frame->nb_samples = avpkt->size * 2; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + out_buf = (int16_t *)frame->data[0]; + + init_get_bits(&gb, avpkt->data, avpkt->size * 8); + + for (j = 0; j < avpkt->size; j++) { + int ilow, ihigh, rlow, rhigh, dhigh; + int xout1, xout2; + + ihigh = get_bits(&gb, 2); + ilow = get_bits(&gb, 6 - skip); + skip_bits(&gb, skip); + + rlow = av_clip((c->band[0].scale_factor * quantizer_table[ilow] >> 10) + + c->band[0].s_predictor, -16384, 16383); + + ff_g722_update_low_predictor(&c->band[0], ilow >> (2 - skip)); + + dhigh = c->band[1].scale_factor * ff_g722_high_inv_quant[ihigh] >> 10; + rhigh = av_clip(dhigh + c->band[1].s_predictor, -16384, 16383); + + ff_g722_update_high_predictor(&c->band[1], dhigh, ihigh); + + c->prev_samples[c->prev_samples_pos++] = rlow + rhigh; + c->prev_samples[c->prev_samples_pos++] = rlow - rhigh; + ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, + &xout1, &xout2); + *out_buf++ = av_clip_int16(xout1 >> 11); + *out_buf++ = av_clip_int16(xout2 >> 11); + if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { + memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22, + 22 * sizeof(c->prev_samples[0])); + c->prev_samples_pos = 22; + } + } + + *got_frame_ptr = 1; + + return avpkt->size; +} + +AVCodec ff_adpcm_g722_decoder = { + .name = "g722", + .long_name = NULL_IF_CONFIG_SMALL("G.722 ADPCM"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ADPCM_G722, + .priv_data_size = sizeof(G722Context), + .init = g722_decode_init, + .decode = g722_decode_frame, + .capabilities = CODEC_CAP_DR1, + .priv_class = &g722_decoder_class, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g723_1.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g723_1.c new file mode 100644 index 000000000..ac279605c --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g723_1.c @@ -0,0 +1,2477 @@ +/* + * G.723.1 compatible decoder + * Copyright (c) 2006 Benjamin Larsson + * Copyright (c) 2010 Mohamed Naufal Basheer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * G.723.1 compatible decoder + */ + +#define BITSTREAM_READER_LE +#include "libavutil/channel_layout.h" +#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "get_bits.h" +#include "acelp_vectors.h" +#include "celp_filters.h" +#include "celp_math.h" +#include "g723_1_data.h" +#include "internal.h" + +#define CNG_RANDOM_SEED 12345 + +typedef struct g723_1_context { + AVClass *class; + + G723_1_Subframe subframe[4]; + enum FrameType cur_frame_type; + enum FrameType past_frame_type; + enum Rate cur_rate; + uint8_t lsp_index[LSP_BANDS]; + int pitch_lag[2]; + int erased_frames; + + int16_t prev_lsp[LPC_ORDER]; + int16_t sid_lsp[LPC_ORDER]; + int16_t prev_excitation[PITCH_MAX]; + int16_t excitation[PITCH_MAX + FRAME_LEN + 4]; + int16_t synth_mem[LPC_ORDER]; + int16_t fir_mem[LPC_ORDER]; + int iir_mem[LPC_ORDER]; + + int random_seed; + int cng_random_seed; + int interp_index; + int interp_gain; + int sid_gain; + int cur_gain; + int reflection_coef; + int pf_gain; ///< formant postfilter + ///< gain scaling unit memory + int postfilter; + + int16_t audio[FRAME_LEN + LPC_ORDER + PITCH_MAX + 4]; + int16_t prev_data[HALF_FRAME_LEN]; + int16_t prev_weight_sig[PITCH_MAX]; + + + int16_t hpf_fir_mem; ///< highpass filter fir + int hpf_iir_mem; ///< and iir memories + int16_t perf_fir_mem[LPC_ORDER]; ///< perceptual filter fir + int16_t perf_iir_mem[LPC_ORDER]; ///< and iir memories + + int16_t harmonic_mem[PITCH_MAX]; +} G723_1_Context; + +static av_cold int g723_1_decode_init(AVCodecContext *avctx) +{ + G723_1_Context *p = avctx->priv_data; + + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->channels = 1; + p->pf_gain = 1 << 12; + + memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(*p->prev_lsp)); + memcpy(p->sid_lsp, dc_lsp, LPC_ORDER * sizeof(*p->sid_lsp)); + + p->cng_random_seed = CNG_RANDOM_SEED; + p->past_frame_type = SID_FRAME; + + return 0; +} + +/** + * Unpack the frame into parameters. + * + * @param p the context + * @param buf pointer to the input buffer + * @param buf_size size of the input buffer + */ +static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, + int buf_size) +{ + GetBitContext gb; + int ad_cb_len; + int temp, info_bits, i; + + init_get_bits(&gb, buf, buf_size * 8); + + /* Extract frame type and rate info */ + info_bits = get_bits(&gb, 2); + + if (info_bits == 3) { + p->cur_frame_type = UNTRANSMITTED_FRAME; + return 0; + } + + /* Extract 24 bit lsp indices, 8 bit for each band */ + p->lsp_index[2] = get_bits(&gb, 8); + p->lsp_index[1] = get_bits(&gb, 8); + p->lsp_index[0] = get_bits(&gb, 8); + + if (info_bits == 2) { + p->cur_frame_type = SID_FRAME; + p->subframe[0].amp_index = get_bits(&gb, 6); + return 0; + } + + /* Extract the info common to both rates */ + p->cur_rate = info_bits ? RATE_5300 : RATE_6300; + p->cur_frame_type = ACTIVE_FRAME; + + p->pitch_lag[0] = get_bits(&gb, 7); + if (p->pitch_lag[0] > 123) /* test if forbidden code */ + return -1; + p->pitch_lag[0] += PITCH_MIN; + p->subframe[1].ad_cb_lag = get_bits(&gb, 2); + + p->pitch_lag[1] = get_bits(&gb, 7); + if (p->pitch_lag[1] > 123) + return -1; + p->pitch_lag[1] += PITCH_MIN; + p->subframe[3].ad_cb_lag = get_bits(&gb, 2); + p->subframe[0].ad_cb_lag = 1; + p->subframe[2].ad_cb_lag = 1; + + for (i = 0; i < SUBFRAMES; i++) { + /* Extract combined gain */ + temp = get_bits(&gb, 12); + ad_cb_len = 170; + p->subframe[i].dirac_train = 0; + if (p->cur_rate == RATE_6300 && p->pitch_lag[i >> 1] < SUBFRAME_LEN - 2) { + p->subframe[i].dirac_train = temp >> 11; + temp &= 0x7FF; + ad_cb_len = 85; + } + p->subframe[i].ad_cb_gain = FASTDIV(temp, GAIN_LEVELS); + if (p->subframe[i].ad_cb_gain < ad_cb_len) { + p->subframe[i].amp_index = temp - p->subframe[i].ad_cb_gain * + GAIN_LEVELS; + } else { + return -1; + } + } + + p->subframe[0].grid_index = get_bits1(&gb); + p->subframe[1].grid_index = get_bits1(&gb); + p->subframe[2].grid_index = get_bits1(&gb); + p->subframe[3].grid_index = get_bits1(&gb); + + if (p->cur_rate == RATE_6300) { + skip_bits1(&gb); /* skip reserved bit */ + + /* Compute pulse_pos index using the 13-bit combined position index */ + temp = get_bits(&gb, 13); + p->subframe[0].pulse_pos = temp / 810; + + temp -= p->subframe[0].pulse_pos * 810; + p->subframe[1].pulse_pos = FASTDIV(temp, 90); + + temp -= p->subframe[1].pulse_pos * 90; + p->subframe[2].pulse_pos = FASTDIV(temp, 9); + p->subframe[3].pulse_pos = temp - p->subframe[2].pulse_pos * 9; + + p->subframe[0].pulse_pos = (p->subframe[0].pulse_pos << 16) + + get_bits(&gb, 16); + p->subframe[1].pulse_pos = (p->subframe[1].pulse_pos << 14) + + get_bits(&gb, 14); + p->subframe[2].pulse_pos = (p->subframe[2].pulse_pos << 16) + + get_bits(&gb, 16); + p->subframe[3].pulse_pos = (p->subframe[3].pulse_pos << 14) + + get_bits(&gb, 14); + + p->subframe[0].pulse_sign = get_bits(&gb, 6); + p->subframe[1].pulse_sign = get_bits(&gb, 5); + p->subframe[2].pulse_sign = get_bits(&gb, 6); + p->subframe[3].pulse_sign = get_bits(&gb, 5); + } else { /* 5300 bps */ + p->subframe[0].pulse_pos = get_bits(&gb, 12); + p->subframe[1].pulse_pos = get_bits(&gb, 12); + p->subframe[2].pulse_pos = get_bits(&gb, 12); + p->subframe[3].pulse_pos = get_bits(&gb, 12); + + p->subframe[0].pulse_sign = get_bits(&gb, 4); + p->subframe[1].pulse_sign = get_bits(&gb, 4); + p->subframe[2].pulse_sign = get_bits(&gb, 4); + p->subframe[3].pulse_sign = get_bits(&gb, 4); + } + + return 0; +} + +/** + * Bitexact implementation of sqrt(val/2). + */ +static int16_t square_root(unsigned val) +{ + av_assert2(!(val & 0x80000000)); + + return (ff_sqrt(val << 1) >> 1) & (~1); +} + +/** + * Calculate the number of left-shifts required for normalizing the input. + * + * @param num input number + * @param width width of the input, 15 or 31 bits + */ +static int normalize_bits(int num, int width) +{ + return width - av_log2(num) - 1; +} + +#define normalize_bits_int16(num) normalize_bits(num, 15) +#define normalize_bits_int32(num) normalize_bits(num, 31) + +/** + * Scale vector contents based on the largest of their absolutes. + */ +static int scale_vector(int16_t *dst, const int16_t *vector, int length) +{ + int bits, max = 0; + int i; + + for (i = 0; i < length; i++) + max |= FFABS(vector[i]); + + bits= 14 - av_log2_16bit(max); + bits= FFMAX(bits, 0); + + for (i = 0; i < length; i++) + dst[i] = vector[i] << bits >> 3; + + return bits - 3; +} + +/** + * Perform inverse quantization of LSP frequencies. + * + * @param cur_lsp the current LSP vector + * @param prev_lsp the previous LSP vector + * @param lsp_index VQ indices + * @param bad_frame bad frame flag + */ +static void inverse_quant(int16_t *cur_lsp, int16_t *prev_lsp, + uint8_t *lsp_index, int bad_frame) +{ + int min_dist, pred; + int i, j, temp, stable; + + /* Check for frame erasure */ + if (!bad_frame) { + min_dist = 0x100; + pred = 12288; + } else { + min_dist = 0x200; + pred = 23552; + lsp_index[0] = lsp_index[1] = lsp_index[2] = 0; + } + + /* Get the VQ table entry corresponding to the transmitted index */ + cur_lsp[0] = lsp_band0[lsp_index[0]][0]; + cur_lsp[1] = lsp_band0[lsp_index[0]][1]; + cur_lsp[2] = lsp_band0[lsp_index[0]][2]; + cur_lsp[3] = lsp_band1[lsp_index[1]][0]; + cur_lsp[4] = lsp_band1[lsp_index[1]][1]; + cur_lsp[5] = lsp_band1[lsp_index[1]][2]; + cur_lsp[6] = lsp_band2[lsp_index[2]][0]; + cur_lsp[7] = lsp_band2[lsp_index[2]][1]; + cur_lsp[8] = lsp_band2[lsp_index[2]][2]; + cur_lsp[9] = lsp_band2[lsp_index[2]][3]; + + /* Add predicted vector & DC component to the previously quantized vector */ + for (i = 0; i < LPC_ORDER; i++) { + temp = ((prev_lsp[i] - dc_lsp[i]) * pred + (1 << 14)) >> 15; + cur_lsp[i] += dc_lsp[i] + temp; + } + + for (i = 0; i < LPC_ORDER; i++) { + cur_lsp[0] = FFMAX(cur_lsp[0], 0x180); + cur_lsp[LPC_ORDER - 1] = FFMIN(cur_lsp[LPC_ORDER - 1], 0x7e00); + + /* Stability check */ + for (j = 1; j < LPC_ORDER; j++) { + temp = min_dist + cur_lsp[j - 1] - cur_lsp[j]; + if (temp > 0) { + temp >>= 1; + cur_lsp[j - 1] -= temp; + cur_lsp[j] += temp; + } + } + stable = 1; + for (j = 1; j < LPC_ORDER; j++) { + temp = cur_lsp[j - 1] + min_dist - cur_lsp[j] - 4; + if (temp > 0) { + stable = 0; + break; + } + } + if (stable) + break; + } + if (!stable) + memcpy(cur_lsp, prev_lsp, LPC_ORDER * sizeof(*cur_lsp)); +} + +/** + * Bitexact implementation of 2ab scaled by 1/2^16. + * + * @param a 32 bit multiplicand + * @param b 16 bit multiplier + */ +#define MULL2(a, b) \ + MULL(a,b,15) + +/** + * Convert LSP frequencies to LPC coefficients. + * + * @param lpc buffer for LPC coefficients + */ +static void lsp2lpc(int16_t *lpc) +{ + int f1[LPC_ORDER / 2 + 1]; + int f2[LPC_ORDER / 2 + 1]; + int i, j; + + /* Calculate negative cosine */ + for (j = 0; j < LPC_ORDER; j++) { + int index = (lpc[j] >> 7) & 0x1FF; + int offset = lpc[j] & 0x7f; + int temp1 = cos_tab[index] << 16; + int temp2 = (cos_tab[index + 1] - cos_tab[index]) * + ((offset << 8) + 0x80) << 1; + + lpc[j] = -(av_sat_dadd32(1 << 15, temp1 + temp2) >> 16); + } + + /* + * Compute sum and difference polynomial coefficients + * (bitexact alternative to lsp2poly() in lsp.c) + */ + /* Initialize with values in Q28 */ + f1[0] = 1 << 28; + f1[1] = (lpc[0] << 14) + (lpc[2] << 14); + f1[2] = lpc[0] * lpc[2] + (2 << 28); + + f2[0] = 1 << 28; + f2[1] = (lpc[1] << 14) + (lpc[3] << 14); + f2[2] = lpc[1] * lpc[3] + (2 << 28); + + /* + * Calculate and scale the coefficients by 1/2 in + * each iteration for a final scaling factor of Q25 + */ + for (i = 2; i < LPC_ORDER / 2; i++) { + f1[i + 1] = f1[i - 1] + MULL2(f1[i], lpc[2 * i]); + f2[i + 1] = f2[i - 1] + MULL2(f2[i], lpc[2 * i + 1]); + + for (j = i; j >= 2; j--) { + f1[j] = MULL2(f1[j - 1], lpc[2 * i]) + + (f1[j] >> 1) + (f1[j - 2] >> 1); + f2[j] = MULL2(f2[j - 1], lpc[2 * i + 1]) + + (f2[j] >> 1) + (f2[j - 2] >> 1); + } + + f1[0] >>= 1; + f2[0] >>= 1; + f1[1] = ((lpc[2 * i] << 16 >> i) + f1[1]) >> 1; + f2[1] = ((lpc[2 * i + 1] << 16 >> i) + f2[1]) >> 1; + } + + /* Convert polynomial coefficients to LPC coefficients */ + for (i = 0; i < LPC_ORDER / 2; i++) { + int64_t ff1 = f1[i + 1] + f1[i]; + int64_t ff2 = f2[i + 1] - f2[i]; + + lpc[i] = av_clipl_int32(((ff1 + ff2) << 3) + (1 << 15)) >> 16; + lpc[LPC_ORDER - i - 1] = av_clipl_int32(((ff1 - ff2) << 3) + + (1 << 15)) >> 16; + } +} + +/** + * Quantize LSP frequencies by interpolation and convert them to + * the corresponding LPC coefficients. + * + * @param lpc buffer for LPC coefficients + * @param cur_lsp the current LSP vector + * @param prev_lsp the previous LSP vector + */ +static void lsp_interpolate(int16_t *lpc, int16_t *cur_lsp, int16_t *prev_lsp) +{ + int i; + int16_t *lpc_ptr = lpc; + + /* cur_lsp * 0.25 + prev_lsp * 0.75 */ + ff_acelp_weighted_vector_sum(lpc, cur_lsp, prev_lsp, + 4096, 12288, 1 << 13, 14, LPC_ORDER); + ff_acelp_weighted_vector_sum(lpc + LPC_ORDER, cur_lsp, prev_lsp, + 8192, 8192, 1 << 13, 14, LPC_ORDER); + ff_acelp_weighted_vector_sum(lpc + 2 * LPC_ORDER, cur_lsp, prev_lsp, + 12288, 4096, 1 << 13, 14, LPC_ORDER); + memcpy(lpc + 3 * LPC_ORDER, cur_lsp, LPC_ORDER * sizeof(*lpc)); + + for (i = 0; i < SUBFRAMES; i++) { + lsp2lpc(lpc_ptr); + lpc_ptr += LPC_ORDER; + } +} + +/** + * Generate a train of dirac functions with period as pitch lag. + */ +static void gen_dirac_train(int16_t *buf, int pitch_lag) +{ + int16_t vector[SUBFRAME_LEN]; + int i, j; + + memcpy(vector, buf, SUBFRAME_LEN * sizeof(*vector)); + for (i = pitch_lag; i < SUBFRAME_LEN; i += pitch_lag) { + for (j = 0; j < SUBFRAME_LEN - i; j++) + buf[i + j] += vector[j]; + } +} + +/** + * Generate fixed codebook excitation vector. + * + * @param vector decoded excitation vector + * @param subfrm current subframe + * @param cur_rate current bitrate + * @param pitch_lag closed loop pitch lag + * @param index current subframe index + */ +static void gen_fcb_excitation(int16_t *vector, G723_1_Subframe *subfrm, + enum Rate cur_rate, int pitch_lag, int index) +{ + int temp, i, j; + + memset(vector, 0, SUBFRAME_LEN * sizeof(*vector)); + + if (cur_rate == RATE_6300) { + if (subfrm->pulse_pos >= max_pos[index]) + return; + + /* Decode amplitudes and positions */ + j = PULSE_MAX - pulses[index]; + temp = subfrm->pulse_pos; + for (i = 0; i < SUBFRAME_LEN / GRID_SIZE; i++) { + temp -= combinatorial_table[j][i]; + if (temp >= 0) + continue; + temp += combinatorial_table[j++][i]; + if (subfrm->pulse_sign & (1 << (PULSE_MAX - j))) { + vector[subfrm->grid_index + GRID_SIZE * i] = + -fixed_cb_gain[subfrm->amp_index]; + } else { + vector[subfrm->grid_index + GRID_SIZE * i] = + fixed_cb_gain[subfrm->amp_index]; + } + if (j == PULSE_MAX) + break; + } + if (subfrm->dirac_train == 1) + gen_dirac_train(vector, pitch_lag); + } else { /* 5300 bps */ + int cb_gain = fixed_cb_gain[subfrm->amp_index]; + int cb_shift = subfrm->grid_index; + int cb_sign = subfrm->pulse_sign; + int cb_pos = subfrm->pulse_pos; + int offset, beta, lag; + + for (i = 0; i < 8; i += 2) { + offset = ((cb_pos & 7) << 3) + cb_shift + i; + vector[offset] = (cb_sign & 1) ? cb_gain : -cb_gain; + cb_pos >>= 3; + cb_sign >>= 1; + } + + /* Enhance harmonic components */ + lag = pitch_contrib[subfrm->ad_cb_gain << 1] + pitch_lag + + subfrm->ad_cb_lag - 1; + beta = pitch_contrib[(subfrm->ad_cb_gain << 1) + 1]; + + if (lag < SUBFRAME_LEN - 2) { + for (i = lag; i < SUBFRAME_LEN; i++) + vector[i] += beta * vector[i - lag] >> 15; + } + } +} + +/** + * Get delayed contribution from the previous excitation vector. + */ +static void get_residual(int16_t *residual, int16_t *prev_excitation, int lag) +{ + int offset = PITCH_MAX - PITCH_ORDER / 2 - lag; + int i; + + residual[0] = prev_excitation[offset]; + residual[1] = prev_excitation[offset + 1]; + + offset += 2; + for (i = 2; i < SUBFRAME_LEN + PITCH_ORDER - 1; i++) + residual[i] = prev_excitation[offset + (i - 2) % lag]; +} + +static int dot_product(const int16_t *a, const int16_t *b, int length) +{ + int sum = ff_dot_product(a,b,length); + return av_sat_add32(sum, sum); +} + +/** + * Generate adaptive codebook excitation. + */ +static void gen_acb_excitation(int16_t *vector, int16_t *prev_excitation, + int pitch_lag, G723_1_Subframe *subfrm, + enum Rate cur_rate) +{ + int16_t residual[SUBFRAME_LEN + PITCH_ORDER - 1]; + const int16_t *cb_ptr; + int lag = pitch_lag + subfrm->ad_cb_lag - 1; + + int i; + int sum; + + get_residual(residual, prev_excitation, lag); + + /* Select quantization table */ + if (cur_rate == RATE_6300 && pitch_lag < SUBFRAME_LEN - 2) { + cb_ptr = adaptive_cb_gain85; + } else + cb_ptr = adaptive_cb_gain170; + + /* Calculate adaptive vector */ + cb_ptr += subfrm->ad_cb_gain * 20; + for (i = 0; i < SUBFRAME_LEN; i++) { + sum = ff_dot_product(residual + i, cb_ptr, PITCH_ORDER); + vector[i] = av_sat_dadd32(1 << 15, av_sat_add32(sum, sum)) >> 16; + } +} + +/** + * Estimate maximum auto-correlation around pitch lag. + * + * @param buf buffer with offset applied + * @param offset offset of the excitation vector + * @param ccr_max pointer to the maximum auto-correlation + * @param pitch_lag decoded pitch lag + * @param length length of autocorrelation + * @param dir forward lag(1) / backward lag(-1) + */ +static int autocorr_max(const int16_t *buf, int offset, int *ccr_max, + int pitch_lag, int length, int dir) +{ + int limit, ccr, lag = 0; + int i; + + pitch_lag = FFMIN(PITCH_MAX - 3, pitch_lag); + if (dir > 0) + limit = FFMIN(FRAME_LEN + PITCH_MAX - offset - length, pitch_lag + 3); + else + limit = pitch_lag + 3; + + for (i = pitch_lag - 3; i <= limit; i++) { + ccr = dot_product(buf, buf + dir * i, length); + + if (ccr > *ccr_max) { + *ccr_max = ccr; + lag = i; + } + } + return lag; +} + +/** + * Calculate pitch postfilter optimal and scaling gains. + * + * @param lag pitch postfilter forward/backward lag + * @param ppf pitch postfilter parameters + * @param cur_rate current bitrate + * @param tgt_eng target energy + * @param ccr cross-correlation + * @param res_eng residual energy + */ +static void comp_ppf_gains(int lag, PPFParam *ppf, enum Rate cur_rate, + int tgt_eng, int ccr, int res_eng) +{ + int pf_residual; /* square of postfiltered residual */ + int temp1, temp2; + + ppf->index = lag; + + temp1 = tgt_eng * res_eng >> 1; + temp2 = ccr * ccr << 1; + + if (temp2 > temp1) { + if (ccr >= res_eng) { + ppf->opt_gain = ppf_gain_weight[cur_rate]; + } else { + ppf->opt_gain = (ccr << 15) / res_eng * + ppf_gain_weight[cur_rate] >> 15; + } + /* pf_res^2 = tgt_eng + 2*ccr*gain + res_eng*gain^2 */ + temp1 = (tgt_eng << 15) + (ccr * ppf->opt_gain << 1); + temp2 = (ppf->opt_gain * ppf->opt_gain >> 15) * res_eng; + pf_residual = av_sat_add32(temp1, temp2 + (1 << 15)) >> 16; + + if (tgt_eng >= pf_residual << 1) { + temp1 = 0x7fff; + } else { + temp1 = (tgt_eng << 14) / pf_residual; + } + + /* scaling_gain = sqrt(tgt_eng/pf_res^2) */ + ppf->sc_gain = square_root(temp1 << 16); + } else { + ppf->opt_gain = 0; + ppf->sc_gain = 0x7fff; + } + + ppf->opt_gain = av_clip_int16(ppf->opt_gain * ppf->sc_gain >> 15); +} + +/** + * Calculate pitch postfilter parameters. + * + * @param p the context + * @param offset offset of the excitation vector + * @param pitch_lag decoded pitch lag + * @param ppf pitch postfilter parameters + * @param cur_rate current bitrate + */ +static void comp_ppf_coeff(G723_1_Context *p, int offset, int pitch_lag, + PPFParam *ppf, enum Rate cur_rate) +{ + + int16_t scale; + int i; + int temp1, temp2; + + /* + * 0 - target energy + * 1 - forward cross-correlation + * 2 - forward residual energy + * 3 - backward cross-correlation + * 4 - backward residual energy + */ + int energy[5] = {0, 0, 0, 0, 0}; + int16_t *buf = p->audio + LPC_ORDER + offset; + int fwd_lag = autocorr_max(buf, offset, &energy[1], pitch_lag, + SUBFRAME_LEN, 1); + int back_lag = autocorr_max(buf, offset, &energy[3], pitch_lag, + SUBFRAME_LEN, -1); + + ppf->index = 0; + ppf->opt_gain = 0; + ppf->sc_gain = 0x7fff; + + /* Case 0, Section 3.6 */ + if (!back_lag && !fwd_lag) + return; + + /* Compute target energy */ + energy[0] = dot_product(buf, buf, SUBFRAME_LEN); + + /* Compute forward residual energy */ + if (fwd_lag) + energy[2] = dot_product(buf + fwd_lag, buf + fwd_lag, SUBFRAME_LEN); + + /* Compute backward residual energy */ + if (back_lag) + energy[4] = dot_product(buf - back_lag, buf - back_lag, SUBFRAME_LEN); + + /* Normalize and shorten */ + temp1 = 0; + for (i = 0; i < 5; i++) + temp1 = FFMAX(energy[i], temp1); + + scale = normalize_bits(temp1, 31); + for (i = 0; i < 5; i++) + energy[i] = (energy[i] << scale) >> 16; + + if (fwd_lag && !back_lag) { /* Case 1 */ + comp_ppf_gains(fwd_lag, ppf, cur_rate, energy[0], energy[1], + energy[2]); + } else if (!fwd_lag) { /* Case 2 */ + comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3], + energy[4]); + } else { /* Case 3 */ + + /* + * Select the largest of energy[1]^2/energy[2] + * and energy[3]^2/energy[4] + */ + temp1 = energy[4] * ((energy[1] * energy[1] + (1 << 14)) >> 15); + temp2 = energy[2] * ((energy[3] * energy[3] + (1 << 14)) >> 15); + if (temp1 >= temp2) { + comp_ppf_gains(fwd_lag, ppf, cur_rate, energy[0], energy[1], + energy[2]); + } else { + comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3], + energy[4]); + } + } +} + +/** + * Classify frames as voiced/unvoiced. + * + * @param p the context + * @param pitch_lag decoded pitch_lag + * @param exc_eng excitation energy estimation + * @param scale scaling factor of exc_eng + * + * @return residual interpolation index if voiced, 0 otherwise + */ +static int comp_interp_index(G723_1_Context *p, int pitch_lag, + int *exc_eng, int *scale) +{ + int offset = PITCH_MAX + 2 * SUBFRAME_LEN; + int16_t *buf = p->audio + LPC_ORDER; + + int index, ccr, tgt_eng, best_eng, temp; + + *scale = scale_vector(buf, p->excitation, FRAME_LEN + PITCH_MAX); + buf += offset; + + /* Compute maximum backward cross-correlation */ + ccr = 0; + index = autocorr_max(buf, offset, &ccr, pitch_lag, SUBFRAME_LEN * 2, -1); + ccr = av_sat_add32(ccr, 1 << 15) >> 16; + + /* Compute target energy */ + tgt_eng = dot_product(buf, buf, SUBFRAME_LEN * 2); + *exc_eng = av_sat_add32(tgt_eng, 1 << 15) >> 16; + + if (ccr <= 0) + return 0; + + /* Compute best energy */ + best_eng = dot_product(buf - index, buf - index, SUBFRAME_LEN * 2); + best_eng = av_sat_add32(best_eng, 1 << 15) >> 16; + + temp = best_eng * *exc_eng >> 3; + + if (temp < ccr * ccr) { + return index; + } else + return 0; +} + +/** + * Peform residual interpolation based on frame classification. + * + * @param buf decoded excitation vector + * @param out output vector + * @param lag decoded pitch lag + * @param gain interpolated gain + * @param rseed seed for random number generator + */ +static void residual_interp(int16_t *buf, int16_t *out, int lag, + int gain, int *rseed) +{ + int i; + if (lag) { /* Voiced */ + int16_t *vector_ptr = buf + PITCH_MAX; + /* Attenuate */ + for (i = 0; i < lag; i++) + out[i] = vector_ptr[i - lag] * 3 >> 2; + av_memcpy_backptr((uint8_t*)(out + lag), lag * sizeof(*out), + (FRAME_LEN - lag) * sizeof(*out)); + } else { /* Unvoiced */ + for (i = 0; i < FRAME_LEN; i++) { + *rseed = *rseed * 521 + 259; + out[i] = gain * *rseed >> 15; + } + memset(buf, 0, (FRAME_LEN + PITCH_MAX) * sizeof(*buf)); + } +} + +/** + * Perform IIR filtering. + * + * @param fir_coef FIR coefficients + * @param iir_coef IIR coefficients + * @param src source vector + * @param dest destination vector + * @param width width of the output, 16 bits(0) / 32 bits(1) + */ +#define iir_filter(fir_coef, iir_coef, src, dest, width)\ +{\ + int m, n;\ + int res_shift = 16 & ~-(width);\ + int in_shift = 16 - res_shift;\ +\ + for (m = 0; m < SUBFRAME_LEN; m++) {\ + int64_t filter = 0;\ + for (n = 1; n <= LPC_ORDER; n++) {\ + filter -= (fir_coef)[n - 1] * (src)[m - n] -\ + (iir_coef)[n - 1] * ((dest)[m - n] >> in_shift);\ + }\ +\ + (dest)[m] = av_clipl_int32(((src)[m] << 16) + (filter << 3) +\ + (1 << 15)) >> res_shift;\ + }\ +} + +/** + * Adjust gain of postfiltered signal. + * + * @param p the context + * @param buf postfiltered output vector + * @param energy input energy coefficient + */ +static void gain_scale(G723_1_Context *p, int16_t * buf, int energy) +{ + int num, denom, gain, bits1, bits2; + int i; + + num = energy; + denom = 0; + for (i = 0; i < SUBFRAME_LEN; i++) { + int temp = buf[i] >> 2; + temp *= temp; + denom = av_sat_dadd32(denom, temp); + } + + if (num && denom) { + bits1 = normalize_bits(num, 31); + bits2 = normalize_bits(denom, 31); + num = num << bits1 >> 1; + denom <<= bits2; + + bits2 = 5 + bits1 - bits2; + bits2 = FFMAX(0, bits2); + + gain = (num >> 1) / (denom >> 16); + gain = square_root(gain << 16 >> bits2); + } else { + gain = 1 << 12; + } + + for (i = 0; i < SUBFRAME_LEN; i++) { + p->pf_gain = (15 * p->pf_gain + gain + (1 << 3)) >> 4; + buf[i] = av_clip_int16((buf[i] * (p->pf_gain + (p->pf_gain >> 4)) + + (1 << 10)) >> 11); + } +} + +/** + * Perform formant filtering. + * + * @param p the context + * @param lpc quantized lpc coefficients + * @param buf input buffer + * @param dst output buffer + */ +static void formant_postfilter(G723_1_Context *p, int16_t *lpc, + int16_t *buf, int16_t *dst) +{ + int16_t filter_coef[2][LPC_ORDER]; + int filter_signal[LPC_ORDER + FRAME_LEN], *signal_ptr; + int i, j, k; + + memcpy(buf, p->fir_mem, LPC_ORDER * sizeof(*buf)); + memcpy(filter_signal, p->iir_mem, LPC_ORDER * sizeof(*filter_signal)); + + for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) { + for (k = 0; k < LPC_ORDER; k++) { + filter_coef[0][k] = (-lpc[k] * postfilter_tbl[0][k] + + (1 << 14)) >> 15; + filter_coef[1][k] = (-lpc[k] * postfilter_tbl[1][k] + + (1 << 14)) >> 15; + } + iir_filter(filter_coef[0], filter_coef[1], buf + i, + filter_signal + i, 1); + lpc += LPC_ORDER; + } + + memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(int16_t)); + memcpy(p->iir_mem, filter_signal + FRAME_LEN, LPC_ORDER * sizeof(int)); + + buf += LPC_ORDER; + signal_ptr = filter_signal + LPC_ORDER; + for (i = 0; i < SUBFRAMES; i++) { + int temp; + int auto_corr[2]; + int scale, energy; + + /* Normalize */ + scale = scale_vector(dst, buf, SUBFRAME_LEN); + + /* Compute auto correlation coefficients */ + auto_corr[0] = dot_product(dst, dst + 1, SUBFRAME_LEN - 1); + auto_corr[1] = dot_product(dst, dst, SUBFRAME_LEN); + + /* Compute reflection coefficient */ + temp = auto_corr[1] >> 16; + if (temp) { + temp = (auto_corr[0] >> 2) / temp; + } + p->reflection_coef = (3 * p->reflection_coef + temp + 2) >> 2; + temp = -p->reflection_coef >> 1 & ~3; + + /* Compensation filter */ + for (j = 0; j < SUBFRAME_LEN; j++) { + dst[j] = av_sat_dadd32(signal_ptr[j], + (signal_ptr[j - 1] >> 16) * temp) >> 16; + } + + /* Compute normalized signal energy */ + temp = 2 * scale + 4; + if (temp < 0) { + energy = av_clipl_int32((int64_t)auto_corr[1] << -temp); + } else + energy = auto_corr[1] >> temp; + + gain_scale(p, dst, energy); + + buf += SUBFRAME_LEN; + signal_ptr += SUBFRAME_LEN; + dst += SUBFRAME_LEN; + } +} + +static int sid_gain_to_lsp_index(int gain) +{ + if (gain < 0x10) + return gain << 6; + else if (gain < 0x20) + return (gain - 8) << 7; + else + return (gain - 20) << 8; +} + +static inline int cng_rand(int *state, int base) +{ + *state = (*state * 521 + 259) & 0xFFFF; + return (*state & 0x7FFF) * base >> 15; +} + +static int estimate_sid_gain(G723_1_Context *p) +{ + int i, shift, seg, seg2, t, val, val_add, x, y; + + shift = 16 - p->cur_gain * 2; + if (shift > 0) + t = p->sid_gain << shift; + else + t = p->sid_gain >> -shift; + x = t * cng_filt[0] >> 16; + + if (x >= cng_bseg[2]) + return 0x3F; + + if (x >= cng_bseg[1]) { + shift = 4; + seg = 3; + } else { + shift = 3; + seg = (x >= cng_bseg[0]); + } + seg2 = FFMIN(seg, 3); + + val = 1 << shift; + val_add = val >> 1; + for (i = 0; i < shift; i++) { + t = seg * 32 + (val << seg2); + t *= t; + if (x >= t) + val += val_add; + else + val -= val_add; + val_add >>= 1; + } + + t = seg * 32 + (val << seg2); + y = t * t - x; + if (y <= 0) { + t = seg * 32 + ((val + 1) << seg2); + t = t * t - x; + val = ((seg2 - 1) << 4) + val; + if (t >= y) + val++; + } else { + t = seg * 32 + ((val - 1) << seg2); + t = t * t - x; + val = ((seg2 - 1) << 4) + val; + if (t >= y) + val--; + } + + return val; +} + +static void generate_noise(G723_1_Context *p) +{ + int i, j, idx, t; + int off[SUBFRAMES]; + int signs[SUBFRAMES / 2 * 11], pos[SUBFRAMES / 2 * 11]; + int tmp[SUBFRAME_LEN * 2]; + int16_t *vector_ptr; + int64_t sum; + int b0, c, delta, x, shift; + + p->pitch_lag[0] = cng_rand(&p->cng_random_seed, 21) + 123; + p->pitch_lag[1] = cng_rand(&p->cng_random_seed, 19) + 123; + + for (i = 0; i < SUBFRAMES; i++) { + p->subframe[i].ad_cb_gain = cng_rand(&p->cng_random_seed, 50) + 1; + p->subframe[i].ad_cb_lag = cng_adaptive_cb_lag[i]; + } + + for (i = 0; i < SUBFRAMES / 2; i++) { + t = cng_rand(&p->cng_random_seed, 1 << 13); + off[i * 2] = t & 1; + off[i * 2 + 1] = ((t >> 1) & 1) + SUBFRAME_LEN; + t >>= 2; + for (j = 0; j < 11; j++) { + signs[i * 11 + j] = ((t & 1) * 2 - 1) << 14; + t >>= 1; + } + } + + idx = 0; + for (i = 0; i < SUBFRAMES; i++) { + for (j = 0; j < SUBFRAME_LEN / 2; j++) + tmp[j] = j; + t = SUBFRAME_LEN / 2; + for (j = 0; j < pulses[i]; j++, idx++) { + int idx2 = cng_rand(&p->cng_random_seed, t); + + pos[idx] = tmp[idx2] * 2 + off[i]; + tmp[idx2] = tmp[--t]; + } + } + + vector_ptr = p->audio + LPC_ORDER; + memcpy(vector_ptr, p->prev_excitation, + PITCH_MAX * sizeof(*p->excitation)); + for (i = 0; i < SUBFRAMES; i += 2) { + gen_acb_excitation(vector_ptr, vector_ptr, + p->pitch_lag[i >> 1], &p->subframe[i], + p->cur_rate); + gen_acb_excitation(vector_ptr + SUBFRAME_LEN, + vector_ptr + SUBFRAME_LEN, + p->pitch_lag[i >> 1], &p->subframe[i + 1], + p->cur_rate); + + t = 0; + for (j = 0; j < SUBFRAME_LEN * 2; j++) + t |= FFABS(vector_ptr[j]); + t = FFMIN(t, 0x7FFF); + if (!t) { + shift = 0; + } else { + shift = -10 + av_log2(t); + if (shift < -2) + shift = -2; + } + sum = 0; + if (shift < 0) { + for (j = 0; j < SUBFRAME_LEN * 2; j++) { + t = vector_ptr[j] << -shift; + sum += t * t; + tmp[j] = t; + } + } else { + for (j = 0; j < SUBFRAME_LEN * 2; j++) { + t = vector_ptr[j] >> shift; + sum += t * t; + tmp[j] = t; + } + } + + b0 = 0; + for (j = 0; j < 11; j++) + b0 += tmp[pos[(i / 2) * 11 + j]] * signs[(i / 2) * 11 + j]; + b0 = (b0 * 2 * 2979LL + (1 << 29)) >> 30; // approximated division by 11 + + c = p->cur_gain * (p->cur_gain * SUBFRAME_LEN >> 5); + if (shift * 2 + 3 >= 0) + c >>= shift * 2 + 3; + else + c <<= -(shift * 2 + 3); + c = (av_clipl_int32(sum << 1) - c) * 2979LL >> 15; + + delta = b0 * b0 * 2 - c; + if (delta <= 0) { + x = -b0; + } else { + delta = square_root(delta); + x = delta - b0; + t = delta + b0; + if (FFABS(t) < FFABS(x)) + x = -t; + } + shift++; + if (shift < 0) + x >>= -shift; + else + x <<= shift; + x = av_clip(x, -10000, 10000); + + for (j = 0; j < 11; j++) { + idx = (i / 2) * 11 + j; + vector_ptr[pos[idx]] = av_clip_int16(vector_ptr[pos[idx]] + + (x * signs[idx] >> 15)); + } + + /* copy decoded data to serve as a history for the next decoded subframes */ + memcpy(vector_ptr + PITCH_MAX, vector_ptr, + sizeof(*vector_ptr) * SUBFRAME_LEN * 2); + vector_ptr += SUBFRAME_LEN * 2; + } + /* Save the excitation for the next frame */ + memcpy(p->prev_excitation, p->audio + LPC_ORDER + FRAME_LEN, + PITCH_MAX * sizeof(*p->excitation)); +} + +static int g723_1_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + G723_1_Context *p = avctx->priv_data; + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int dec_mode = buf[0] & 3; + + PPFParam ppf[SUBFRAMES]; + int16_t cur_lsp[LPC_ORDER]; + int16_t lpc[SUBFRAMES * LPC_ORDER]; + int16_t acb_vector[SUBFRAME_LEN]; + int16_t *out; + int bad_frame = 0, i, j, ret; + int16_t *audio = p->audio; + + if (buf_size < frame_size[dec_mode]) { + if (buf_size) + av_log(avctx, AV_LOG_WARNING, + "Expected %d bytes, got %d - skipping packet\n", + frame_size[dec_mode], buf_size); + *got_frame_ptr = 0; + return buf_size; + } + + if (unpack_bitstream(p, buf, buf_size) < 0) { + bad_frame = 1; + if (p->past_frame_type == ACTIVE_FRAME) + p->cur_frame_type = ACTIVE_FRAME; + else + p->cur_frame_type = UNTRANSMITTED_FRAME; + } + + frame->nb_samples = FRAME_LEN; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + out = (int16_t *)frame->data[0]; + + if (p->cur_frame_type == ACTIVE_FRAME) { + if (!bad_frame) + p->erased_frames = 0; + else if (p->erased_frames != 3) + p->erased_frames++; + + inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, bad_frame); + lsp_interpolate(lpc, cur_lsp, p->prev_lsp); + + /* Save the lsp_vector for the next frame */ + memcpy(p->prev_lsp, cur_lsp, LPC_ORDER * sizeof(*p->prev_lsp)); + + /* Generate the excitation for the frame */ + memcpy(p->excitation, p->prev_excitation, + PITCH_MAX * sizeof(*p->excitation)); + if (!p->erased_frames) { + int16_t *vector_ptr = p->excitation + PITCH_MAX; + + /* Update interpolation gain memory */ + p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index + + p->subframe[3].amp_index) >> 1]; + for (i = 0; i < SUBFRAMES; i++) { + gen_fcb_excitation(vector_ptr, &p->subframe[i], p->cur_rate, + p->pitch_lag[i >> 1], i); + gen_acb_excitation(acb_vector, &p->excitation[SUBFRAME_LEN * i], + p->pitch_lag[i >> 1], &p->subframe[i], + p->cur_rate); + /* Get the total excitation */ + for (j = 0; j < SUBFRAME_LEN; j++) { + int v = av_clip_int16(vector_ptr[j] << 1); + vector_ptr[j] = av_clip_int16(v + acb_vector[j]); + } + vector_ptr += SUBFRAME_LEN; + } + + vector_ptr = p->excitation + PITCH_MAX; + + p->interp_index = comp_interp_index(p, p->pitch_lag[1], + &p->sid_gain, &p->cur_gain); + + /* Peform pitch postfiltering */ + if (p->postfilter) { + i = PITCH_MAX; + for (j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + comp_ppf_coeff(p, i, p->pitch_lag[j >> 1], + ppf + j, p->cur_rate); + + for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + ff_acelp_weighted_vector_sum(p->audio + LPC_ORDER + i, + vector_ptr + i, + vector_ptr + i + ppf[j].index, + ppf[j].sc_gain, + ppf[j].opt_gain, + 1 << 14, 15, SUBFRAME_LEN); + } else { + audio = vector_ptr - LPC_ORDER; + } + + /* Save the excitation for the next frame */ + memcpy(p->prev_excitation, p->excitation + FRAME_LEN, + PITCH_MAX * sizeof(*p->excitation)); + } else { + p->interp_gain = (p->interp_gain * 3 + 2) >> 2; + if (p->erased_frames == 3) { + /* Mute output */ + memset(p->excitation, 0, + (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation)); + memset(p->prev_excitation, 0, + PITCH_MAX * sizeof(*p->excitation)); + memset(frame->data[0], 0, + (FRAME_LEN + LPC_ORDER) * sizeof(int16_t)); + } else { + int16_t *buf = p->audio + LPC_ORDER; + + /* Regenerate frame */ + residual_interp(p->excitation, buf, p->interp_index, + p->interp_gain, &p->random_seed); + + /* Save the excitation for the next frame */ + memcpy(p->prev_excitation, buf + (FRAME_LEN - PITCH_MAX), + PITCH_MAX * sizeof(*p->excitation)); + } + } + p->cng_random_seed = CNG_RANDOM_SEED; + } else { + if (p->cur_frame_type == SID_FRAME) { + p->sid_gain = sid_gain_to_lsp_index(p->subframe[0].amp_index); + inverse_quant(p->sid_lsp, p->prev_lsp, p->lsp_index, 0); + } else if (p->past_frame_type == ACTIVE_FRAME) { + p->sid_gain = estimate_sid_gain(p); + } + + if (p->past_frame_type == ACTIVE_FRAME) + p->cur_gain = p->sid_gain; + else + p->cur_gain = (p->cur_gain * 7 + p->sid_gain) >> 3; + generate_noise(p); + lsp_interpolate(lpc, p->sid_lsp, p->prev_lsp); + /* Save the lsp_vector for the next frame */ + memcpy(p->prev_lsp, p->sid_lsp, LPC_ORDER * sizeof(*p->prev_lsp)); + } + + p->past_frame_type = p->cur_frame_type; + + memcpy(p->audio, p->synth_mem, LPC_ORDER * sizeof(*p->audio)); + for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + ff_celp_lp_synthesis_filter(p->audio + i, &lpc[j * LPC_ORDER], + audio + i, SUBFRAME_LEN, LPC_ORDER, + 0, 1, 1 << 12); + memcpy(p->synth_mem, p->audio + FRAME_LEN, LPC_ORDER * sizeof(*p->audio)); + + if (p->postfilter) { + formant_postfilter(p, lpc, p->audio, out); + } else { // if output is not postfiltered it should be scaled by 2 + for (i = 0; i < FRAME_LEN; i++) + out[i] = av_clip_int16(p->audio[LPC_ORDER + i] << 1); + } + + *got_frame_ptr = 1; + + return frame_size[dec_mode]; +} + +#define OFFSET(x) offsetof(G723_1_Context, x) +#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM + +static const AVOption options[] = { + { "postfilter", "postfilter on/off", OFFSET(postfilter), AV_OPT_TYPE_INT, + { .i64 = 1 }, 0, 1, AD }, + { NULL } +}; + + +static const AVClass g723_1dec_class = { + .class_name = "G.723.1 decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_g723_1_decoder = { + .name = "g723_1", + .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_G723_1, + .priv_data_size = sizeof(G723_1_Context), + .init = g723_1_decode_init, + .decode = g723_1_decode_frame, + .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, + .priv_class = &g723_1dec_class, +}; + +#if CONFIG_G723_1_ENCODER +#define BITSTREAM_WRITER_LE +#include "put_bits.h" + +static av_cold int g723_1_encode_init(AVCodecContext *avctx) +{ + G723_1_Context *p = avctx->priv_data; + + if (avctx->sample_rate != 8000) { + av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); + return -1; + } + + if (avctx->channels != 1) { + av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); + return AVERROR(EINVAL); + } + + if (avctx->bit_rate == 6300) { + p->cur_rate = RATE_6300; + } else if (avctx->bit_rate == 5300) { + av_log(avctx, AV_LOG_ERROR, "Bitrate not supported yet, use 6.3k\n"); + return AVERROR_PATCHWELCOME; + } else { + av_log(avctx, AV_LOG_ERROR, + "Bitrate not supported, use 6.3k\n"); + return AVERROR(EINVAL); + } + avctx->frame_size = 240; + memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(int16_t)); + + return 0; +} + +/** + * Remove DC component from the input signal. + * + * @param buf input signal + * @param fir zero memory + * @param iir pole memory + */ +static void highpass_filter(int16_t *buf, int16_t *fir, int *iir) +{ + int i; + for (i = 0; i < FRAME_LEN; i++) { + *iir = (buf[i] << 15) + ((-*fir) << 15) + MULL2(*iir, 0x7f00); + *fir = buf[i]; + buf[i] = av_clipl_int32((int64_t)*iir + (1 << 15)) >> 16; + } +} + +/** + * Estimate autocorrelation of the input vector. + * + * @param buf input buffer + * @param autocorr autocorrelation coefficients vector + */ +static void comp_autocorr(int16_t *buf, int16_t *autocorr) +{ + int i, scale, temp; + int16_t vector[LPC_FRAME]; + + scale_vector(vector, buf, LPC_FRAME); + + /* Apply the Hamming window */ + for (i = 0; i < LPC_FRAME; i++) + vector[i] = (vector[i] * hamming_window[i] + (1 << 14)) >> 15; + + /* Compute the first autocorrelation coefficient */ + temp = ff_dot_product(vector, vector, LPC_FRAME); + + /* Apply a white noise correlation factor of (1025/1024) */ + temp += temp >> 10; + + /* Normalize */ + scale = normalize_bits_int32(temp); + autocorr[0] = av_clipl_int32((int64_t)(temp << scale) + + (1 << 15)) >> 16; + + /* Compute the remaining coefficients */ + if (!autocorr[0]) { + memset(autocorr + 1, 0, LPC_ORDER * sizeof(int16_t)); + } else { + for (i = 1; i <= LPC_ORDER; i++) { + temp = ff_dot_product(vector, vector + i, LPC_FRAME - i); + temp = MULL2((temp << scale), binomial_window[i - 1]); + autocorr[i] = av_clipl_int32((int64_t)temp + (1 << 15)) >> 16; + } + } +} + +/** + * Use Levinson-Durbin recursion to compute LPC coefficients from + * autocorrelation values. + * + * @param lpc LPC coefficients vector + * @param autocorr autocorrelation coefficients vector + * @param error prediction error + */ +static void levinson_durbin(int16_t *lpc, int16_t *autocorr, int16_t error) +{ + int16_t vector[LPC_ORDER]; + int16_t partial_corr; + int i, j, temp; + + memset(lpc, 0, LPC_ORDER * sizeof(int16_t)); + + for (i = 0; i < LPC_ORDER; i++) { + /* Compute the partial correlation coefficient */ + temp = 0; + for (j = 0; j < i; j++) + temp -= lpc[j] * autocorr[i - j - 1]; + temp = ((autocorr[i] << 13) + temp) << 3; + + if (FFABS(temp) >= (error << 16)) + break; + + partial_corr = temp / (error << 1); + + lpc[i] = av_clipl_int32((int64_t)(partial_corr << 14) + + (1 << 15)) >> 16; + + /* Update the prediction error */ + temp = MULL2(temp, partial_corr); + error = av_clipl_int32((int64_t)(error << 16) - temp + + (1 << 15)) >> 16; + + memcpy(vector, lpc, i * sizeof(int16_t)); + for (j = 0; j < i; j++) { + temp = partial_corr * vector[i - j - 1] << 1; + lpc[j] = av_clipl_int32((int64_t)(lpc[j] << 16) - temp + + (1 << 15)) >> 16; + } + } +} + +/** + * Calculate LPC coefficients for the current frame. + * + * @param buf current frame + * @param prev_data 2 trailing subframes of the previous frame + * @param lpc LPC coefficients vector + */ +static void comp_lpc_coeff(int16_t *buf, int16_t *lpc) +{ + int16_t autocorr[(LPC_ORDER + 1) * SUBFRAMES]; + int16_t *autocorr_ptr = autocorr; + int16_t *lpc_ptr = lpc; + int i, j; + + for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) { + comp_autocorr(buf + i, autocorr_ptr); + levinson_durbin(lpc_ptr, autocorr_ptr + 1, autocorr_ptr[0]); + + lpc_ptr += LPC_ORDER; + autocorr_ptr += LPC_ORDER + 1; + } +} + +static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp) +{ + int f[LPC_ORDER + 2]; ///< coefficients of the sum and difference + ///< polynomials (F1, F2) ordered as + ///< f1[0], f2[0], ...., f1[5], f2[5] + + int max, shift, cur_val, prev_val, count, p; + int i, j; + int64_t temp; + + /* Initialize f1[0] and f2[0] to 1 in Q25 */ + for (i = 0; i < LPC_ORDER; i++) + lsp[i] = (lpc[i] * bandwidth_expand[i] + (1 << 14)) >> 15; + + /* Apply bandwidth expansion on the LPC coefficients */ + f[0] = f[1] = 1 << 25; + + /* Compute the remaining coefficients */ + for (i = 0; i < LPC_ORDER / 2; i++) { + /* f1 */ + f[2 * i + 2] = -f[2 * i] - ((lsp[i] + lsp[LPC_ORDER - 1 - i]) << 12); + /* f2 */ + f[2 * i + 3] = f[2 * i + 1] - ((lsp[i] - lsp[LPC_ORDER - 1 - i]) << 12); + } + + /* Divide f1[5] and f2[5] by 2 for use in polynomial evaluation */ + f[LPC_ORDER] >>= 1; + f[LPC_ORDER + 1] >>= 1; + + /* Normalize and shorten */ + max = FFABS(f[0]); + for (i = 1; i < LPC_ORDER + 2; i++) + max = FFMAX(max, FFABS(f[i])); + + shift = normalize_bits_int32(max); + + for (i = 0; i < LPC_ORDER + 2; i++) + f[i] = av_clipl_int32((int64_t)(f[i] << shift) + (1 << 15)) >> 16; + + /** + * Evaluate F1 and F2 at uniform intervals of pi/256 along the + * unit circle and check for zero crossings. + */ + p = 0; + temp = 0; + for (i = 0; i <= LPC_ORDER / 2; i++) + temp += f[2 * i] * cos_tab[0]; + prev_val = av_clipl_int32(temp << 1); + count = 0; + for ( i = 1; i < COS_TBL_SIZE / 2; i++) { + /* Evaluate */ + temp = 0; + for (j = 0; j <= LPC_ORDER / 2; j++) + temp += f[LPC_ORDER - 2 * j + p] * cos_tab[i * j % COS_TBL_SIZE]; + cur_val = av_clipl_int32(temp << 1); + + /* Check for sign change, indicating a zero crossing */ + if ((cur_val ^ prev_val) < 0) { + int abs_cur = FFABS(cur_val); + int abs_prev = FFABS(prev_val); + int sum = abs_cur + abs_prev; + + shift = normalize_bits_int32(sum); + sum <<= shift; + abs_prev = abs_prev << shift >> 8; + lsp[count++] = ((i - 1) << 7) + (abs_prev >> 1) / (sum >> 16); + + if (count == LPC_ORDER) + break; + + /* Switch between sum and difference polynomials */ + p ^= 1; + + /* Evaluate */ + temp = 0; + for (j = 0; j <= LPC_ORDER / 2; j++){ + temp += f[LPC_ORDER - 2 * j + p] * + cos_tab[i * j % COS_TBL_SIZE]; + } + cur_val = av_clipl_int32(temp<<1); + } + prev_val = cur_val; + } + + if (count != LPC_ORDER) + memcpy(lsp, prev_lsp, LPC_ORDER * sizeof(int16_t)); +} + +/** + * Quantize the current LSP subvector. + * + * @param num band number + * @param offset offset of the current subvector in an LPC_ORDER vector + * @param size size of the current subvector + */ +#define get_index(num, offset, size) \ +{\ + int error, max = -1;\ + int16_t temp[4];\ + int i, j;\ + for (i = 0; i < LSP_CB_SIZE; i++) {\ + for (j = 0; j < size; j++){\ + temp[j] = (weight[j + (offset)] * lsp_band##num[i][j] +\ + (1 << 14)) >> 15;\ + }\ + error = dot_product(lsp + (offset), temp, size) << 1;\ + error -= dot_product(lsp_band##num[i], temp, size);\ + if (error > max) {\ + max = error;\ + lsp_index[num] = i;\ + }\ + }\ +} + +/** + * Vector quantize the LSP frequencies. + * + * @param lsp the current lsp vector + * @param prev_lsp the previous lsp vector + */ +static void lsp_quantize(uint8_t *lsp_index, int16_t *lsp, int16_t *prev_lsp) +{ + int16_t weight[LPC_ORDER]; + int16_t min, max; + int shift, i; + + /* Calculate the VQ weighting vector */ + weight[0] = (1 << 20) / (lsp[1] - lsp[0]); + weight[LPC_ORDER - 1] = (1 << 20) / + (lsp[LPC_ORDER - 1] - lsp[LPC_ORDER - 2]); + + for (i = 1; i < LPC_ORDER - 1; i++) { + min = FFMIN(lsp[i] - lsp[i - 1], lsp[i + 1] - lsp[i]); + if (min > 0x20) + weight[i] = (1 << 20) / min; + else + weight[i] = INT16_MAX; + } + + /* Normalize */ + max = 0; + for (i = 0; i < LPC_ORDER; i++) + max = FFMAX(weight[i], max); + + shift = normalize_bits_int16(max); + for (i = 0; i < LPC_ORDER; i++) { + weight[i] <<= shift; + } + + /* Compute the VQ target vector */ + for (i = 0; i < LPC_ORDER; i++) { + lsp[i] -= dc_lsp[i] + + (((prev_lsp[i] - dc_lsp[i]) * 12288 + (1 << 14)) >> 15); + } + + get_index(0, 0, 3); + get_index(1, 3, 3); + get_index(2, 6, 4); +} + +/** + * Apply the formant perceptual weighting filter. + * + * @param flt_coef filter coefficients + * @param unq_lpc unquantized lpc vector + */ +static void perceptual_filter(G723_1_Context *p, int16_t *flt_coef, + int16_t *unq_lpc, int16_t *buf) +{ + int16_t vector[FRAME_LEN + LPC_ORDER]; + int i, j, k, l = 0; + + memcpy(buf, p->iir_mem, sizeof(int16_t) * LPC_ORDER); + memcpy(vector, p->fir_mem, sizeof(int16_t) * LPC_ORDER); + memcpy(vector + LPC_ORDER, buf + LPC_ORDER, sizeof(int16_t) * FRAME_LEN); + + for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) { + for (k = 0; k < LPC_ORDER; k++) { + flt_coef[k + 2 * l] = (unq_lpc[k + l] * percept_flt_tbl[0][k] + + (1 << 14)) >> 15; + flt_coef[k + 2 * l + LPC_ORDER] = (unq_lpc[k + l] * + percept_flt_tbl[1][k] + + (1 << 14)) >> 15; + } + iir_filter(flt_coef + 2 * l, flt_coef + 2 * l + LPC_ORDER, vector + i, + buf + i, 0); + l += LPC_ORDER; + } + memcpy(p->iir_mem, buf + FRAME_LEN, sizeof(int16_t) * LPC_ORDER); + memcpy(p->fir_mem, vector + FRAME_LEN, sizeof(int16_t) * LPC_ORDER); +} + +/** + * Estimate the open loop pitch period. + * + * @param buf perceptually weighted speech + * @param start estimation is carried out from this position + */ +static int estimate_pitch(int16_t *buf, int start) +{ + int max_exp = 32; + int max_ccr = 0x4000; + int max_eng = 0x7fff; + int index = PITCH_MIN; + int offset = start - PITCH_MIN + 1; + + int ccr, eng, orig_eng, ccr_eng, exp; + int diff, temp; + + int i; + + orig_eng = ff_dot_product(buf + offset, buf + offset, HALF_FRAME_LEN); + + for (i = PITCH_MIN; i <= PITCH_MAX - 3; i++) { + offset--; + + /* Update energy and compute correlation */ + orig_eng += buf[offset] * buf[offset] - + buf[offset + HALF_FRAME_LEN] * buf[offset + HALF_FRAME_LEN]; + ccr = ff_dot_product(buf + start, buf + offset, HALF_FRAME_LEN); + if (ccr <= 0) + continue; + + /* Split into mantissa and exponent to maintain precision */ + exp = normalize_bits_int32(ccr); + ccr = av_clipl_int32((int64_t)(ccr << exp) + (1 << 15)) >> 16; + exp <<= 1; + ccr *= ccr; + temp = normalize_bits_int32(ccr); + ccr = ccr << temp >> 16; + exp += temp; + + temp = normalize_bits_int32(orig_eng); + eng = av_clipl_int32((int64_t)(orig_eng << temp) + (1 << 15)) >> 16; + exp -= temp; + + if (ccr >= eng) { + exp--; + ccr >>= 1; + } + if (exp > max_exp) + continue; + + if (exp + 1 < max_exp) + goto update; + + /* Equalize exponents before comparison */ + if (exp + 1 == max_exp) + temp = max_ccr >> 1; + else + temp = max_ccr; + ccr_eng = ccr * max_eng; + diff = ccr_eng - eng * temp; + if (diff > 0 && (i - index < PITCH_MIN || diff > ccr_eng >> 2)) { +update: + index = i; + max_exp = exp; + max_ccr = ccr; + max_eng = eng; + } + } + return index; +} + +/** + * Compute harmonic noise filter parameters. + * + * @param buf perceptually weighted speech + * @param pitch_lag open loop pitch period + * @param hf harmonic filter parameters + */ +static void comp_harmonic_coeff(int16_t *buf, int16_t pitch_lag, HFParam *hf) +{ + int ccr, eng, max_ccr, max_eng; + int exp, max, diff; + int energy[15]; + int i, j; + + for (i = 0, j = pitch_lag - 3; j <= pitch_lag + 3; i++, j++) { + /* Compute residual energy */ + energy[i << 1] = ff_dot_product(buf - j, buf - j, SUBFRAME_LEN); + /* Compute correlation */ + energy[(i << 1) + 1] = ff_dot_product(buf, buf - j, SUBFRAME_LEN); + } + + /* Compute target energy */ + energy[14] = ff_dot_product(buf, buf, SUBFRAME_LEN); + + /* Normalize */ + max = 0; + for (i = 0; i < 15; i++) + max = FFMAX(max, FFABS(energy[i])); + + exp = normalize_bits_int32(max); + for (i = 0; i < 15; i++) { + energy[i] = av_clipl_int32((int64_t)(energy[i] << exp) + + (1 << 15)) >> 16; + } + + hf->index = -1; + hf->gain = 0; + max_ccr = 1; + max_eng = 0x7fff; + + for (i = 0; i <= 6; i++) { + eng = energy[i << 1]; + ccr = energy[(i << 1) + 1]; + + if (ccr <= 0) + continue; + + ccr = (ccr * ccr + (1 << 14)) >> 15; + diff = ccr * max_eng - eng * max_ccr; + if (diff > 0) { + max_ccr = ccr; + max_eng = eng; + hf->index = i; + } + } + + if (hf->index == -1) { + hf->index = pitch_lag; + return; + } + + eng = energy[14] * max_eng; + eng = (eng >> 2) + (eng >> 3); + ccr = energy[(hf->index << 1) + 1] * energy[(hf->index << 1) + 1]; + if (eng < ccr) { + eng = energy[(hf->index << 1) + 1]; + + if (eng >= max_eng) + hf->gain = 0x2800; + else + hf->gain = ((eng << 15) / max_eng * 0x2800 + (1 << 14)) >> 15; + } + hf->index += pitch_lag - 3; +} + +/** + * Apply the harmonic noise shaping filter. + * + * @param hf filter parameters + */ +static void harmonic_filter(HFParam *hf, const int16_t *src, int16_t *dest) +{ + int i; + + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = hf->gain * src[i - hf->index] << 1; + dest[i] = av_clipl_int32((src[i] << 16) - temp + (1 << 15)) >> 16; + } +} + +static void harmonic_noise_sub(HFParam *hf, const int16_t *src, int16_t *dest) +{ + int i; + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = hf->gain * src[i - hf->index] << 1; + dest[i] = av_clipl_int32(((dest[i] - src[i]) << 16) + temp + + (1 << 15)) >> 16; + + } +} + +/** + * Combined synthesis and formant perceptual weighting filer. + * + * @param qnt_lpc quantized lpc coefficients + * @param perf_lpc perceptual filter coefficients + * @param perf_fir perceptual filter fir memory + * @param perf_iir perceptual filter iir memory + * @param scale the filter output will be scaled by 2^scale + */ +static void synth_percept_filter(int16_t *qnt_lpc, int16_t *perf_lpc, + int16_t *perf_fir, int16_t *perf_iir, + const int16_t *src, int16_t *dest, int scale) +{ + int i, j; + int16_t buf_16[SUBFRAME_LEN + LPC_ORDER]; + int64_t buf[SUBFRAME_LEN]; + + int16_t *bptr_16 = buf_16 + LPC_ORDER; + + memcpy(buf_16, perf_fir, sizeof(int16_t) * LPC_ORDER); + memcpy(dest - LPC_ORDER, perf_iir, sizeof(int16_t) * LPC_ORDER); + + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = 0; + for (j = 1; j <= LPC_ORDER; j++) + temp -= qnt_lpc[j - 1] * bptr_16[i - j]; + + buf[i] = (src[i] << 15) + (temp << 3); + bptr_16[i] = av_clipl_int32(buf[i] + (1 << 15)) >> 16; + } + + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t fir = 0, iir = 0; + for (j = 1; j <= LPC_ORDER; j++) { + fir -= perf_lpc[j - 1] * bptr_16[i - j]; + iir += perf_lpc[j + LPC_ORDER - 1] * dest[i - j]; + } + dest[i] = av_clipl_int32(((buf[i] + (fir << 3)) << scale) + (iir << 3) + + (1 << 15)) >> 16; + } + memcpy(perf_fir, buf_16 + SUBFRAME_LEN, sizeof(int16_t) * LPC_ORDER); + memcpy(perf_iir, dest + SUBFRAME_LEN - LPC_ORDER, + sizeof(int16_t) * LPC_ORDER); +} + +/** + * Compute the adaptive codebook contribution. + * + * @param buf input signal + * @param index the current subframe index + */ +static void acb_search(G723_1_Context *p, int16_t *residual, + int16_t *impulse_resp, const int16_t *buf, + int index) +{ + + int16_t flt_buf[PITCH_ORDER][SUBFRAME_LEN]; + + const int16_t *cb_tbl = adaptive_cb_gain85; + + int ccr_buf[PITCH_ORDER * SUBFRAMES << 2]; + + int pitch_lag = p->pitch_lag[index >> 1]; + int acb_lag = 1; + int acb_gain = 0; + int odd_frame = index & 1; + int iter = 3 + odd_frame; + int count = 0; + int tbl_size = 85; + + int i, j, k, l, max; + int64_t temp; + + if (!odd_frame) { + if (pitch_lag == PITCH_MIN) + pitch_lag++; + else + pitch_lag = FFMIN(pitch_lag, PITCH_MAX - 5); + } + + for (i = 0; i < iter; i++) { + get_residual(residual, p->prev_excitation, pitch_lag + i - 1); + + for (j = 0; j < SUBFRAME_LEN; j++) { + temp = 0; + for (k = 0; k <= j; k++) + temp += residual[PITCH_ORDER - 1 + k] * impulse_resp[j - k]; + flt_buf[PITCH_ORDER - 1][j] = av_clipl_int32((temp << 1) + + (1 << 15)) >> 16; + } + + for (j = PITCH_ORDER - 2; j >= 0; j--) { + flt_buf[j][0] = ((residual[j] << 13) + (1 << 14)) >> 15; + for (k = 1; k < SUBFRAME_LEN; k++) { + temp = (flt_buf[j + 1][k - 1] << 15) + + residual[j] * impulse_resp[k]; + flt_buf[j][k] = av_clipl_int32((temp << 1) + (1 << 15)) >> 16; + } + } + + /* Compute crosscorrelation with the signal */ + for (j = 0; j < PITCH_ORDER; j++) { + temp = ff_dot_product(buf, flt_buf[j], SUBFRAME_LEN); + ccr_buf[count++] = av_clipl_int32(temp << 1); + } + + /* Compute energies */ + for (j = 0; j < PITCH_ORDER; j++) { + ccr_buf[count++] = dot_product(flt_buf[j], flt_buf[j], + SUBFRAME_LEN); + } + + for (j = 1; j < PITCH_ORDER; j++) { + for (k = 0; k < j; k++) { + temp = ff_dot_product(flt_buf[j], flt_buf[k], SUBFRAME_LEN); + ccr_buf[count++] = av_clipl_int32(temp<<2); + } + } + } + + /* Normalize and shorten */ + max = 0; + for (i = 0; i < 20 * iter; i++) + max = FFMAX(max, FFABS(ccr_buf[i])); + + temp = normalize_bits_int32(max); + + for (i = 0; i < 20 * iter; i++){ + ccr_buf[i] = av_clipl_int32((int64_t)(ccr_buf[i] << temp) + + (1 << 15)) >> 16; + } + + max = 0; + for (i = 0; i < iter; i++) { + /* Select quantization table */ + if (!odd_frame && pitch_lag + i - 1 >= SUBFRAME_LEN - 2 || + odd_frame && pitch_lag >= SUBFRAME_LEN - 2) { + cb_tbl = adaptive_cb_gain170; + tbl_size = 170; + } + + for (j = 0, k = 0; j < tbl_size; j++, k += 20) { + temp = 0; + for (l = 0; l < 20; l++) + temp += ccr_buf[20 * i + l] * cb_tbl[k + l]; + temp = av_clipl_int32(temp); + + if (temp > max) { + max = temp; + acb_gain = j; + acb_lag = i; + } + } + } + + if (!odd_frame) { + pitch_lag += acb_lag - 1; + acb_lag = 1; + } + + p->pitch_lag[index >> 1] = pitch_lag; + p->subframe[index].ad_cb_lag = acb_lag; + p->subframe[index].ad_cb_gain = acb_gain; +} + +/** + * Subtract the adaptive codebook contribution from the input + * to obtain the residual. + * + * @param buf target vector + */ +static void sub_acb_contrib(const int16_t *residual, const int16_t *impulse_resp, + int16_t *buf) +{ + int i, j; + /* Subtract adaptive CB contribution to obtain the residual */ + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = buf[i] << 14; + for (j = 0; j <= i; j++) + temp -= residual[j] * impulse_resp[i - j]; + + buf[i] = av_clipl_int32((temp << 2) + (1 << 15)) >> 16; + } +} + +/** + * Quantize the residual signal using the fixed codebook (MP-MLQ). + * + * @param optim optimized fixed codebook parameters + * @param buf excitation vector + */ +static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp, + int16_t *buf, int pulse_cnt, int pitch_lag) +{ + FCBParam param; + int16_t impulse_r[SUBFRAME_LEN]; + int16_t temp_corr[SUBFRAME_LEN]; + int16_t impulse_corr[SUBFRAME_LEN]; + + int ccr1[SUBFRAME_LEN]; + int ccr2[SUBFRAME_LEN]; + int amp, err, max, max_amp_index, min, scale, i, j, k, l; + + int64_t temp; + + /* Update impulse response */ + memcpy(impulse_r, impulse_resp, sizeof(int16_t) * SUBFRAME_LEN); + param.dirac_train = 0; + if (pitch_lag < SUBFRAME_LEN - 2) { + param.dirac_train = 1; + gen_dirac_train(impulse_r, pitch_lag); + } + + for (i = 0; i < SUBFRAME_LEN; i++) + temp_corr[i] = impulse_r[i] >> 1; + + /* Compute impulse response autocorrelation */ + temp = dot_product(temp_corr, temp_corr, SUBFRAME_LEN); + + scale = normalize_bits_int32(temp); + impulse_corr[0] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16; + + for (i = 1; i < SUBFRAME_LEN; i++) { + temp = dot_product(temp_corr + i, temp_corr, SUBFRAME_LEN - i); + impulse_corr[i] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16; + } + + /* Compute crosscorrelation of impulse response with residual signal */ + scale -= 4; + for (i = 0; i < SUBFRAME_LEN; i++){ + temp = dot_product(buf + i, impulse_r, SUBFRAME_LEN - i); + if (scale < 0) + ccr1[i] = temp >> -scale; + else + ccr1[i] = av_clipl_int32(temp << scale); + } + + /* Search loop */ + for (i = 0; i < GRID_SIZE; i++) { + /* Maximize the crosscorrelation */ + max = 0; + for (j = i; j < SUBFRAME_LEN; j += GRID_SIZE) { + temp = FFABS(ccr1[j]); + if (temp >= max) { + max = temp; + param.pulse_pos[0] = j; + } + } + + /* Quantize the gain (max crosscorrelation/impulse_corr[0]) */ + amp = max; + min = 1 << 30; + max_amp_index = GAIN_LEVELS - 2; + for (j = max_amp_index; j >= 2; j--) { + temp = av_clipl_int32((int64_t)fixed_cb_gain[j] * + impulse_corr[0] << 1); + temp = FFABS(temp - amp); + if (temp < min) { + min = temp; + max_amp_index = j; + } + } + + max_amp_index--; + /* Select additional gain values */ + for (j = 1; j < 5; j++) { + for (k = i; k < SUBFRAME_LEN; k += GRID_SIZE) { + temp_corr[k] = 0; + ccr2[k] = ccr1[k]; + } + param.amp_index = max_amp_index + j - 2; + amp = fixed_cb_gain[param.amp_index]; + + param.pulse_sign[0] = (ccr2[param.pulse_pos[0]] < 0) ? -amp : amp; + temp_corr[param.pulse_pos[0]] = 1; + + for (k = 1; k < pulse_cnt; k++) { + max = -1 << 30; + for (l = i; l < SUBFRAME_LEN; l += GRID_SIZE) { + if (temp_corr[l]) + continue; + temp = impulse_corr[FFABS(l - param.pulse_pos[k - 1])]; + temp = av_clipl_int32((int64_t)temp * + param.pulse_sign[k - 1] << 1); + ccr2[l] -= temp; + temp = FFABS(ccr2[l]); + if (temp > max) { + max = temp; + param.pulse_pos[k] = l; + } + } + + param.pulse_sign[k] = (ccr2[param.pulse_pos[k]] < 0) ? + -amp : amp; + temp_corr[param.pulse_pos[k]] = 1; + } + + /* Create the error vector */ + memset(temp_corr, 0, sizeof(int16_t) * SUBFRAME_LEN); + + for (k = 0; k < pulse_cnt; k++) + temp_corr[param.pulse_pos[k]] = param.pulse_sign[k]; + + for (k = SUBFRAME_LEN - 1; k >= 0; k--) { + temp = 0; + for (l = 0; l <= k; l++) { + int prod = av_clipl_int32((int64_t)temp_corr[l] * + impulse_r[k - l] << 1); + temp = av_clipl_int32(temp + prod); + } + temp_corr[k] = temp << 2 >> 16; + } + + /* Compute square of error */ + err = 0; + for (k = 0; k < SUBFRAME_LEN; k++) { + int64_t prod; + prod = av_clipl_int32((int64_t)buf[k] * temp_corr[k] << 1); + err = av_clipl_int32(err - prod); + prod = av_clipl_int32((int64_t)temp_corr[k] * temp_corr[k]); + err = av_clipl_int32(err + prod); + } + + /* Minimize */ + if (err < optim->min_err) { + optim->min_err = err; + optim->grid_index = i; + optim->amp_index = param.amp_index; + optim->dirac_train = param.dirac_train; + + for (k = 0; k < pulse_cnt; k++) { + optim->pulse_sign[k] = param.pulse_sign[k]; + optim->pulse_pos[k] = param.pulse_pos[k]; + } + } + } + } +} + +/** + * Encode the pulse position and gain of the current subframe. + * + * @param optim optimized fixed CB parameters + * @param buf excitation vector + */ +static void pack_fcb_param(G723_1_Subframe *subfrm, FCBParam *optim, + int16_t *buf, int pulse_cnt) +{ + int i, j; + + j = PULSE_MAX - pulse_cnt; + + subfrm->pulse_sign = 0; + subfrm->pulse_pos = 0; + + for (i = 0; i < SUBFRAME_LEN >> 1; i++) { + int val = buf[optim->grid_index + (i << 1)]; + if (!val) { + subfrm->pulse_pos += combinatorial_table[j][i]; + } else { + subfrm->pulse_sign <<= 1; + if (val < 0) subfrm->pulse_sign++; + j++; + + if (j == PULSE_MAX) break; + } + } + subfrm->amp_index = optim->amp_index; + subfrm->grid_index = optim->grid_index; + subfrm->dirac_train = optim->dirac_train; +} + +/** + * Compute the fixed codebook excitation. + * + * @param buf target vector + * @param impulse_resp impulse response of the combined filter + */ +static void fcb_search(G723_1_Context *p, int16_t *impulse_resp, + int16_t *buf, int index) +{ + FCBParam optim; + int pulse_cnt = pulses[index]; + int i; + + optim.min_err = 1 << 30; + get_fcb_param(&optim, impulse_resp, buf, pulse_cnt, SUBFRAME_LEN); + + if (p->pitch_lag[index >> 1] < SUBFRAME_LEN - 2) { + get_fcb_param(&optim, impulse_resp, buf, pulse_cnt, + p->pitch_lag[index >> 1]); + } + + /* Reconstruct the excitation */ + memset(buf, 0, sizeof(int16_t) * SUBFRAME_LEN); + for (i = 0; i < pulse_cnt; i++) + buf[optim.pulse_pos[i]] = optim.pulse_sign[i]; + + pack_fcb_param(&p->subframe[index], &optim, buf, pulse_cnt); + + if (optim.dirac_train) + gen_dirac_train(buf, p->pitch_lag[index >> 1]); +} + +/** + * Pack the frame parameters into output bitstream. + * + * @param frame output buffer + * @param size size of the buffer + */ +static int pack_bitstream(G723_1_Context *p, unsigned char *frame, int size) +{ + PutBitContext pb; + int info_bits, i, temp; + + init_put_bits(&pb, frame, size); + + if (p->cur_rate == RATE_6300) { + info_bits = 0; + put_bits(&pb, 2, info_bits); + } + + put_bits(&pb, 8, p->lsp_index[2]); + put_bits(&pb, 8, p->lsp_index[1]); + put_bits(&pb, 8, p->lsp_index[0]); + + put_bits(&pb, 7, p->pitch_lag[0] - PITCH_MIN); + put_bits(&pb, 2, p->subframe[1].ad_cb_lag); + put_bits(&pb, 7, p->pitch_lag[1] - PITCH_MIN); + put_bits(&pb, 2, p->subframe[3].ad_cb_lag); + + /* Write 12 bit combined gain */ + for (i = 0; i < SUBFRAMES; i++) { + temp = p->subframe[i].ad_cb_gain * GAIN_LEVELS + + p->subframe[i].amp_index; + if (p->cur_rate == RATE_6300) + temp += p->subframe[i].dirac_train << 11; + put_bits(&pb, 12, temp); + } + + put_bits(&pb, 1, p->subframe[0].grid_index); + put_bits(&pb, 1, p->subframe[1].grid_index); + put_bits(&pb, 1, p->subframe[2].grid_index); + put_bits(&pb, 1, p->subframe[3].grid_index); + + if (p->cur_rate == RATE_6300) { + skip_put_bits(&pb, 1); /* reserved bit */ + + /* Write 13 bit combined position index */ + temp = (p->subframe[0].pulse_pos >> 16) * 810 + + (p->subframe[1].pulse_pos >> 14) * 90 + + (p->subframe[2].pulse_pos >> 16) * 9 + + (p->subframe[3].pulse_pos >> 14); + put_bits(&pb, 13, temp); + + put_bits(&pb, 16, p->subframe[0].pulse_pos & 0xffff); + put_bits(&pb, 14, p->subframe[1].pulse_pos & 0x3fff); + put_bits(&pb, 16, p->subframe[2].pulse_pos & 0xffff); + put_bits(&pb, 14, p->subframe[3].pulse_pos & 0x3fff); + + put_bits(&pb, 6, p->subframe[0].pulse_sign); + put_bits(&pb, 5, p->subframe[1].pulse_sign); + put_bits(&pb, 6, p->subframe[2].pulse_sign); + put_bits(&pb, 5, p->subframe[3].pulse_sign); + } + + flush_put_bits(&pb); + return frame_size[info_bits]; +} + +static int g723_1_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + G723_1_Context *p = avctx->priv_data; + int16_t unq_lpc[LPC_ORDER * SUBFRAMES]; + int16_t qnt_lpc[LPC_ORDER * SUBFRAMES]; + int16_t cur_lsp[LPC_ORDER]; + int16_t weighted_lpc[LPC_ORDER * SUBFRAMES << 1]; + int16_t vector[FRAME_LEN + PITCH_MAX]; + int offset, ret; + int16_t *in = (const int16_t *)frame->data[0]; + + HFParam hf[4]; + int i, j; + + highpass_filter(in, &p->hpf_fir_mem, &p->hpf_iir_mem); + + memcpy(vector, p->prev_data, HALF_FRAME_LEN * sizeof(int16_t)); + memcpy(vector + HALF_FRAME_LEN, in, FRAME_LEN * sizeof(int16_t)); + + comp_lpc_coeff(vector, unq_lpc); + lpc2lsp(&unq_lpc[LPC_ORDER * 3], p->prev_lsp, cur_lsp); + lsp_quantize(p->lsp_index, cur_lsp, p->prev_lsp); + + /* Update memory */ + memcpy(vector + LPC_ORDER, p->prev_data + SUBFRAME_LEN, + sizeof(int16_t) * SUBFRAME_LEN); + memcpy(vector + LPC_ORDER + SUBFRAME_LEN, in, + sizeof(int16_t) * (HALF_FRAME_LEN + SUBFRAME_LEN)); + memcpy(p->prev_data, in + HALF_FRAME_LEN, + sizeof(int16_t) * HALF_FRAME_LEN); + memcpy(in, vector + LPC_ORDER, sizeof(int16_t) * FRAME_LEN); + + perceptual_filter(p, weighted_lpc, unq_lpc, vector); + + memcpy(in, vector + LPC_ORDER, sizeof(int16_t) * FRAME_LEN); + memcpy(vector, p->prev_weight_sig, sizeof(int16_t) * PITCH_MAX); + memcpy(vector + PITCH_MAX, in, sizeof(int16_t) * FRAME_LEN); + + scale_vector(vector, vector, FRAME_LEN + PITCH_MAX); + + p->pitch_lag[0] = estimate_pitch(vector, PITCH_MAX); + p->pitch_lag[1] = estimate_pitch(vector, PITCH_MAX + HALF_FRAME_LEN); + + for (i = PITCH_MAX, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + comp_harmonic_coeff(vector + i, p->pitch_lag[j >> 1], hf + j); + + memcpy(vector, p->prev_weight_sig, sizeof(int16_t) * PITCH_MAX); + memcpy(vector + PITCH_MAX, in, sizeof(int16_t) * FRAME_LEN); + memcpy(p->prev_weight_sig, vector + FRAME_LEN, sizeof(int16_t) * PITCH_MAX); + + for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + harmonic_filter(hf + j, vector + PITCH_MAX + i, in + i); + + inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, 0); + lsp_interpolate(qnt_lpc, cur_lsp, p->prev_lsp); + + memcpy(p->prev_lsp, cur_lsp, sizeof(int16_t) * LPC_ORDER); + + offset = 0; + for (i = 0; i < SUBFRAMES; i++) { + int16_t impulse_resp[SUBFRAME_LEN]; + int16_t residual[SUBFRAME_LEN + PITCH_ORDER - 1]; + int16_t flt_in[SUBFRAME_LEN]; + int16_t zero[LPC_ORDER], fir[LPC_ORDER], iir[LPC_ORDER]; + + /** + * Compute the combined impulse response of the synthesis filter, + * formant perceptual weighting filter and harmonic noise shaping filter + */ + memset(zero, 0, sizeof(int16_t) * LPC_ORDER); + memset(vector, 0, sizeof(int16_t) * PITCH_MAX); + memset(flt_in, 0, sizeof(int16_t) * SUBFRAME_LEN); + + flt_in[0] = 1 << 13; /* Unit impulse */ + synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1), + zero, zero, flt_in, vector + PITCH_MAX, 1); + harmonic_filter(hf + i, vector + PITCH_MAX, impulse_resp); + + /* Compute the combined zero input response */ + flt_in[0] = 0; + memcpy(fir, p->perf_fir_mem, sizeof(int16_t) * LPC_ORDER); + memcpy(iir, p->perf_iir_mem, sizeof(int16_t) * LPC_ORDER); + + synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1), + fir, iir, flt_in, vector + PITCH_MAX, 0); + memcpy(vector, p->harmonic_mem, sizeof(int16_t) * PITCH_MAX); + harmonic_noise_sub(hf + i, vector + PITCH_MAX, in); + + acb_search(p, residual, impulse_resp, in, i); + gen_acb_excitation(residual, p->prev_excitation,p->pitch_lag[i >> 1], + &p->subframe[i], p->cur_rate); + sub_acb_contrib(residual, impulse_resp, in); + + fcb_search(p, impulse_resp, in, i); + + /* Reconstruct the excitation */ + gen_acb_excitation(impulse_resp, p->prev_excitation, p->pitch_lag[i >> 1], + &p->subframe[i], RATE_6300); + + memmove(p->prev_excitation, p->prev_excitation + SUBFRAME_LEN, + sizeof(int16_t) * (PITCH_MAX - SUBFRAME_LEN)); + for (j = 0; j < SUBFRAME_LEN; j++) + in[j] = av_clip_int16((in[j] << 1) + impulse_resp[j]); + memcpy(p->prev_excitation + PITCH_MAX - SUBFRAME_LEN, in, + sizeof(int16_t) * SUBFRAME_LEN); + + /* Update filter memories */ + synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1), + p->perf_fir_mem, p->perf_iir_mem, + in, vector + PITCH_MAX, 0); + memmove(p->harmonic_mem, p->harmonic_mem + SUBFRAME_LEN, + sizeof(int16_t) * (PITCH_MAX - SUBFRAME_LEN)); + memcpy(p->harmonic_mem + PITCH_MAX - SUBFRAME_LEN, vector + PITCH_MAX, + sizeof(int16_t) * SUBFRAME_LEN); + + in += SUBFRAME_LEN; + offset += LPC_ORDER; + } + + if ((ret = ff_alloc_packet2(avctx, avpkt, 24)) < 0) + return ret; + + *got_packet_ptr = 1; + avpkt->size = pack_bitstream(p, avpkt->data, avpkt->size); + return 0; +} + +AVCodec ff_g723_1_encoder = { + .name = "g723_1", + .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_G723_1, + .priv_data_size = sizeof(G723_1_Context), + .init = g723_1_encode_init, + .encode2 = g723_1_encode_frame, + .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE}, +}; +#endif diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g723_1_data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g723_1_data.h new file mode 100644 index 000000000..38a6c5998 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g723_1_data.h @@ -0,0 +1,1329 @@ +/* + * G723.1 compatible decoder data tables. + * Copyright (c) 2006 Benjamin Larsson + * Copyright (c) 2010 Mohamed Naufal Basheer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * G723.1 compatible decoder data tables + */ + +#ifndef AVCODEC_G723_1_DATA_H +#define AVCODEC_G723_1_DATA_H + +#include + +#define SUBFRAMES 4 +#define SUBFRAME_LEN 60 +#define FRAME_LEN (SUBFRAME_LEN << 2) +#define HALF_FRAME_LEN (FRAME_LEN / 2) +#define LPC_FRAME (HALF_FRAME_LEN + SUBFRAME_LEN) +#define LPC_ORDER 10 +#define LSP_BANDS 3 +#define LSP_CB_SIZE 256 +#define PITCH_MIN 18 +#define PITCH_MAX (PITCH_MIN + 127) +#define PITCH_ORDER 5 +#define GRID_SIZE 2 +#define PULSE_MAX 6 +#define GAIN_LEVELS 24 +#define COS_TBL_SIZE 512 + +/** + * G723.1 frame types + */ +typedef enum FrameType { + ACTIVE_FRAME, ///< Active speech + SID_FRAME, ///< Silence Insertion Descriptor frame + UNTRANSMITTED_FRAME +} FrameType; + +static const uint8_t frame_size[4] = { 24, 20, 4, 1 }; + +typedef enum Rate { + RATE_6300, + RATE_5300 +} Rate; + +/** + * G723.1 unpacked data subframe + */ +typedef struct G723_1_Subframe { + int ad_cb_lag; ///< adaptive codebook lag + int ad_cb_gain; + int dirac_train; + int pulse_sign; + int grid_index; + int amp_index; + int pulse_pos; +} G723_1_Subframe; + +/** + * Pitch postfilter parameters + */ +typedef struct { + int index; ///< postfilter backward/forward lag + int16_t opt_gain; ///< optimal gain + int16_t sc_gain; ///< scaling gain +} PPFParam; + +/** + * Harmonic filter parameters + */ +typedef struct { + int index; + int gain; +} HFParam; + +/** + * Optimized fixed codebook excitation parameters + */ +typedef struct { + int min_err; + int amp_index; + int grid_index; + int dirac_train; + int pulse_pos[PULSE_MAX]; + int pulse_sign[PULSE_MAX]; +} FCBParam; + +/** + * Postfilter gain weighting factors scaled by 2^15 + */ +static const int16_t ppf_gain_weight[2] = {0x1800, 0x2000}; + +/** + * LSP DC component + */ +static const int16_t dc_lsp[LPC_ORDER] = { + 0x0c3b, + 0x1271, + 0x1e0a, + 0x2a36, + 0x3630, + 0x406f, + 0x4d28, + 0x56f4, + 0x638c, + 0x6c46 +}; + +/** + * Cosine table scaled by 2^14 + */ +static const int16_t cos_tab[COS_TBL_SIZE+1] = { + 16384, 16383, 16379, 16373, 16364, 16353, 16340, 16324, + 16305, 16284, 16261, 16235, 16207, 16176, 16143, 16107, + 16069, 16029, 15986, 15941, 15893, 15843, 15791, 15736, + 15679, 15619, 15557, 15493, 15426, 15357, 15286, 15213, + 15137, 15059, 14978, 14896, 14811, 14724, 14635, 14543, + 14449, 14354, 14256, 14155, 14053, 13949, 13842, 13733, + 13623, 13510, 13395, 13279, 13160, 13039, 12916, 12792, + 12665, 12537, 12406, 12274, 12140, 12004, 11866, 11727, + 11585, 11442, 11297, 11151, 11003, 10853, 10702, 10549, + 10394, 10238, 10080, 9921, 9760, 9598, 9434, 9269, + 9102, 8935, 8765, 8595, 8423, 8250, 8076, 7900, + 7723, 7545, 7366, 7186, 7005, 6823, 6639, 6455, + 6270, 6084, 5897, 5708, 5520, 5330, 5139, 4948, + 4756, 4563, 4370, 4176, 3981, 3786, 3590, 3393, + 3196, 2999, 2801, 2603, 2404, 2205, 2006, 1806, + 1606, 1406, 1205, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1205, -1406, + -1606, -1806, -2006, -2205, -2404, -2603, -2801, -2999, + -3196, -3393, -3590, -3786, -3981, -4176, -4370, -4563, + -4756, -4948, -5139, -5330, -5520, -5708, -5897, -6084, + -6270, -6455, -6639, -6823, -7005, -7186, -7366, -7545, + -7723, -7900, -8076, -8250, -8423, -8595, -8765, -8935, + -9102, -9269, -9434, -9598, -9760, -9921, -10080, -10238, + -10394, -10549, -10702, -10853, -11003, -11151, -11297, -11442, + -11585, -11727, -11866, -12004, -12140, -12274, -12406, -12537, + -12665, -12792, -12916, -13039, -13160, -13279, -13395, -13510, + -13623, -13733, -13842, -13949, -14053, -14155, -14256, -14354, + -14449, -14543, -14635, -14724, -14811, -14896, -14978, -15059, + -15137, -15213, -15286, -15357, -15426, -15493, -15557, -15619, + -15679, -15736, -15791, -15843, -15893, -15941, -15986, -16029, + -16069, -16107, -16143, -16176, -16207, -16235, -16261, -16284, + -16305, -16324, -16340, -16353, -16364, -16373, -16379, -16383, + -16384, -16383, -16379, -16373, -16364, -16353, -16340, -16324, + -16305, -16284, -16261, -16235, -16207, -16176, -16143, -16107, + -16069, -16029, -15986, -15941, -15893, -15843, -15791, -15736, + -15679, -15619, -15557, -15493, -15426, -15357, -15286, -15213, + -15137, -15059, -14978, -14896, -14811, -14724, -14635, -14543, + -14449, -14354, -14256, -14155, -14053, -13949, -13842, -13733, + -13623, -13510, -13395, -13279, -13160, -13039, -12916, -12792, + -12665, -12537, -12406, -12274, -12140, -12004, -11866, -11727, + -11585, -11442, -11297, -11151, -11003, -10853, -10702, -10549, + -10394, -10238, -10080, -9921, -9760, -9598, -9434, -9269, + -9102, -8935, -8765, -8595, -8423, -8250, -8076, -7900, + -7723, -7545, -7366, -7186, -7005, -6823, -6639, -6455, + -6270, -6084, -5897, -5708, -5520, -5330, -5139, -4948, + -4756, -4563, -4370, -4176, -3981, -3786, -3590, -3393, + -3196, -2999, -2801, -2603, -2404, -2205, -2006, -1806, + -1606, -1406, -1205, -1005, -804, -603, -402, -201, + 0, 201, 402, 603, 804, 1005, 1205, 1406, + 1606, 1806, 2006, 2205, 2404, 2603, 2801, 2999, + 3196, 3393, 3590, 3786, 3981, 4176, 4370, 4563, + 4756, 4948, 5139, 5330, 5520, 5708, 5897, 6084, + 6270, 6455, 6639, 6823, 7005, 7186, 7366, 7545, + 7723, 7900, 8076, 8250, 8423, 8595, 8765, 8935, + 9102, 9269, 9434, 9598, 9760, 9921, 10080, 10238, + 10394, 10549, 10702, 10853, 11003, 11151, 11297, 11442, + 11585, 11727, 11866, 12004, 12140, 12274, 12406, 12537, + 12665, 12792, 12916, 13039, 13160, 13279, 13395, 13510, + 13623, 13733, 13842, 13949, 14053, 14155, 14256, 14354, + 14449, 14543, 14635, 14724, 14811, 14896, 14978, 15059, + 15137, 15213, 15286, 15357, 15426, 15493, 15557, 15619, + 15679, 15736, 15791, 15843, 15893, 15941, 15986, 16029, + 16069, 16107, 16143, 16176, 16207, 16235, 16261, 16284, + 16305, 16324, 16340, 16353, 16364, 16373, 16379, 16383, + 16384 +}; + +/** + * LSP VQ tables + */ +static const int16_t lsp_band0[LSP_CB_SIZE][3] = { + { 0, 0, 0}, { -270, -1372, -1032}, { -541, -1650, -1382}, + { -723, -2011, -2213}, { -941, -1122, -1942}, { -780, -1145, -2454}, + { -884, -1309, -1373}, {-1051, -1523, -1766}, {-1083, -1622, -2300}, + { -777, -1377, -2147}, { -935, -1467, -2763}, { -802, -1327, -3471}, + { -935, -1959, -3999}, { -240, -89, 222}, { -661, -257, -160}, + { -994, -466, -419}, { -188, -164, -278}, { -342, -512, -415}, + { -607, -511, -797}, { 16, 19, -716}, { 374, 425, -972}, + { -346, 245, -282}, { -265, 506, -754}, { -620, -147, 1955}, + { -742, -860, 2597}, { -150, -352, 2704}, { 305, 880, 1954}, + { 123, 731, 2766}, { -348, 765, 3327}, { 618, 221, 3258}, + { -178, -47, 4219}, { 393, 1304, 3842}, { 698, 1702, 4801}, + { 63, -584, 1229}, { -215, -732, 1704}, { 172, -335, 1909}, + { -2, 216, 1797}, { 353, 127, 2205}, {-1208, 188, 11}, + { -513, -75, -683}, { -973, 222, -646}, { -616, -843, -388}, + { -950, -1113, -359}, {-1431, -623, -705}, {-1398, -1063, -178}, + { -45, -461, 35}, { -9, -657, -216}, { 127, -1078, 95}, + { -950, -1156, 584}, {-1480, -1494, 449}, { -120, -705, 516}, + { -368, -961, 727}, { -378, -526, 973}, { -793, -614, 676}, + { -801, -755, 1287}, {-1476, -340, 1636}, { -505, -1254, 1543}, + {-1243, -1622, 1532}, { -776, -1477, -655}, {-1151, -1296, -823}, + {-1153, -1672, -1124}, {-1291, -2003, -1702}, { -622, -1283, 57}, + { -471, -1611, 509}, {-1060, -1570, -139}, { -873, -2156, -536}, + {-1716, -2021, -364}, {-2150, -3218, -1291}, {-1248, -1945, -2904}, + {-1215, -2633, -2855}, { 167, -244, 84}, { 349, -412, -217}, + { -40, -352, 632}, { 227, -529, 405}, { 68, -383, -443}, + { 167, -558, -706}, { -275, -854, -14}, { -351, -1089, -449}, + { 341, -72, -289}, { 603, -106, -474}, { 322, -219, -649}, + { 179, -317, -998}, { 450, -291, -996}, { 555, 195, -525}, + { 784, 272, -831}, { -148, -384, -849}, { 82, -536, -1357}, + { 238, -172, -1354}, { 422, -268, -1841}, { 297, -737, -2079}, + { -111, -801, -598}, { 1, -668, -984}, { -131, -818, -1299}, + { -329, -521, -1310}, { -151, -778, -1834}, { -93, -352, -1746}, + { -568, -640, -1821}, { -509, -941, -2183}, { 464, -815, -1250}, + { 79, -1133, -1597}, { -184, -1353, -2123}, { -196, -410, -2427}, + { -192, -833, -2810}, { -259, -1382, -3045}, { -217, 4, -1166}, + { -800, -325, -1219}, { -363, -830, -898}, { -661, -1134, -960}, + { -386, -980, -1501}, { -627, -1159, -1722}, { -903, -829, -855}, + { -685, -829, -1313}, {-1065, -959, -1405}, { 441, 25, -847}, + { 655, -27, -1181}, { 1159, -110, -705}, { 856, 253, -1671}, + { 415, 404, -1}, { 322, 903, -398}, { 670, 499, -292}, + { 803, 591, -610}, { 1144, 591, -814}, { 717, 183, 393}, + { 857, 381, 106}, { 609, 62, -27}, { 792, 198, -325}, + { 735, 805, 88}, { 1142, 812, 78}, { 1028, 366, -292}, + { 1309, 743, -237}, { 1615, 589, -79}, { 1010, 639, -243}, + { 999, 964, -311}, { 1500, 1137, -615}, { 988, 357, 646}, + { 1227, 667, 683}, { 1164, 1565, 894}, { 1392, 2015, 477}, + { 1138, 533, 250}, { 1437, 896, 391}, { 1765, 1118, 99}, + { 1112, 1090, 802}, { 1596, 846, 1134}, { 937, 1161, 279}, + { 1719, 1254, 683}, { 1338, 1086, 35}, { 1419, 1324, 428}, + { 1428, 1524, 40}, { 2108, 1594, 89}, { 1015, 544, 1222}, + { 1121, 925, 1263}, { 1030, 1318, 1485}, { 1295, 789, 1817}, + { 1323, 1272, 1909}, { 1724, 1237, 1803}, { 1797, 1689, 858}, + { 2149, 1367, 1301}, { 2302, 1867, 761}, { 2863, 2351, 1053}, + { 52, 163, -76}, { 230, 309, -492}, { -71, 619, 39}, + { -218, 856, 499}, { -654, 736, -207}, { -535, 1259, 155}, + { -480, 1476, 643}, { 262, 1081, 102}, { 309, 1592, -182}, + { 627, 1629, 534}, { 337, 643, 456}, { 758, 670, 713}, + { 202, 1126, 658}, { 612, 1131, 666}, { 686, 1223, 1136}, + { -131, 377, 525}, { 42, 708, 907}, { 87, 1488, 1035}, + { 432, 2117, 904}, { 137, 981, 1332}, { -447, 1014, 1136}, + { -839, 1793, 1246}, { -559, 297, 198}, { -850, 685, 446}, + {-1273, 632, 826}, { -401, -544, 173}, { -753, -793, 144}, + { -436, -9, 772}, { -115, -243, 1310}, { -670, -269, 374}, + {-1027, -13, 639}, { -887, -81, 1137}, {-1277, -455, 158}, + {-1411, -720, 736}, { 172, 88, 403}, { 386, 255, 756}, + { -500, 522, 910}, { -958, 659, 1388}, { -395, 301, 1344}, + { -356, 768, 1813}, { -613, 841, 2419}, { 445, -122, 252}, + { 629, -87, 723}, { 283, -253, 870}, { 456, -116, 1381}, + { 757, 180, 1059}, { 532, 408, 1509}, { 947, 288, 1806}, + { 1325, 994, 2524}, { 892, 1219, 3023}, { 1397, 1596, 3406}, + { 1143, 1552, 2546}, { 1850, 1433, 2710}, { -10, 134, 1002}, + { 154, 499, 1323}, { 508, 792, 1117}, { 509, 1340, 1616}, + { 762, 862, 1608}, { 787, 740, 2320}, { 794, 1727, 1283}, + { 465, 2108, 1660}, { -120, 1451, 1613}, { -386, 2016, 2169}, + { 891, 1225, 2050}, { 456, 1480, 2185}, { 1493, 1283, 1209}, + { 1397, 1636, 1518}, { 1776, 1738, 1552}, { 1572, 1698, 2141}, + { 1389, 2126, 1271}, { 1959, 2413, 1119}, { 1365, 2892, 1505}, + { 2206, 1971, 1623}, { 2076, 1950, 2280}, { 1717, 2291, 1867}, + { 2366, 2515, 1953}, { 2865, 2838, 2522}, { 2535, 3465, 2011}, + { 3381, 4127, 2638}, { 836, 2667, 2289}, { 1761, 2773, 2337}, + { 1415, 3325, 2911}, { 2354, 3138, 3126}, { 2659, 4192, 4010}, + { 1048, 1786, 1818}, { 1242, 2111, 2240}, { 1512, 2079, 2780}, + { 1573, 2491, 3138}, { 2230, 2377, 2782}, { 416, 1773, 2704}, + { 725, 2336, 3297}, { 1252, 2373, 3978}, { 2094, 2268, 3568}, + { 2011, 2712, 4528}, { 1341, 3507, 3876}, { 1216, 3919, 4922}, + { 1693, 4793, 6012} +}; + +static const int16_t lsp_band1[LSP_CB_SIZE][3] = { + { 0, 0, 0}, {-2114, -1302, 76}, {-2652, -1278, -1368}, + {-2847, -828, -349}, {-3812, -2190, -349}, {-3946, -364, -449}, + {-2725, -4492, -3607}, {-3495, -4764, -1744}, { -51, -756, 84}, + { -153, -1191, 504}, { 108, -1418, 1167}, { -835, -896, 390}, + { -569, -1702, 87}, {-1151, -1818, 933}, {-1826, -2547, 411}, + {-1842, -1818, 1451}, {-2438, -1611, 781}, {-2747, -2477, 1311}, + { -940, 1252, 477}, {-1629, 1688, 602}, {-1202, 617, 280}, + {-1737, 393, 580}, {-1528, 1077, 1199}, {-2165, -161, 1408}, + {-2504, -1087, 2371}, {-3458, -175, 1395}, {-1397, -98, -843}, + {-2252, -177, -1149}, {-1489, -726, -1283}, {-1558, -265, -1744}, + {-1867, -821, -1897}, {-2062, -1516, -2340}, {-2595, -1142, -2861}, + { 170, 46, -819}, { -193, -204, -1151}, { 326, -196, -1532}, + { 780, 329, -816}, { 201, 369, -1243}, { 650, -209, -1060}, + { 1144, -15, -1216}, { 1203, -259, -1867}, { -890, -564, -1430}, + { -638, -852, -1921}, { 177, -739, -1358}, { -261, -526, -1666}, + { 206, -407, -2255}, { 338, -526, -822}, { 421, -1095, -1009}, + { 765, -607, -1408}, { 825, -1295, -2004}, { 357, -905, -1815}, + { -58, -1248, -1588}, { -596, -1436, -2046}, { -73, -1159, -2116}, + { -115, -1382, -2581}, { -160, -1723, -1952}, { -6, -2196, -2954}, + { -649, -1705, -2603}, { -617, -1453, -3282}, { -949, -2019, -3102}, + { -812, 1544, 1937}, {-1854, 574, 2000}, {-1463, 1140, 2649}, + {-2683, 1748, 1452}, {-2486, 2241, 2523}, { 783, 1910, 1435}, + { 581, 2682, 1376}, { 236, 2197, 1885}, { -453, 2943, 2057}, + { -682, 2178, 2565}, {-1342, 3201, 3328}, { -288, -184, 262}, + { 121, -149, -183}, { 758, -412, 206}, { 1038, -204, 853}, + { 1577, -457, 700}, { 937, -640, -567}, { 1508, -528, -1024}, + { -225, -527, -427}, { -564, -1095, -332}, { -742, -353, -186}, + {-1288, -459, 84}, {-1853, -484, -274}, {-1554, -731, 825}, + {-2425, -234, 382}, {-1722, 293, -271}, {-2515, 425, -564}, + {-2599, 818, 464}, { -358, 118, -375}, { -613, 198, -874}, + { -690, 683, -324}, {-1352, 1155, -168}, {-1093, 129, -324}, + {-1184, 611, -858}, { 433, 386, -372}, { -120, 486, -634}, + { 234, 851, -631}, { 602, 128, 46}, { 1099, 410, 159}, + { 715, -145, -424}, { 1198, -85, -593}, { 1390, 367, -358}, + { 1683, 362, -964}, { 1711, 622, 45}, { 2033, 833, -383}, + { 2890, 549, -506}, { 7, 401, 52}, { 72, 811, 415}, + { 566, 668, 41}, { 467, 1218, 130}, { 68, 957, -187}, + { -25, 1649, -103}, { -661, 260, 214}, { -925, -94, 612}, + { -321, -422, 965}, { -788, -672, 1783}, { 400, -673, 779}, + { 741, -595, 1635}, { -161, 307, 657}, { -382, 836, 871}, + { -814, 400, 1223}, { 364, 606, 1247}, { 57, 75, 1571}, + { 151, 471, 2287}, { -81, 1021, 1502}, { 227, 1470, 1097}, + { 658, 1275, 1653}, { 664, 1478, 2377}, { 263, -127, 444}, + { 264, 89, 969}, { 794, 171, 576}, { 821, 186, 1226}, + { 404, 462, 517}, { 339, 918, 794}, { 1280, 1423, 196}, + { 1453, 2019, 365}, { 1615, 1481, 672}, { 2394, 1708, 508}, + { 806, 1238, 573}, { 713, 1158, 1078}, { 1285, 1436, 1232}, + { 1790, 1188, 1141}, { 765, 643, 864}, { 1032, 797, 1279}, + { 900, 563, 1827}, { 1514, 673, 2312}, { 1544, 1129, 3240}, + { 1469, 1050, 1594}, { 1945, 1318, 1988}, { 2397, 2026, 2060}, + { 3538, 2057, 2620}, { 1249, -118, 74}, { 1727, 194, 421}, + { 2078, -50, -463}, { 970, 688, -432}, { 1149, 952, -110}, + { 1254, 1275, -651}, { 1386, 929, 401}, { 1960, 1167, 232}, + { 407, -752, -243}, { 859, -1118, 172}, { -227, -860, -992}, + { -796, -1175, -1380}, { 8, -1282, -388}, { 353, -1781, -1037}, + { -732, -397, -807}, { -853, -28, -1342}, {-1229, -1207, -1959}, + {-1015, -1125, -2543}, {-1452, -1791, -2725}, {-1891, -2416, -3269}, + { -918, -1629, -783}, { -580, -2155, -698}, {-1097, -2364, -96}, + {-1387, -1513, 7}, {-1588, -2076, -664}, {-1473, -2740, -784}, + {-2378, -3149, -56}, {-2856, -2092, -169}, {-3391, -3708, 316}, + {-1176, -890, -614}, {-1944, -1061, -800}, { -299, -1517, -1000}, + { -640, -1850, -1526}, {-1454, -1536, -1233}, {-1890, -1955, -1756}, + {-1086, -1921, -2122}, { -750, -2325, -2260}, {-1325, -2413, -2673}, + {-1114, -2542, -3459}, {-1341, -2901, -3963}, {-1160, -2226, -1393}, + {-1001, -2772, -1573}, {-1594, -2641, -1978}, {-1534, -3046, -2624}, + {-2224, -2196, -675}, {-2807, -3054, -1102}, {-2008, -2840, -1186}, + {-1980, -3332, -1695}, {-1715, -3562, -505}, {-2527, -4000, -1887}, + {-2333, -2734, -2296}, {-3440, -2401, -3211}, {-2008, -3528, -3337}, + {-2247, -3291, -4510}, { -475, 949, 155}, { -149, 1365, 545}, + { -757, 1644, 1083}, { -217, 2053, 1353}, {-1433, 2301, 1462}, + { 495, 1661, 529}, { 10, 2037, 740}, { 2082, 1898, 978}, + { 2831, 2294, 911}, { 842, 793, 420}, { 1223, 1023, 863}, + { 1237, 451, 780}, { 1744, 708, 822}, { 1533, 284, 1384}, + { 2135, 609, 1538}, { 2305, 626, 540}, { 2368, 1187, 955}, + { 2586, 1255, -7}, { 3116, 1131, 726}, { 3431, 1730, 428}, + { 2734, 1648, 1307}, { 2988, 1231, 2010}, { 3523, 2024, 1488}, + { 1034, 1657, 871}, { 1206, 2163, 1036}, { 1807, 2372, 1233}, + { 1808, 1769, 1493}, { 1573, 2332, 1779}, { 1216, 1609, 1866}, + { 1480, 1898, 2513}, { 465, 2708, 2776}, { 771, 3638, 3338}, + { 1869, 2599, 2623}, { 2825, 2745, 2468}, { 2638, 2439, 1585}, + { 2094, 2970, 1308}, { 2022, 3057, 1999}, { 3428, 2912, 1816}, + { 4536, 2974, 2129}, { 1046, 2563, 2086}, { 1363, 3562, 2318}, + { 2511, 1891, 2984}, { 1866, 2306, 3986}, { 3272, 2924, 3682}, + { 3146, 3564, 2272}, { 3592, 3968, 2822}, { 2431, 3369, 3069}, + { 1931, 4709, 3090}, { 2629, 4220, 3986}, { 4639, 4056, 3664}, + { 4035, 5334, 4912} +}; + +static const int16_t lsp_band2[LSP_CB_SIZE][4] = { + { 0, 0, 0, 0}, { 601, 512, -542, 334}, + { 428, 1087, -484, -132}, { 652, 622, -391, -572}, + { 378, 799, 141, -860}, { 1040, 409, 112, -554}, + { 1123, 670, -75, -847}, { 1421, 494, -315, -1095}, + { 787, 1001, 114, -460}, { 988, 1672, 216, -681}, + { 1007, 1241, -132, -1247}, { 1073, 399, 186, -5}, + { 1262, 193, -694, -129}, { 325, 196, 51, -641}, + { 861, -59, 350, -458}, { 1261, 567, 586, -346}, + { 1532, 885, 210, -517}, { 2027, 937, 113, -792}, + { 1383, 1064, 334, 38}, { 1964, 1468, 459, 133}, + { 2062, 1186, -98, -121}, { 2577, 1445, 506, -373}, + { 2310, 1682, -2, -960}, { 2876, 1939, 765, 138}, + { 3581, 2360, 649, -414}, { 219, 176, -398, -309}, + { 434, -78, -435, -880}, { -344, 301, 265, -552}, + { -915, 470, 657, -380}, { 419, -432, -163, -453}, + { 351, -953, 8, -562}, { 789, -43, 20, -958}, + { 302, -594, -352, -1159}, { 1040, 108, -668, -924}, + { 1333, 210, -1217, -1663}, { 483, 589, -350, -1140}, + { 1003, 824, -802, -1184}, { 745, 58, -589, -1443}, + { 346, 247, -915, -1683}, { 270, 796, -720, -2043}, + { 1208, 722, -222, -193}, { 1486, 1180, -412, -672}, + { 1722, 179, -69, -521}, { 2047, 860, -666, -1410}, + { -146, 222, -281, -805}, { -189, 90, -114, -1307}, + { -152, 1086, -241, -764}, { -439, 733, -601, -1302}, + { -833, -167, -351, -601}, { -856, -422, -411, -1059}, + { -747, -355, -582, -1644}, { -837, 210, -916, -1144}, + {-1800, 32, -878, -1687}, { -48, -23, -1146, 52}, + { -350, -409, -1656, -364}, { 265, -728, -858, -577}, + { 458, -247, -1141, -997}, { 691, -407, -1988, -1161}, + { -66, -104, -705, -1249}, { -431, -93, -1191, -1844}, + { 203, -732, -1000, -1693}, { 10, -832, -1846, -1819}, + { 493, -128, -1436, -1768}, { 488, -311, -1730, -2540}, + { -653, -532, -1150, -1172}, {-1086, -289, -1706, -1533}, + { -699, -1205, -1216, -1766}, {-1032, -1481, -2074, -1523}, + { -721, -1220, -2277, -2600}, { 12, -539, -1484, -1131}, + { -40, -911, -2106, -441}, { -471, -484, -2267, -1549}, + { -141, -988, -3006, -1721}, {-1545, -2102, -583, 342}, + {-1383, -2772, -386, -13}, {-2118, -2589, -1205, 72}, + {-2147, -3231, -965, 390}, {-2949, -3300, -621, 637}, + {-3907, -4138, -865, 803}, {-1287, -845, -375, -548}, + {-1416, -1169, -487, -1277}, {-1400, -1690, -1027, -418}, + {-2018, -1909, -1188, -1260}, {-1418, -2222, -2029, -128}, + {-2067, -2998, -2693, -310}, { -950, -1028, -1538, 185}, + {-1616, -915, -2205, -549}, { 19, -821, -1145, 352}, + { 184, -1175, -1356, -627}, { -547, -1088, -1661, -911}, + { -216, -1502, -2197, -948}, { -795, -1306, -2374, -451}, + { -924, -1889, -2796, -680}, { -600, -1614, -3609, -885}, + {-2392, -2528, 319, 303}, {-2908, -2095, -310, 573}, + {-3460, -2141, 49, -113}, {-2231, -448, 675, -146}, + {-2805, -532, 1231, 479}, {-2684, -486, -200, 611}, + {-3525, -971, -198, 704}, {-3707, 173, 349, 254}, + {-4734, -1447, -34, 880}, { 777, -512, 114, -10}, + { 1250, -66, 442, -5}, { 604, 613, 452, -352}, + { 1224, 777, 675, -1014}, {-1372, -79, -1208, -238}, + {-2389, -17, -1157, -818}, {-1504, -673, -1133, -1060}, + {-1984, -799, -2005, -1973}, {-2037, -798, -1068, -105}, + {-3190, -899, -1817, -194}, { -156, -886, 394, -318}, + { -258, -1283, 551, 202}, { -536, -1729, 910, 331}, + { -847, -1109, 795, -163}, {-1171, -1128, 715, 519}, + {-1080, -1319, 1685, 668}, {-1000, -1921, 96, 211}, + {-1487, -2148, 831, 174}, {-1139, -374, 414, -4}, + {-1517, -1383, 396, -352}, {-1012, 439, -59, -967}, + {-1812, 706, -440, -1030}, {-1971, -329, -34, -827}, + {-2472, -1588, -151, -606}, {-2161, 374, -281, 76}, + {-3012, 231, -15, -690}, { 1104, 566, 721, 209}, + { 1685, 564, 383, 98}, { 1898, 750, 792, -97}, + { 556, -64, 561, -93}, { 876, 162, 913, -22}, + { 961, 675, 1296, 140}, { 756, -396, 851, 544}, + { 360, -303, 1341, 396}, { 878, -22, 1464, 863}, + { -309, -273, 642, -129}, { -686, -82, 842, 454}, + { -5, -47, 1069, 998}, { -94, 967, 1277, 298}, + { -489, 385, 1473, 746}, { -369, -717, 1333, 242}, + { 281, -993, 1726, 924}, { 464, 601, 1575, 1376}, + { -250, 206, 2339, 1175}, { -438, 377, -597, -285}, + {-1020, 787, -790, -287}, { -458, -410, 215, 295}, + { -589, -860, -121, 797}, {-1175, 122, -437, 466}, + {-1480, -121, 367, 924}, { 234, 323, 770, -555}, + { 145, 30, 996, 26}, { 66, 849, 93, -145}, + { -117, 1261, 474, -399}, {-1495, 1051, 218, -506}, + {-1390, 694, 994, 88}, { 616, 7, 78, 304}, + { 1060, 52, -62, 835}, { 833, 454, 649, 1359}, + { -770, 464, 47, 93}, { -574, 1199, -39, 379}, + { 114, -98, 488, 485}, { 727, 244, 606, 696}, + { -76, 455, 671, 546}, { -565, -13, 145, 819}, + { -376, 569, 448, 1128}, { 218, 122, 265, 1167}, + { 230, 738, 932, 1003}, { 138, 477, 36, 450}, + { 404, 787, -73, 1000}, { 497, 1259, 387, 1231}, + { 17, 207, 195, -79}, { 562, 358, 53, -158}, + { 493, 387, 478, 189}, { 678, 831, 640, 558}, + { -197, 523, 613, 57}, { 429, 894, 769, 111}, + { 67, 1174, 568, 511}, { 1242, 824, 251, 840}, + { 1419, 1074, 864, 481}, { 924, 1474, 669, 724}, + { 1539, 1879, 654, 1590}, { 445, 337, 1111, 541}, + { 472, 1421, 1264, 1094}, { 794, 735, 1103, 668}, + { 1055, 863, 1192, 1020}, { 778, 1105, 806, 1798}, + { 1052, 1527, 1587, 2151}, { 881, 1552, 1265, 391}, + { 726, 872, 1812, 601}, { 1469, 280, 1008, 616}, + { 1403, 577, 1803, 1244}, { 1650, 1314, 1148, 1072}, + { 1297, 1669, 1911, 1026}, { 2093, 1044, 2115, 1189}, + { 1644, 1961, 2587, 1512}, { 25, -315, -9, -106}, + { 290, -339, 428, -444}, { -68, -783, 735, 772}, + { 245, -555, 468, 47}, { 334, -895, 814, 146}, + { 235, 368, -964, -959}, { -203, 315, -1566, -1217}, + { 801, 17, -276, -354}, { 894, -495, -789, -635}, + { 716, 291, -1189, -357}, { 560, -260, -733, -2}, + { 679, -508, -1429, 211}, { -51, -62, -428, 557}, + { 322, -638, -211, 614}, { -878, -1057, -84, -71}, + { -388, -1415, -167, -318}, { -754, -1574, 214, -539}, + {-1419, -2004, -92, -787}, { -47, -856, -347, -255}, + { 23, -1211, -173, 320}, { -658, -487, -893, 353}, + { -783, -1587, -584, 507}, {-1420, -859, -378, 441}, + {-2095, -1491, -137, 439}, { -321, -1450, -1288, -12}, + { -359, -2113, -553, -8}, { -831, -1918, -1561, 32}, + {-1014, -2487, -1359, -939}, { -475, -311, -169, -236}, + { -907, -426, 276, -611}, { -96, -400, 50, -710}, + { -426, -1022, -10, -985}, { -197, -258, -744, -575}, + { -611, -930, -771, -394}, { -267, -776, -612, -939}, + { -256, -1346, -802, -1122}, { -796, -1570, -825, -754}, + { 712, 876, 141, 227}, { 981, 1509, 85, 124}, + { 1462, 1228, 979, -39}, { 1734, 999, 1481, 440}, + { 2293, 1116, 769, 440}, { 2504, 1480, 1241, 356}, + { 2474, 1909, 1558, 810}, { 917, 1134, 607, -134}, + { 509, 1809, 781, -123}, { 1712, 1506, 559, -423}, + { 2037, 2317, 726, -155}, { 3031, 2676, 1203, 331}, + { 3664, 3274, 1768, 531}, { 1610, 1839, 867, 183}, + { 1774, 1972, 1538, 97}, { 1822, 2158, 1282, 659}, + { 2222, 2758, 1818, 900}, { 3251, 2124, 1723, 996}, + { 3633, 2336, 2408, 1453}, { 2923, 3517, 2567, 1318}, +}; + +/** + * Used for the coding/decoding of the pulses positions + * for the MP-MLQ codebook + */ +static const int32_t combinatorial_table[PULSE_MAX][SUBFRAME_LEN/GRID_SIZE] = { + {118755, 98280, 80730, 65780, 53130, + 42504, 33649, 26334, 20349, 15504, + 11628, 8568, 6188, 4368, 3003, + 2002, 1287, 792, 462, 252, + 126, 56, 21, 6, 1, + 0, 0, 0, 0, 0}, + + { 23751, 20475, 17550, 14950, 12650, + 10626, 8855, 7315, 5985, 4845, + 3876, 3060, 2380, 1820, 1365, + 1001, 715, 495, 330, 210, + 126, 70, 35, 15, 5, + 1, 0, 0, 0, 0}, + + { 3654, 3276, 2925, 2600, 2300, + 2024, 1771, 1540, 1330, 1140, + 969, 816, 680, 560, 455, + 364, 286, 220, 165, 120, + 84, 56, 35, 20, 10, + 4, 1, 0, 0, 0}, + + { 406, 378, 351, 325, 300, + 276, 253, 231, 210, 190, + 171, 153, 136, 120, 105, + 91, 78, 66, 55, 45, + 36, 28, 21, 15, 10, + 6, 3, 1, 0, 0}, + + { 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, + 19, 18, 17, 16, 15, + 14, 13, 12, 11, 10, + 9, 8, 7, 6, 5, + 4, 3, 2, 1, 0}, + + { 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1}, +}; + +static const int16_t pitch_contrib[340] = { + 60, 0, 0, 2489, 60, 0, 0, 5217, + 1, 6171, 0, 3953, 0, 10364, 1, 9357, + -1, 8843, 1, 9396, 0, 5794, -1, 10816, + 2, 11606, -2, 12072, 0, 8616, 1, 12170, + 0, 14440, 0, 7787, -1, 13721, 0, 18205, + 0, 14471, 0, 15807, 1, 15275, 0, 13480, + -1, 18375, -1, 0, 1, 11194, -1, 13010, + 1, 18836, -2, 20354, 1, 16233, -1, 0, + 60, 0, 0, 12130, 0, 13385, 1, 17834, + 1, 20875, 0, 21996, 1, 0, 1, 18277, + -1, 21321, 1, 13738, -1, 19094, -1, 20387, + -1, 0, 0, 21008, 60, 0, -2, 22807, + 0, 15900, 1, 0, 0, 17989, -1, 22259, + 1, 24395, 1, 23138, 0, 23948, 1, 22997, + 2, 22604, -1, 25942, 0, 26246, 1, 25321, + 0, 26423, 0, 24061, 0, 27247, 60, 0, + -1, 25572, 1, 23918, 1, 25930, 2, 26408, + -1, 19049, 1, 27357, -1, 24538, 60, 0, + -1, 25093, 0, 28549, 1, 0, 0, 22793, + -1, 25659, 0, 29377, 0, 30276, 0, 26198, + 1, 22521, -1, 28919, 0, 27384, 1, 30162, + -1, 0, 0, 24237, -1, 30062, 0, 21763, + 1, 30917, 60, 0, 0, 31284, 0, 29433, + 1, 26821, 1, 28655, 0, 31327, 2, 30799, + 1, 31389, 0, 32322, 1, 31760, -2, 31830, + 0, 26936, -1, 31180, 1, 30875, 0, 27873, + -1, 30429, 1, 31050, 0, 0, 0, 31912, + 1, 31611, 0, 31565, 0, 25557, 0, 31357, + 60, 0, 1, 29536, 1, 28985, -1, 26984, + -1, 31587, 2, 30836, -2, 31133, 0, 30243, + -1, 30742, -1, 32090, 60, 0, 2, 30902, + 60, 0, 0, 30027, 0, 29042, 60, 0, + 0, 31756, 0, 24553, 0, 25636, -2, 30501, + 60, 0, -1, 29617, 0, 30649, 60, 0, + 0, 29274, 2, 30415, 0, 27480, 0, 31213, + -1, 28147, 0, 30600, 1, 31652, 2, 29068, + 60, 0, 1, 28571, 1, 28730, 1, 31422, + 0, 28257, 0, 24797, 60, 0, 0, 0, + 60, 0, 0, 22105, 0, 27852, 60, 0, + 60, 0, -1, 24214, 0, 24642, 0, 23305, + 60, 0, 60, 0, 1, 22883, 0, 21601, + 60, 0, 2, 25650, 60, 0, -2, 31253, + -2, 25144, 0, 17998 +}; + +/** + * Number of non-zero pulses in the MP-MLQ excitation + */ +static const int8_t pulses[4] = {6, 5, 6, 5}; + +/** + * Size of the MP-MLQ fixed excitation codebooks + */ +static const int32_t max_pos[4] = {593775, 142506, 593775, 142506}; + +static const int16_t fixed_cb_gain[GAIN_LEVELS] = { + 1, 2, 3, 4, 6, 9, 13, 18, + 26, 38, 55, 80, 115, 166, 240, 348, + 502, 726, 1050, 1517, 2193, 3170, 4582, 6623, +}; + +static const int16_t adaptive_cb_gain85[85 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 800, 1496, 167, -256, + -338, -39, -136, -1, -4, -6, -73, -8, + -15, 12, 23, 2, 16, 30, 3, -5, + -462, -686, 493, 2575, 311, -13, -28, -14, + -404, -5, -19, 13, 20, 72, 107, -77, + 8, 13, -9, -48, 1483, 144, 784, 928, + 1243, -134, -1, -37, -52, -94, -13, -71, + -6, -84, -8, -44, -112, -10, -59, -70, + -77, 275, 3522, 1056, -1254, 0, -4, -757, + -68, -95, 1, 16, -59, 4, -17, -227, + -5, 21, 269, 80, -125, -40, -264, 381, + 5027, 0, 0, -4, -8, -1542, 0, -2, + 0, 2, 0, 6, 38, 12, 81, -117, + 138, 332, 2215, 2574, 1339, -1, -6, -299, + -404, -109, -2, -18, -44, -21, -52, -348, + -11, -27, -181, -210, 3685, 2883, -887, 866, + -1639, -828, -507, -48, -45, -164, -648, 199, + 156, -194, -152, 46, 368, 288, -88, 86, + 1396, 2146, 2235, 345, 942, -118, -281, -305, + -7, -54, -182, -190, -292, -29, -45, -47, + -80, -123, -128, -19, 13, 4475, 3549, -804, + -655, 0, -1222, -768, -39, -26, -3, -2, + -969, 0, 219, 174, 0, 179, 141, -32, + -724, 254, 242, 6049, 2462, -32, -3, -3, + -2233, -370, 11, 10, -3, 267, -94, -89, + 108, -38, -36, -909, 626, -1713, 6121, 4561, + -1061, -23, -179, -2287, -1270, -68, 65, -233, + 640, -174, 477, -1704, 40, -111, 396, 295, + -350, 1391, 7985, 511, -405, -7, -118, -3892, + -15, -10, 29, 170, -678, 10, -43, -249, + -8, 34, 197, 12, 3144, -529, 608, 2530, + 3878, -603, -17, -22, -390, -918, 101, -116, + 19, -485, 81, -93, -744, 125, -144, -599, + 2589, -689, 3045, 5603, -404, -409, -29, -566, + -1916, -10, 108, -481, 128, -885, 235, -1041, + 63, -17, 75, 138, 3107, 513, 1374, -3594, + -4922, -589, -16, -115, -788, -1478, -97, -260, + -43, 681, 112, 301, 933, 154, 413, -1079, + 2468, 6010, 1107, -390, 1961, -372, -2204, -74, + -9, -234, -905, -166, -406, 58, 143, 26, + -295, -719, -132, 46, 4773, 2766, 2368, 4862, + -4044, -1390, -467, -342, -1443, -998, -806, -690, + -399, -1416, -821, -702, 1178, 682, 584, 1200, + 1665, -1879, 1443, 1701, 8562, -169, -215, -127, + -176, -4475, 190, -146, 165, -172, 195, -149, + -870, 982, -754, -889, 2716, 9011, -1007, 755, + -1785, -450, -4956, -61, -34, -194, -1493, 167, + 554, -125, -415, 46, 296, 982, -109, 82, + -2727, 7548, 1285, 938, 3420, -453, -3478, -100, + -53, -714, 1256, 213, -592, 156, -432, -73, + 569, -1576, -268, -196, 3677, 882, 4050, 1202, + 2323, -825, -47, -1001, -88, -329, -198, -909, + -218, -269, -64, -297, -521, -125, -574, -170, + 2046, -753, 122, 10102, 603, -255, -34, 0, + -6229, -22, 94, -15, 5, -1261, 464, -75, + -75, 27, -4, -372, 449, -1815, 10690, 3870, + -527, -12, -201, -6976, -914, -16, 49, -293, + 1184, -106, 428, -2525, 14, -58, 344, 124, + -941, 2352, 5049, 3650, 2637, -54, -337, -1556, + -813, -424, 135, 290, -725, 209, -524, -1125, + 151, -378, -812, -587, -1879, 796, 3117, 9569, + -404, -215, -38, -593, -5589, -9, 91, 357, + -151, 1097, -464, -1821, -46, 19, 76, 236, + -1715, 2043, -2096, 9946, 4001, -179, -254, -268, + -6038, -977, 213, -219, 261, 1041, -1240, 1272, + 418, -498, 511, -2429, -5772, -618, -3921, 284, + -3155, -2033, -23, -938, -4, -607, -218, -1381, + -148, 100, 10, 68, -1111, -119, -755, 54, + 382, 4748, 8003, -2064, 2198, -8, -1376, -3909, + -260, -294, -110, -186, -2319, 48, 598, 1008, + -51, -637, -1073, 277, -867, 3015, 11926, -1675, + 947, -45, -555, -8681, -171, -54, 159, 631, + -2195, -88, 308, 1219, 50, -174, -690, 96, + -4933, -432, 6757, 3771, 1352, -1485, -11, -2786, + -867, -111, -130, 2034, 178, 1135, 99, -1555, + 407, 35, -557, -311, 152, 9726, 4231, -1928, + 1490, -1, -5774, -1092, -226, -135, -90, -39, + -2511, 17, 1144, 498, -13, -884, -384, 175, + 2512, 193, 9033, 5361, -3148, -385, -2, -4980, + -1754, -605, -29, -1385, -106, -822, -63, -2956, + 482, 37, 1735, 1030, 8464, 2844, 12, 549, + 2132, -4373, -493, 0, -18, -277, -1469, -6, + -2, -284, -95, 0, -1101, -370, -1, -71, + 2141, -2602, 7166, 9046, -1350, -279, -413, -3134, + -4994, -111, 340, -936, 1138, -1182, 1436, -3957, + 176, -214, 590, 745, -244, 278, 13307, 1227, + -161, -3, -4, -10808, -91, -1, 4, 198, + -226, 18, -20, -997, -2, 2, 131, 12, + -1947, 8217, 6269, 917, -2559, -231, -4121, -2399, + -51, -399, 976, 745, -3144, 108, -460, -350, + -304, 1283, 979, 143, -1810, 2061, -2781, 6056, + 10058, -200, -259, -472, -2238, -6174, 227, -307, + 349, 669, -761, 1028, 1111, -1265, 1707, -3717, + 7827, 9161, -3409, 2473, -1510, -3739, -5122, -709, + -373, -139, -4376, 1628, 1906, -1181, -1382, 514, + 721, 844, -314, 228, -1430, 8313, 9541, -2955, + 1626, -124, -4218, -5556, -533, -161, 725, 832, + -4841, -257, 1499, 1721, 142, -825, -947, 293, + 2819, -4247, 5391, 8673, 2756, -485, -1101, -1774, + -4591, -463, 730, -927, 1397, -1492, 2248, -2854, + -474, 714, -907, -1459, 141, 14552, 690, 257, + -112, -1, -12926, -29, -4, 0, -125, -5, + -613, -2, -228, -10, 0, 99, 4, 1, + 11938, -1859, 1806, -962, -884, -8699, -211, -199, + -56, -47, 1355, -1316, 205, 701, -109, 106, + 644, -100, 97, -51, 3728, 1982, 2264, 4584, + 3131, -848, -239, -312, -1282, -598, -451, -515, + -273, -1043, -554, -633, -712, -378, -432, -876, + -1181, 766, 720, 14303, -216, -85, -35, -31, + -12486, -2, 55, 51, -33, 1031, -668, -628, + -15, 10, 9, 189, -4385, 4826, 10112, 1569, + 3388, -1173, -1421, -6242, -150, -700, 1291, 2706, + -2979, 420, -462, -969, 906, -998, -2091, -324, + -448, 1932, 15591, -1842, 657, -12, -227, -14837, + -207, -26, 52, 427, -1838, -50, 217, 1753, + 18, -77, -626, 74, -4141, 1844, 3962, 5517, + 6220, -1046, -207, -958, -1858, -2361, 466, 1001, + -446, 1394, -621, -1334, 1572, -700, -1504, -2094, + 729, -2299, 14755, 3657, -952, -32, -322, -13288, + -816, -55, 102, -656, 2071, -162, 513, -3294, + 42, -133, 857, 212, -1385, 5801, 13339, -3137, + 1344, -117, -2054, -10861, -600, -110, 490, 1127, + -4723, -265, 1111, 2554, 113, -476, -1094, 257, + 4710, 9661, 1073, -2467, 3274, -1354, -5697, -70, + -371, -654, -2777, -308, -633, 709, 1455, 161, + -941, -1930, -214, 493, 1843, -3624, 12422, 6898, + -1559, -207, -802, -9419, -2904, -148, 407, -1397, + 2748, -775, 1526, -5230, 175, -344, 1182, 656, + 1433, 2394, 2507, 1380, 8780, -125, -349, -383, + -116, -4705, -209, -219, -366, -120, -201, -211, + -768, -1283, -1343, -740, -1712, 12915, 5883, -2197, + 991, -179, -10181, -2112, -294, -60, 1350, 615, + -4638, -229, 1732, 789, 103, -781, -356, 133, + 15072, 2158, -1245, 910, -496, -13865, -284, -94, + -50, -15, -1986, 1145, 164, -837, -119, 69, + 456, 65, -37, 27, 4655, 7319, 4916, 586, + -3381, -1322, -3270, -1475, -20, -697, -2079, -1396, + -2196, -166, -261, -175, 960, 1510, 1014, 120, + 1191, -2140, 5120, 13498, -1418, -86, -279, -1600, + -11121, -122, 155, -372, 669, -981, 1763, -4218, + 103, -185, 443, 1168, -1530, -817, 8191, 9632, + -1452, -143, -40, -4095, -5663, -128, -76, 765, + 408, 900, 480, -4815, -135, -72, 726, 854, + -3236, 607, 1696, -2106, 11485, -639, -22, -175, + -270, -8051, 119, 335, -62, -416, 78, 218, + 2268, -425, -1189, 1476, 3203, -1903, -837, 9679, + 7057, -626, -221, -42, -5718, -3039, 372, 163, + -97, -1892, 1124, 494, -1380, 819, 360, -4169, + 213, -655, 17015, 620, -384, -2, -26, -17671, + -23, -9, 8, -221, 681, -8, 24, -644, + 5, -15, 399, 14, 5088, 35, -3339, 3726, + 8488, -1580, 0, -680, -847, -4397, -10, 1037, + 7, -1157, -8, 759, -2636, -18, 1730, -1930, + -988, 1454, -2688, 15039, 2682, -59, -129, -441, + -13805, -439, 87, -162, 238, 907, -1335, 2467, + 161, -238, 440, -2462, -4865, -2842, -53, 5495, + 6523, -1445, -493, 0, -1843, -2597, -844, -16, + -9, 1632, 953, 18, 1937, 1131, 21, -2188, + 3076, 15069, -2914, 1810, -971, -577, -13860, -518, + -200, -57, -2829, 547, 2680, -339, -1665, 322, + 182, 893, -172, 107, 1311, 5355, 11054, 2299, + -3654, -105, -1750, -7458, -322, -814, -428, -885, + -3613, -184, -751, -1551, 292, 1194, 2465, 512, + 4035, 5619, 4618, 1815, 1912, -994, -1927, -1301, + -201, -223, -1384, -1137, -1583, -447, -622, -511, + -471, -656, -539, -211, -2131, 2754, -4501, 12879, + 7432, -277, -463, -1236, -10124, -3371, 358, -585, + 756, 1675, -2165, 3538, 967, -1249, 2042, -5842, + 5618, -515, 3219, -4149, 4857, -1926, -16, -632, + -1050, -1440, 176, -1104, 101, 1422, -130, 815, + -1666, 152, -954, 1230, 1838, -1709, 1139, 16867, + 716, -206, -178, -79, -17366, -31, 191, -127, + 118, -1892, 1759, -1173, -80, 74, -49, -737, + 1978, -3845, 10050, 11854, -2492, -238, -902, -6164, + -8576, -379, 464, -1213, 2358, -1431, 2782, -7271, + 301, -585, 1529, 1803, -2600, 11246, 11289, -3647, + 1463, -412, -7720, -7778, -812, -130, 1784, 1791, + -7749, -578, 2504, 2513, 232, -1004, -1008, 325, + 3442, 907, 2725, 8970, 3638, -723, -50, -453, + -4911, -808, -190, -572, -150, -1884, -496, -1492, + -764, -201, -605, -1992, -126, 17498, 3481, -2003, + 1090, 0, -18689, -739, -244, -72, 135, 26, + -3717, -15, 2139, 425, 8, -1165, -231, 133, + -1814, 1048, -2164, 4070, 16272, -200, -67, -285, + -1011, -16160, 116, -239, 138, 450, -260, 537, + 1801, -1041, 2149, -4042, 9354, 12580, -1883, 962, + -617, -5341, -9660, -216, -56, -23, -7183, 1075, + 1446, -549, -738, 110, 352, 474, -71, 36, + 1708, 4199, 7387, 6335, 1003, -178, -1076, -3330, + -2449, -61, -437, -770, -1893, -660, -1623, -2856, + -104, -257, -452, -388, -2624, 5623, 17310, -2353, + 592, -420, -1930, -18288, -338, -21, 900, 2772, + -5941, -376, 807, 2486, 94, -203, -625, 85, + 1211, -850, 1193, -1926, 15992, -89, -44, -86, + -226, -15609, 62, -88, 61, 142, -100, 140, + -1182, 830, -1165, 1880, 3983, -2054, 11506, -19, + 3622, -968, -257, -8080, 0, -801, 499, -2797, + 1442, 4, -2, 13, -880, 454, -2544, 4, + -786, -1354, 16092, 7246, -1665, -37, -111, -15805, + -3205, -169, -65, 772, 1330, 348, 599, -7117, + -80, -137, 1636, 736, -4316, -511, 6674, 11665, + 4633, -1137, -15, -2719, -8305, -1310, -134, 1758, + 208, 3073, 364, -4752, 1220, 144, -1887, -3299, + 7912, 4557, 1937, 1885, 7037, -3821, -1267, -229, + -216, -3022, -2200, -935, -538, -910, -524, -222, + -3398, -1957, -832, -809, 3434, 2967, 5867, 8196, + 8766, -720, -537, -2101, -4100, -4690, -622, -1230, + -1062, -1718, -1484, -2935, -1837, -1588, -3139, -4385, + 5881, 9176, 8119, 3934, 3355, -2111, -5139, -4023, + -944, -687, -3294, -2914, -4547, -1412, -2203, -1949, + -1204, -1879, -1662, -805 +}; + +static const int16_t adaptive_cb_gain170[170 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 776, 212, 715, 670, + 809, -36, -2, -31, -27, -39, -10, -33, + -9, -31, -8, -29, -38, -10, -35, -33, + 1296, 1316, -168, -320, -815, -102, -105, -1, + -6, -40, -104, 13, 13, 25, 25, -3, + 64, 65, -8, -15, -589, 680, 2478, 308, + -596, -21, -28, -375, -5, -21, 24, 89, + -102, 11, -12, -46, -21, 24, 90, 11, + -735, -487, -5, 2948, 468, -33, -14, 0, + -530, -13, -21, 0, 0, 132, 87, 0, + 21, 13, 0, -84, 1042, 1730, 1068, 333, + 626, -66, -182, -69, -6, -23, -110, -67, + -112, -21, -35, -21, -39, -66, -40, -12, + 486, -769, 4074, 2825, -1107, -14, -36, -1013, + -487, -74, 22, -120, 191, -83, 132, -702, + 32, -52, 275, 191, 1521, -767, -124, 4320, + 1026, -141, -35, 0, -1139, -64, 71, 11, + -5, -401, 202, 32, -95, 48, 7, -270, + 2425, 1267, 3439, -91, -1166, -359, -98, -722, + 0, -83, -187, -509, -266, 13, 7, 19, + 172, 90, 244, -6, -1251, 975, 173, 4039, + 2005, -95, -58, -1, -996, -245, 74, 13, + -10, 308, -240, -42, 153, -119, -21, -494, + 1820, 632, 1322, 2062, 1031, -202, -24, -106, + -259, -64, -70, -146, -51, -229, -79, -166, + -114, -39, -83, -129, -447, 4904, 244, -315, + -2038, -12, -1467, -3, -6, -253, 134, 6, + -73, -8, 94, 4, -55, 610, 30, -39, + -208, -1102, 463, -448, 5653, -2, -74, -13, + -12, -1950, -14, 5, 31, -5, -30, 12, + 71, 380, -159, 154, 4739, 2600, -1864, 856, + -1554, -1371, -412, -212, -44, -147, -752, 539, + 295, -247, -135, 97, 449, 246, -176, 81, + 1894, 3533, 35, -26, 2145, -219, -762, 0, + 0, -280, -408, -4, -7, 3, 5, 0, + -248, -462, -4, 3, -2699, 1841, 4072, 2443, + 1582, -444, -207, -1012, -364, -152, 303, 670, + -457, 402, -274, -607, 260, -177, -393, -236, + -844, 3358, 6106, -1059, -537, -43, -688, -2275, + -68, -17, 173, 314, -1251, -54, 217, 395, + -27, 110, 200, -34, 1251, 1016, 3020, 2210, + 1445, -95, -63, -556, -298, -127, -77, -230, + -187, -168, -137, -407, -110, -89, -266, -194, + 2099, 2277, 4038, 3533, -2870, -269, -316, -995, + -762, -503, -291, -517, -561, -452, -491, -871, + 367, 399, 707, 619, 400, -1114, 8516, 2422, + -1117, -9, -75, -4426, -358, -76, 27, -208, + 579, -59, 164, -1259, 27, -75, 580, 165, + -4398, -2011, 3912, -2407, 2258, -1180, -247, -934, + -353, -311, -540, 1050, 480, -646, -295, 575, + 606, 277, -539, 331, 1767, -1447, 4240, 6160, + -757, -190, -127, -1097, -2316, -35, 156, -457, + 374, -664, 544, -1594, 81, -66, 195, 284, + 1594, -1463, 1035, 6938, 1920, -155, -130, -65, + -2938, -225, 142, -100, 92, -675, 619, -438, + -186, 171, -121, -813, -562, 4716, 4085, -591, + 2421, -19, -1357, -1018, -21, -357, 162, 140, + -1175, -20, 170, 147, 83, -696, -603, 87, + 1552, 8778, -935, 354, -1424, -147, -4703, -53, + -7, -123, -831, 88, 501, -33, -189, 20, + 134, 763, -81, 30, 4831, -4431, 41, -1479, + -2976, -1424, -1198, 0, -133, -540, 1306, -12, + 11, 436, -400, 3, 877, -804, 7, -268, + 2090, 1192, 1006, 1645, 4853, -266, -86, -61, + -165, -1437, -152, -128, -73, -210, -119, -101, + -619, -353, -298, -487, 2386, 5712, 1426, -94, + 1350, -347, -1991, -124, 0, -111, -832, -207, + -497, 13, 32, 8, -196, -470, -117, 7, + -1349, 1091, 1659, 8891, 313, -111, -72, -168, + -4825, -5, 89, 136, -110, 732, -592, -900, + 25, -20, -31, -170, 9980, 916, -381, -808, + 88, -6080, -51, -8, -39, 0, -558, 232, + 21, 492, 45, -18, -53, -4, 2, 4, + 2338, -1031, -248, 3928, 6484, -333, -64, -3, + -942, -2566, 147, 35, -15, -560, 247, 59, + -925, 408, 98, -1555, 6166, -1240, -337, 3672, + -1277, -2320, -93, -6, -823, -99, 466, 126, + -25, -1382, 278, 75, 480, -96, -26, 286, + 4377, -132, -2588, 1701, 4865, -1169, -1, -409, + -176, -1444, 35, 691, -20, -454, 13, 268, + -1299, 39, 768, -505, 2594, 3295, 3944, 1481, + 682, -410, -662, -949, -133, -28, -521, -624, + -793, -234, -297, -356, -108, -137, -164, -61, + 4151, 624, 815, 4485, 2229, -1052, -23, -40, + -1228, -303, -158, -206, -31, -1136, -170, -223, + -565, -84, -111, -610, -3575, -361, 4924, 2791, + 4698, -780, -7, -1480, -475, -1347, -78, 1074, + 108, 609, 61, -839, 1025, 103, -1412, -800, + -2518, 3791, 8623, 315, 2465, -387, -877, -4538, + -6, -370, 582, 1325, -1995, 48, -73, -166, + 378, -570, -1297, -47, -691, 2989, 9957, -421, + -1142, -29, -545, -6051, -10, -79, 126, 420, + -1817, -17, 76, 256, -48, 208, 694, -29, + -1918, 104, -3190, -3410, -4440, -224, 0, -621, + -709, -1203, 12, -373, 20, -399, 21, -664, + -519, 28, -864, -924, -3359, -1668, 1854, 6939, + 1430, -688, -169, -209, -2939, -124, -341, 380, + 188, 1422, 706, -785, 293, 145, -161, -606, + 42, 9706, 3164, -952, 907, 0, -5750, -611, + -55, -50, -25, -8, -1874, 2, 564, 183, + -2, -537, -175, 52, 1607, 785, 2862, 4327, + 3307, -157, -37, -500, -1143, -667, -77, -280, + -137, -424, -207, -756, -324, -158, -577, -873, + 6801, 3416, 2227, 1682, -3217, -2823, -712, -302, + -172, -631, -1418, -924, -464, -698, -350, -228, + 1335, 670, 437, 330, 3459, 3898, 364, 7841, + -2640, -730, -927, -8, -3753, -425, -823, -76, + -86, -1655, -1865, -174, 557, 628, 58, 1263, + -5902, -3458, -2465, -1886, 4334, -2126, -730, -371, + -217, -1146, -1245, -888, -520, -679, -398, -283, + 1561, 915, 652, 499, -3710, 1133, 7849, 3443, + -215, -840, -78, -3760, -723, -2, 256, 1777, + -543, 779, -238, -1649, -48, 14, 103, 45, + 4132, 2828, 2, -4212, -4116, -1042, -488, 0, + -1083, -1034, -713, 0, 0, 1062, 727, 0, + 1038, 710, 0, -1058, 5875, 8496, -1796, 1376, + -1786, -2107, -4406, -197, -115, -194, -3047, 644, + 931, -493, -713, 150, 640, 926, -195, 150, + 3143, 3483, 3546, -793, 4489, -603, -740, -767, + -38, -1230, -668, -680, -754, 152, 168, 171, + -861, -954, -971, 217, 2845, 7965, 3695, -5432, + 3978, -494, -3873, -833, -1801, -966, -1383, -641, + -1796, 943, 2641, 1225, -691, -1934, -897, 1319, + 1538, 150, 7139, 2049, 3097, -144, -1, -3110, + -256, -585, -14, -670, -65, -192, -18, -892, + -290, -28, -1349, -387, 618, 7520, 4729, -238, + -3373, -23, -3452, -1365, -3, -694, -283, -178, + -2170, 8, 109, 68, 127, 1548, 973, -49, + 2965, -3013, 7912, 7076, -1997, -536, -554, -3821, + -3056, -243, 545, -1431, 1455, -1280, 1301, -3417, + 361, -367, 964, 862, 2443, -929, -1113, 9677, + 4138, -364, -52, -75, -5716, -1045, 138, 166, + -63, -1443, 549, 657, -617, 234, 281, -2444, + 1966, 3309, 10085, -3399, 2105, -236, -668, -6207, + -705, -270, -397, -1210, -2037, 408, 686, 2092, + -252, -425, -1295, 436, -112, -1368, 8868, 4822, + 2048, 0, -114, -4800, -1419, -256, -9, 61, + 740, 33, 402, -2610, 14, 171, -1108, -602, + -2597, 438, -1839, 6229, 7266, -411, -11, -206, + -2368, -3223, 69, -291, 49, 987, -166, 699, + 1152, -194, 816, -2763, 3454, 553, 9127, 4946, + -5596, -728, -18, -5084, -1493, -1911, -116, -1924, + -308, -1042, -166, -2755, 1179, 188, 3117, 1689, + -532, -663, 12262, 2495, -1004, -17, -26, -9177, + -380, -61, -21, 398, 496, 81, 101, -1867, + -32, -40, 751, 152, -2100, 1317, -1509, 11425, + 2997, -269, -105, -139, -7967, -548, 168, -193, + 121, 1464, -918, 1052, 384, -240, 276, -2090, + 1193, -2697, 11259, 5373, -763, -86, -444, -7737, + -1762, -35, 196, -819, 1853, -391, 884, -3692, + 55, -125, 525, 250, 2405, -471, 11079, 203, + 782, -353, -13, -7491, -2, -37, 69, -1626, + 318, -29, 5, -137, -114, 22, -529, -9, + -1871, 5685, 11290, -2662, 1353, -213, -1972, -7780, + -432, -111, 649, 1289, -3917, -304, 923, 1834, + 154, -469, -932, 220, -3768, 5927, -3093, 5041, + 5212, -866, -2144, -584, -1551, -1658, 1363, -711, + 1119, 1159, -1824, 951, 1198, -1885, 984, -1603, + -2546, 9502, 5969, -2440, 1928, -395, -5511, -2175, + -363, -226, 1477, 927, -3462, -379, 1415, 889, + 299, -1118, -702, 287, -4963, 3568, 4592, 5508, + 3451, -1503, -777, -1287, -1851, -727, 1080, 1391, + -1000, 1668, -1199, -1543, 1045, -751, -967, -1160, + 1745, -2586, 3983, 10899, -1551, -186, -408, -968, + -7250, -146, 275, -424, 628, -1161, 1720, -2649, + 165, -244, 377, 1032, 867, -456, -727, 3369, + 11822, -45, -12, -32, -692, -8531, 24, 38, + -20, -178, 93, 149, -625, 329, 525, -2431, + 7535, 2422, 1926, 1405, 1599, -3466, -358, -226, + -120, -156, -1114, -886, -284, -646, -207, -165, + -735, -236, -188, -137, 1041, -735, -142, 13209, + 1515, -66, -33, -1, -10649, -140, 46, 9, + -6, -839, 593, 114, -96, 68, 13, -1222, + 7950, 6745, -1444, -1008, 2721, -3857, -2777, -127, + -62, -452, -3273, 700, 594, 489, 415, -88, + -1320, -1120, 239, 167, -4754, -1379, 4522, -578, + -5733, -1379, -116, -1248, -20, -2006, -400, 1312, + 380, -167, -48, 159, -1663, -482, 1582, -202, + 3220, 5978, 5923, 2430, -2689, -633, -2181, -2141, + -360, -441, -1175, -1164, -2161, -477, -886, -878, + 528, 981, 972, 398, 377, 1312, 13978, -1470, + 677, -8, -105, -11925, -132, -28, -30, -321, + -1119, 33, 117, 1254, -15, -54, -577, 60, + -3435, 6770, 314, -885, 5686, -720, -2797, -6, + -47, -1973, 1419, 65, -129, -185, 366, 16, + 1192, -2349, -109, 307, 3171, 8774, -2260, 2679, + 3069, -613, -4699, -312, -438, -575, -1698, 437, + 1210, -518, -1435, 369, -594, -1643, 423, -501, + 5557, 1509, 5407, -125, -7386, -1884, -139, -1784, + 0, -3330, -511, -1834, -498, 42, 11, 41, + 2505, 680, 2438, -56, -2838, 2595, 13228, 271, + 1793, -491, -411, -10680, -4, -196, 449, 2291, + -2095, 47, -42, -219, 310, -284, -1447, -29, + 664, -278, 14966, 951, -711, -26, -4, -13672, + -55, -30, 11, -606, 253, -38, 16, -869, + 28, -12, 650, 41, 808, 1770, 8658, 5863, + -1486, -39, -191, -4576, -2098, -134, -87, -427, + -935, -289, -633, -3098, 73, 160, 785, 531, + 3063, 1539, 2000, -542, 9576, -572, -144, -244, + -17, -5597, -287, -374, -188, 101, 51, 66, + -1790, -900, -1169, 317, 514, 14083, -323, 896, + -891, -16, -12106, -6, -49, -48, -442, 10, + 277, -28, -770, 17, 27, 766, -17, 48, + 892, 158, 5237, 11057, -1603, -48, -1, -1674, + -7462, -156, -8, -285, -50, -602, -106, -3534, + 87, 15, 512, 1082, -1612, 2564, -4296, 12526, + 5710, -158, -401, -1126, -9576, -1990, 252, -422, + 672, 1232, -1960, 3284, 561, -893, 1497, -4365, + 4889, -6878, 612, 6109, 4753, -1459, -2887, -22, + -2277, -1379, 2052, -182, 257, -1823, 2564, -228, + -1418, 1995, -177, -1772, 3053, -506, 2403, 9625, + 1322, -569, -15, -352, -5655, -106, 94, -448, + 74, -1794, 297, -1412, -246, 40, -194, -777, + -754, 12904, 4480, -2113, 1471, -34, -10163, -1225, + -272, -132, 594, 206, -3529, -97, 1664, 577, + 67, -1159, -402, 189, 4255, 1476, 5055, 2393, + 2912, -1105, -132, -1559, -349, -517, -383, -1313, + -455, -621, -215, -738, -756, -262, -898, -425, + -1371, 535, 1417, 14604, -997, -114, -17, -122, + -13017, -60, 44, 118, -46, 1222, -477, -1263, + -83, 32, 86, 888, 5368, -1744, 4083, -1236, + 3753, -1758, -185, -1017, -93, -860, 571, -1338, + 434, 405, -131, 308, -1229, 399, -935, 283, + 1588, -3097, 14415, 3699, -1171, -154, -585, -12683, + -835, -83, 300, -1397, 2725, -358, 699, -3255, + 113, -221, 1030, 264, 212, 7989, 9471, -3344, + 2009, -2, -3895, -5475, -682, -246, -103, -123, + -4618, 43, 1630, 1933, -26, -979, -1161, 410, + 856, 2294, -627, 6930, 6929, -44, -321, -24, + -2931, -2930, -119, 32, 87, -362, -970, 265, + -362, -970, 265, -2931, 2357, -4187, 7162, 7683, + 3371, -339, -1070, -3131, -3603, -693, 602, -1030, + 1830, -1105, 1963, -3359, -485, 861, -1474, -1581, + 350, 4585, 14053, -3819, 1218, -7, -1283, -12054, + -890, -90, -97, -300, -3933, 81, 1068, 3275, + -26, -341, -1045, 284, -3248, 3531, 475, 2137, + 11711, -644, -761, -13, -278, -8372, 700, 94, + -102, 423, -460, -62, 2322, -2524, -340, -1528, + -3017, 3852, 1725, 8440, 5257, -555, -905, -181, + -4348, -1686, 709, 317, -405, 1554, -1984, -889, + 968, -1236, -553, -2708, -909, 3196, 15512, -2528, + 1066, -50, -623, -14686, -390, -69, 177, 861, + -3026, -140, 493, 2393, 59, -208, -1009, 164, + 959, -3370, 9617, 9545, -1761, -56, -693, -5645, + -5561, -189, 197, -563, 1978, -558, 1963, -5603, + 103, -362, 1034, 1026, 7575, 11796, -4845, 3252, + -1703, -3502, -8493, -1433, -645, -177, -5454, 2240, + 3488, -1503, -2341, 961, 787, 1226, -503, 338, + 6409, 1722, 1764, -4191, 6015, -2507, -181, -189, + -1072, -2208, -673, -690, -185, 1639, 440, 451, + -2353, -632, -647, 1538, -2420, 12161, 5038, 1286, + -2098, -357, -9027, -1549, -100, -268, 1796, 744, + -3740, 190, -954, -395, -310, 1557, 645, 164, + -2232, -1341, 7246, 9470, -1977, -304, -109, -3204, + -5474, -238, -182, 987, 593, 1290, 775, -4188, + -269, -161, 874, 1143, 1030, 7034, 4231, 1551, + 3077, -64, -3019, -1093, -146, -577, -442, -266, + -1816, -97, -666, -400, -193, -1321, -794, -291, + 5121, 11835, -477, -1749, 2298, -1601, -8549, -13, + -186, -322, -3699, 149, 344, 546, 1264, -50, + -718, -1660, 66, 245, -3328, 3827, 5921, 9976, + -1045, -676, -894, -2140, -6075, -66, 777, 1203, + -1383, 2027, -2330, -3605, -212, 244, 377, 636, + 3813, 5718, -4666, -3412, 5674, -887, -1995, -1329, + -710, -1965, -1331, 1086, 1628, 794, 1191, -972, + -1320, -1980, 1616, 1181, 1348, -3672, 13154, 6938, + -1690, -110, -823, -10561, -2938, -174, 302, -1082, + 2948, -570, 1555, -5570, 139, -379, 1357, 716, + 2151, -3586, 6949, 12131, -1224, -282, -785, -2947, + -8982, -91, 470, -912, 1521, -1592, 2655, -5145, + 160, -268, 519, 906, -2889, 9647, 10276, -2728, + 995, -509, -5680, -6445, -454, -60, 1701, 1812, + -6051, -481, 1606, 1711, 175, -586, -624, 165, + 6177, 2184, 555, 1985, 6589, -2329, -291, -18, + -240, -2650, -823, -209, -74, -748, -264, -67, + -2484, -878, -223, -798, -492, 391, 17166, -681, + 240, -14, -9, -17987, -28, -3, 11, 515, + -410, -20, 16, 713, 7, -5, -252, 10, + 12628, 5448, -2630, 3011, -2695, -9733, -1811, -422, + -553, -443, -4199, 2027, 874, -2321, -1001, 483, + 2077, 896, -432, 495, -3628, -534, 3447, 7002, + 6751, -803, -17, -725, -2992, -2782, -118, 763, + 112, 1550, 228, -1473, 1495, 220, -1420, -2885, + -5239, 5901, 8107, 3650, 4846, -1675, -2125, -4012, + -813, -1433, 1887, 2592, -2920, 1167, -1315, -1806, + 1550, -1745, -2398, -1080, 6157, 6678, 4099, -1074, + 2348, -2314, -2722, -1025, -70, -336, -2509, -1540, + -1670, 403, 437, 268, -882, -957, -587, 153, + 1079, 16099, 242, -881, 1690, -71, -15820, -3, + -47, -174, -1060, -16, -238, 58, 865, 13, + -111, -1661, -25, 90, -278, 227, -1039, 1636, + 16945, -4, -3, -65, -163, -17526, 3, -17, + 14, 27, -22, 103, 287, -234, 1074, -1693, + 15778, -1454, 574, -603, -107, -15195, -129, -20, + -22, 0, 1400, -553, 51, 581, -53, 21, + 103, -9, 3, -3, 2406, -836, 13224, 7993, + -4266, -353, -42, -10673, -3899, -1111, 122, -1942, + 674, -1174, 407, -6451, 626, -217, 3443, 2081, + 3184, 14368, -3336, 2255, -1801, -619, -12600, -679, + -310, -198, -2793, 648, 2926, -438, -1977, 459, + 350, 1580, -366, 247, -1698, 17076, 2504, -539, + -646, -176, -17798, -382, -17, -25, 1770, 259, + -2610, -55, 561, 82, -67, 673, 98, -21, + 2375, -797, -2696, 14483, 5383, -344, -38, -443, + -12803, -1769, 115, 391, -131, -2100, 705, 2384, + -780, 262, 886, -4759, -2691, 2554, -4520, 9573, + 10655, -442, -398, -1247, -5594, -6930, 419, -742, + 704, 1572, -1492, 2641, 1750, -1661, 2939, -6226, + -4332, -4399, -1657, 4880, 7375, -1145, -1181, -167, + -1453, -3319, -1163, -438, -444, 1290, 1310, 493, + 1950, 1980, 745, -2196, -3498, 7405, 9955, 2693, + -2971, -746, -3347, -6049, -442, -538, 1581, 2125, + -4499, 575, -1217, -1636, -634, 1342, 1805, 488, + 6717, -3792, 7739, 2798, 3489, -2754, -877, -3655, + -477, -743, 1554, -3173, 1791, -1147, 647, -1321, + -1430, 807, -1648, -595, 5263, 9770, 3463, 1069, + -3971, -1690, -5826, -732, -69, -962, -3138, -1112, + -2065, -343, -637, -226, 1275, 2368, 839, 259, + 1243, -2634, 16772, 1871, 332, -94, -423, -17169, + -213, -6, 199, -1273, 2696, -142, 300, -1915, + -25, 53, -339, -37, 2691, 2836, 3105, 5711, + 4817, -442, -491, -588, -1991, -1416, -465, -510, + -537, -938, -988, -1082, -791, -834, -913, -1679, + 4366, 2944, 7210, 3627, 1161, -1163, -529, -3172, + -803, -82, -784, -1921, -1295, -966, -651, -1596, + -309, -208, -511, -257, 13888, 3951, -671, -2305, + 3354, -11773, -953, -27, -324, -686, -3349, 569, + 161, 1954, 556, -94, -2843, -809, 137, 472, + 7053, 5847, 2929, 8378, -4794, -3036, -2086, -523, + -4284, -1403, -2517, -1261, -1045, -3607, -2990, -1498, + 2064, 1711, 857, 2451, -2191, 12838, 9182, -3915, + 1617, -293, -10059, -5146, -935, -159, 1717, 1228, + -7195, -523, 3068, 2194, 216, -1267, -906, 386, + -4881, 13114, 5767, -435, 4155, -1454, -10498, -2030, + -11, -1054, 3907, 1718, -4616, -129, 348, 153, + 1238, -3326, -1462, 110, 7843, -1250, 210, 7106, + -5203, -3754, -95, -2, -3082, -1652, 598, -100, + 16, -3402, 542, -91, 2491, -397, 66, 2257, + -2463, 8168, 14551, -3908, 1828, -370, -4072, -12923, + -932, -204, 1228, 2188, -7254, -587, 1948, 3471, + 274, -911, -1623, 436, -1579, 347, -272, -2735, + 16031, -152, -7, -4, -456, -15686, 33, -26, + 5, -263, 58, -45, 1545, -340, 266, 2676, + -6327, 1328, 5093, -5079, 7617, -2443, -107, -1583, + -1574, -3541, 513, 1967, -413, -1961, 411, 1578, + 2941, -617, -2367, 2361, 3286, -4509, 11306, 11025, + -2623, -659, -1241, -7802, -7419, -420, 904, -2267, + 3112, -2211, 3034, -7608, 526, -722, 1810, 1765, + 5567, 17853, -3754, 1166, -519, -1892, -19455, -860, + -83, -16, -6067, 1275, 4090, -396, -1271, 267, + 176, 566, -119, 37, -2136, -424, 15292, 5108, + -1648, -278, -10, -14273, -1593, -165, -55, 1993, + 396, 666, 132, -4768, -214, -42, 1538, 514, + 2267, -3297, 2549, 16563, -791, -313, -663, -396, + -16745, -38, 456, -352, 513, -2291, 3333, -2576, + 109, -159, 123, 799, 3655, 1899, -3364, 6279, + 12510, -815, -220, -690, -2406, -9552, -423, 750, + 390, -1400, -728, 1289, -2791, -1450, 2568, -4794, + 8052, 2285, -6193, 5138, 6003, -3957, -318, -2341, + -1611, -2199, -1123, 3044, 864, -2525, -716, 1942, + -2950, -837, 2269, -1882, -386, -2291, 7679, 15387, + -2723, -9, -320, -3599, -14452, -452, -54, 181, + 1074, 362, 2152, -7212, -64, -380, 1276, 2557, + 2777, -1173, 3984, 13079, 2508, -470, -84, -969, + -10440, -384, 198, -675, 285, -2217, 936, -3180, + -425, 179, -610, -2002, -1879, 1771, -2684, 16705, + 1833, -215, -191, -439, -17032, -205, 203, -308, + 290, 1916, -1805, 2736, 210, -198, 300, -1869, + 1052, 4495, 15519, 1467, -4032, -67, -1233, -14700, + -131, -992, -288, -997, -4257, -94, -402, -1389, + 259, 1106, 3819, 361, 3010, 2544, 6969, 7559, + 1996, -553, -395, -2964, -3487, -243, -467, -1280, + -1082, -1388, -1174, -3215, -366, -310, -849, -921, + -5209, -1867, 8713, 10351, 1549, -1656, -212, -4634, + -6540, -146, -593, 2770, 993, 3291, 1180, -5505, + 492, 176, -824, -979, -4314, 8513, 913, 7547, + -2723, -1135, -4423, -50, -3476, -452, 2241, 240, + -474, 1987, -3921, -420, -717, 1415, 151, 1254, + 12929, -1219, 2448, 1757, 6303, -10204, -90, -365, + -188, -2425, 962, -1932, 182, -1386, 130, -262, + -4974, 469, -941, -676, 6465, 4132, 3167, 3160, + 5697, -2551, -1042, -612, -609, -1981, -1630, -1249, + -798, -1247, -797, -611, -2248, -1437, -1101, -1099, + -3636, 4859, 18914, -1335, 810, -807, -1441, -21836, + -108, -40, 1078, 4198, -5609, -296, 396, 1541, + 179, -240, -936, 66, 8844, 7864, 654, -4063, + -5680, -4774, -3774, -26, -1007, -1969, -4245, -353, + -314, 2193, 1950, 162, 3066, 2726, 226, -1408, + 1859, 2634, 9228, 996, 9464, -211, -423, -5197, + -60, -5467, -299, -1047, -1483, -113, -160, -561, + -1074, -1521, -5330, -575, 2949, 12260, 10290, -497, + -3943, -530, -9174, -6463, -15, -949, -2206, -1852, + -7700, 89, 372, 312, 709, 2950, 2476, -119, + -2903, 1552, 14867, 9970, -496, -514, -147, -13491, + -6068, -15, 275, 2634, -1408, 1766, -944, -9047, + -87, 47, 450, 302, 3243, 8234, 7586, 3373, + 2151, -642, -4138, -3512, -694, -282, -1630, -1501, + -3812, -667, -1695, -1561, -425, -1081, -996, -442, + -9631, 60, 3501, 5359, 10150, -5662, 0, -748, + -1752, -6288, 35, 2058, -12, 3150, -19, -1145, + 5967, -37, -2169, -3320, -6874, -2553, -5446, -2195, + -7841, -2884, -397, -1810, -294, -3753, -1071, -2285, + -848, -921, -342, -729, -3290, -1221, -2606, -1050, + -3413, -1141, 4630, 13612, 7897, -711, -79, -1308, + -11310, -3806, -237, 964, 322, 2836, 948, -3847, + 1645, 550, -2231, -6561, 4410, -5678, 8006, -3992, + 3811, -1187, -1968, -3912, -973, -886, 1528, -2155, + 2775, 1074, -1383, 1951, -1025, 1321, -1862, 928, + 5659, 11535, 2203, -452, 7169, -1954, -8121, -296, + -12, -3137, -3984, -761, -1551, 156, 318, 60, + -2476, -5048, -964, 197, 2914, -2914, 3485, -3965, + 13675, -518, -518, -741, -959, -11414, 518, -620, + 620, 705, -705, 843, -2433, 2432, -2909, 3310, + 7843, 1907, 1022, 8882, 7972, -3755, -222, -63, + -4815, -3879, -913, -489, -119, -4252, -1034, -554, + -3816, -928, -497, -4322, 13807, 9531, 1436, 1612, + 1779, -11636, -5544, -125, -158, -193, -8032, -1210, + -835, -1358, -938, -141, -1499, -1035, -156, -175, + 13620, -5337, 5450, -2263, 1723, -11322, -1738, -1813, + -312, -181, 4436, -4531, 1775, 1881, -737, 752, + -1432, 561, -573, 238, 5297, 8374, 8872, 7694, + 6538, -1712, -4280, -4804, -3613, -2609, -2707, -2868, + -4534, -2487, -3932, -4166, -2113, -3341, -3540, -3070 +}; + +/** + * 0.65^i (Zero part) and 0.75^i (Pole part) scaled by 2^15 + */ +static const int16_t postfilter_tbl[2][LPC_ORDER] = { + /* Zero */ + {21299, 13844, 8999, 5849, 3802, 2471, 1606, 1044, 679, 441}, + /* Pole */ + {24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845} +}; + +/** + * Hamming window coefficients scaled by 2^15 + */ +static const int16_t hamming_window[LPC_FRAME] = { + 2621, 2631, 2659, 2705, 2770, 2853, 2955, 3074, 3212, 3367, + 3541, 3731, 3939, 4164, 4405, 4663, 4937, 5226, 5531, 5851, + 6186, 6534, 6897, 7273, 7661, 8062, 8475, 8899, 9334, 9780, + 10235, 10699, 11172, 11653, 12141, 12636, 13138, 13645, 14157, 14673, + 15193, 15716, 16242, 16769, 17298, 17827, 18356, 18884, 19411, 19935, + 20457, 20975, 21489, 21999, 22503, 23002, 23494, 23978, 24455, 24924, + 25384, 25834, 26274, 26704, 27122, 27529, 27924, 28306, 28675, 29031, + 29373, 29700, 30012, 30310, 30592, 30857, 31107, 31340, 31557, 31756, + 31938, 32102, 32249, 32377, 32488, 32580, 32654, 32710, 32747, 32766, + 32766, 32747, 32710, 32654, 32580, 32488, 32377, 32249, 32102, 31938, + 31756, 31557, 31340, 31107, 30857, 30592, 30310, 30012, 29700, 29373, + 29031, 28675, 28306, 27924, 27529, 27122, 26704, 26274, 25834, 25384, + 24924, 24455, 23978, 23494, 23002, 22503, 21999, 21489, 20975, 20457, + 19935, 19411, 18884, 18356, 17827, 17298, 16769, 16242, 15716, 15193, + 14673, 14157, 13645, 13138, 12636, 12141, 11653, 11172, 10699, 10235, + 9780, 9334, 8899, 8475, 8062, 7661, 7273, 6897, 6534, 6186, + 5851, 5531, 5226, 4937, 4663, 4405, 4164, 3939, 3731, 3541, + 3367, 3212, 3074, 2955, 2853, 2770, 2705, 2659, 2631, 2621 +}; + +/** + * Binomial window coefficients scaled by 2^15 + */ +static const int16_t binomial_window[LPC_ORDER] = { + 32749, 32695, 32604, 32477, 32315, 32118, 31887, 31622, 31324, 30995 +}; + +/** + * 0.994^i scaled by 2^15 + */ +static const int16_t bandwidth_expand[LPC_ORDER] = { + 32571, 32376, 32182, 31989, 31797, 31606, 31416, 31228, 31040, 30854 +}; + +/** + * 0.5^i scaled by 2^15 + */ +static const int16_t percept_flt_tbl[2][LPC_ORDER] = { + /* Zero part */ + {29491, 26542, 23888, 21499, 19349, 17414, 15673, 14106, 12695, 11425}, + /* Pole part */ + {16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32} +}; + +static const int cng_adaptive_cb_lag[4] = { 1, 0, 1, 3 }; + +static const int cng_filt[4] = { 273, 998, 499, 333 }; + +static const int cng_bseg[3] = { 2048, 18432, 231233 }; + +#endif /* AVCODEC_G723_1_DATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g726.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g726.c new file mode 100644 index 000000000..6de3be629 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g726.c @@ -0,0 +1,473 @@ +/* + * G.726 ADPCM audio codec + * Copyright (c) 2004 Roman Shaposhnik + * + * This is a very straightforward rendition of the G.726 + * Section 4 "Computational Details". + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + +#include "libavutil/avassert.h" +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "libavutil/internal.h" +#include "avcodec.h" +#include "internal.h" +#include "get_bits.h" +#include "put_bits.h" + +/** + * G.726 11bit float. + * G.726 Standard uses rather odd 11bit floating point arithmentic for + * numerous occasions. It's a mystery to me why they did it this way + * instead of simply using 32bit integer arithmetic. + */ +typedef struct Float11 { + uint8_t sign; /**< 1bit sign */ + uint8_t exp; /**< 4bit exponent */ + uint8_t mant; /**< 6bit mantissa */ +} Float11; + +static inline Float11* i2f(int i, Float11* f) +{ + f->sign = (i < 0); + if (f->sign) + i = -i; + f->exp = av_log2_16bit(i) + !!i; + f->mant = i? (i<<6) >> f->exp : 1<<5; + return f; +} + +static inline int16_t mult(Float11* f1, Float11* f2) +{ + int res, exp; + + exp = f1->exp + f2->exp; + res = (((f1->mant * f2->mant) + 0x30) >> 4); + res = exp > 19 ? res << (exp - 19) : res >> (19 - exp); + return (f1->sign ^ f2->sign) ? -res : res; +} + +static inline int sgn(int value) +{ + return (value < 0) ? -1 : 1; +} + +typedef struct G726Tables { + const int* quant; /**< quantization table */ + const int16_t* iquant; /**< inverse quantization table */ + const int16_t* W; /**< special table #1 ;-) */ + const uint8_t* F; /**< special table #2 */ +} G726Tables; + +typedef struct G726Context { + AVClass *class; + G726Tables tbls; /**< static tables needed for computation */ + + Float11 sr[2]; /**< prev. reconstructed samples */ + Float11 dq[6]; /**< prev. difference */ + int a[2]; /**< second order predictor coeffs */ + int b[6]; /**< sixth order predictor coeffs */ + int pk[2]; /**< signs of prev. 2 sez + dq */ + + int ap; /**< scale factor control */ + int yu; /**< fast scale factor */ + int yl; /**< slow scale factor */ + int dms; /**< short average magnitude of F[i] */ + int dml; /**< long average magnitude of F[i] */ + int td; /**< tone detect */ + + int se; /**< estimated signal for the next iteration */ + int sez; /**< estimated second order prediction */ + int y; /**< quantizer scaling factor for the next iteration */ + int code_size; +} G726Context; + +static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ + { 260, INT_MAX }; +static const int16_t iquant_tbl16[] = + { 116, 365, 365, 116 }; +static const int16_t W_tbl16[] = + { -22, 439, 439, -22 }; +static const uint8_t F_tbl16[] = + { 0, 7, 7, 0 }; + +static const int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ + { 7, 217, 330, INT_MAX }; +static const int16_t iquant_tbl24[] = + { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN }; +static const int16_t W_tbl24[] = + { -4, 30, 137, 582, 582, 137, 30, -4 }; +static const uint8_t F_tbl24[] = + { 0, 1, 2, 7, 7, 2, 1, 0 }; + +static const int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ + { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; +static const int16_t iquant_tbl32[] = + { INT16_MIN, 4, 135, 213, 273, 323, 373, 425, + 425, 373, 323, 273, 213, 135, 4, INT16_MIN }; +static const int16_t W_tbl32[] = + { -12, 18, 41, 64, 112, 198, 355, 1122, + 1122, 355, 198, 112, 64, 41, 18, -12}; +static const uint8_t F_tbl32[] = + { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; + +static const int quant_tbl40[] = /**< 40kbit/s 5bits per sample */ + { -122, -16, 67, 138, 197, 249, 297, 338, + 377, 412, 444, 474, 501, 527, 552, INT_MAX }; +static const int16_t iquant_tbl40[] = + { INT16_MIN, -66, 28, 104, 169, 224, 274, 318, + 358, 395, 429, 459, 488, 514, 539, 566, + 566, 539, 514, 488, 459, 429, 395, 358, + 318, 274, 224, 169, 104, 28, -66, INT16_MIN }; +static const int16_t W_tbl40[] = + { 14, 14, 24, 39, 40, 41, 58, 100, + 141, 179, 219, 280, 358, 440, 529, 696, + 696, 529, 440, 358, 280, 219, 179, 141, + 100, 58, 41, 40, 39, 24, 14, 14 }; +static const uint8_t F_tbl40[] = + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, + 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + +static const G726Tables G726Tables_pool[] = + {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, + { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, + { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, + { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }}; + + +/** + * Para 4.2.2 page 18: Adaptive quantizer. + */ +static inline uint8_t quant(G726Context* c, int d) +{ + int sign, exp, i, dln; + + sign = i = 0; + if (d < 0) { + sign = 1; + d = -d; + } + exp = av_log2_16bit(d); + dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2); + + while (c->tbls.quant[i] < INT_MAX && c->tbls.quant[i] < dln) + ++i; + + if (sign) + i = ~i; + if (c->code_size != 2 && i == 0) /* I'm not sure this is a good idea */ + i = 0xff; + + return i; +} + +/** + * Para 4.2.3 page 22: Inverse adaptive quantizer. + */ +static inline int16_t inverse_quant(G726Context* c, int i) +{ + int dql, dex, dqt; + + dql = c->tbls.iquant[i] + (c->y >> 2); + dex = (dql>>7) & 0xf; /* 4bit exponent */ + dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */ + return (dql < 0) ? 0 : ((dqt<> 7); +} + +static int16_t g726_decode(G726Context* c, int I) +{ + int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0; + Float11 f; + int I_sig= I >> (c->code_size - 1); + + dq = inverse_quant(c, I); + + /* Transition detect */ + ylint = (c->yl >> 15); + ylfrac = (c->yl >> 10) & 0x1f; + thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint; + tr= (c->td == 1 && dq > ((3*thr2)>>2)); + + if (I_sig) /* get the sign */ + dq = -dq; + re_signal = c->se + dq; + + /* Update second order predictor coefficient A2 and A1 */ + pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0; + dq0 = dq ? sgn(dq) : 0; + if (tr) { + c->a[0] = 0; + c->a[1] = 0; + for (i=0; i<6; i++) + c->b[i] = 0; + } else { + /* This is a bit crazy, but it really is +255 not +256 */ + fa1 = av_clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255); + + c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7); + c->a[1] = av_clip(c->a[1], -12288, 12288); + c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8); + c->a[0] = av_clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]); + + for (i=0; i<6; i++) + c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8); + } + + /* Update Dq and Sr and Pk */ + c->pk[1] = c->pk[0]; + c->pk[0] = pk0 ? pk0 : 1; + c->sr[1] = c->sr[0]; + i2f(re_signal, &c->sr[0]); + for (i=5; i>0; i--) + c->dq[i] = c->dq[i-1]; + i2f(dq, &c->dq[0]); + c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */ + + c->td = c->a[1] < -11776; + + /* Update Ap */ + c->dms += (c->tbls.F[I]<<4) + ((- c->dms) >> 5); + c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7); + if (tr) + c->ap = 256; + else { + c->ap += (-c->ap) >> 4; + if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3)) + c->ap += 0x20; + } + + /* Update Yu and Yl */ + c->yu = av_clip(c->y + c->tbls.W[I] + ((-c->y)>>5), 544, 5120); + c->yl += c->yu + ((-c->yl)>>6); + + /* Next iteration for Y */ + al = (c->ap >= 256) ? 1<<6 : c->ap >> 2; + c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6; + + /* Next iteration for SE and SEZ */ + c->se = 0; + for (i=0; i<6; i++) + c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]); + c->sez = c->se >> 1; + for (i=0; i<2; i++) + c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]); + c->se >>= 1; + + return av_clip(re_signal << 2, -0xffff, 0xffff); +} + +static av_cold int g726_reset(G726Context *c) +{ + int i; + + c->tbls = G726Tables_pool[c->code_size - 2]; + for (i=0; i<2; i++) { + c->sr[i].mant = 1<<5; + c->pk[i] = 1; + } + for (i=0; i<6; i++) { + c->dq[i].mant = 1<<5; + } + c->yu = 544; + c->yl = 34816; + + c->y = 544; + + return 0; +} + +#if CONFIG_ADPCM_G726_ENCODER +static int16_t g726_encode(G726Context* c, int16_t sig) +{ + uint8_t i; + + i = quant(c, sig/4 - c->se) & ((1<code_size) - 1); + g726_decode(c, i); + return i; +} + +/* Interfacing to the libavcodec */ + +static av_cold int g726_encode_init(AVCodecContext *avctx) +{ + G726Context* c = avctx->priv_data; + + if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && + avctx->sample_rate != 8000) { + av_log(avctx, AV_LOG_ERROR, "Sample rates other than 8kHz are not " + "allowed when the compliance level is higher than unofficial. " + "Resample or reduce the compliance level.\n"); + return AVERROR(EINVAL); + } + av_assert0(avctx->sample_rate > 0); + + if(avctx->channels != 1){ + av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); + return AVERROR(EINVAL); + } + + if (avctx->bit_rate) + c->code_size = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate; + + c->code_size = av_clip(c->code_size, 2, 5); + avctx->bit_rate = c->code_size * avctx->sample_rate; + avctx->bits_per_coded_sample = c->code_size; + + g726_reset(c); + + /* select a frame size that will end on a byte boundary and have a size of + approximately 1024 bytes */ + avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[c->code_size - 2]; + + return 0; +} + +static int g726_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + G726Context *c = avctx->priv_data; + const int16_t *samples = (const int16_t *)frame->data[0]; + PutBitContext pb; + int i, ret, out_size; + + out_size = (frame->nb_samples * c->code_size + 7) / 8; + if ((ret = ff_alloc_packet2(avctx, avpkt, out_size)) < 0) + return ret; + init_put_bits(&pb, avpkt->data, avpkt->size); + + for (i = 0; i < frame->nb_samples; i++) + put_bits(&pb, c->code_size, g726_encode(c, *samples++)); + + flush_put_bits(&pb); + + avpkt->size = out_size; + *got_packet_ptr = 1; + return 0; +} + +#define OFFSET(x) offsetof(G726Context, x) +#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "code_size", "Bits per code", OFFSET(code_size), AV_OPT_TYPE_INT, { .i64 = 4 }, 2, 5, AE }, + { NULL }, +}; + +static const AVClass g726_class = { + .class_name = "g726", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVCodecDefault defaults[] = { + { "b", "0" }, + { NULL }, +}; + +AVCodec ff_adpcm_g726_encoder = { + .name = "g726", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ADPCM_G726, + .priv_data_size = sizeof(G726Context), + .init = g726_encode_init, + .encode2 = g726_encode_frame, + .capabilities = CODEC_CAP_SMALL_LAST_FRAME, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }, + .priv_class = &g726_class, + .defaults = defaults, +}; +#endif + +#if CONFIG_ADPCM_G726_DECODER +static av_cold int g726_decode_init(AVCodecContext *avctx) +{ + G726Context* c = avctx->priv_data; + + if(avctx->channels > 1){ + avpriv_request_sample(avctx, "Decoding more than one channel"); + return AVERROR_PATCHWELCOME; + } + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + + c->code_size = avctx->bits_per_coded_sample; + if (c->code_size < 2 || c->code_size > 5) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size); + return AVERROR(EINVAL); + } + g726_reset(c); + + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + return 0; +} + +static int g726_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + G726Context *c = avctx->priv_data; + int16_t *samples; + GetBitContext gb; + int out_samples, ret; + + out_samples = buf_size * 8 / c->code_size; + + /* get output buffer */ + frame->nb_samples = out_samples; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + samples = (int16_t *)frame->data[0]; + + init_get_bits(&gb, buf, buf_size * 8); + + while (out_samples--) + *samples++ = g726_decode(c, get_bits(&gb, c->code_size)); + + if (get_bits_left(&gb) > 0) + av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n"); + + *got_frame_ptr = 1; + + return buf_size; +} + +static void g726_decode_flush(AVCodecContext *avctx) +{ + G726Context *c = avctx->priv_data; + g726_reset(c); +} + +AVCodec ff_adpcm_g726_decoder = { + .name = "g726", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ADPCM_G726, + .priv_data_size = sizeof(G726Context), + .init = g726_decode_init, + .decode = g726_decode_frame, + .flush = g726_decode_flush, + .capabilities = CODEC_CAP_DR1, +}; +#endif diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729.h new file mode 100644 index 000000000..61683130a --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729.h @@ -0,0 +1,29 @@ +/* + * G.729, G729 Annex D decoders + * Copyright (c) 2008 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVCODEC_G729_H +#define AVCODEC_G729_H + +/** + * subframe size + */ +#define SUBFRAME_SIZE 40 + +#endif // AVCODEC_G729_H diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729data.h new file mode 100644 index 000000000..365ca47ec --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729data.h @@ -0,0 +1,382 @@ +/* + * data for G.729, G729 Annex D decoders + * Copyright (c) 2007 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_G729DATA_H +#define AVCODEC_G729DATA_H + +#include + +#define MA_NP 4 ///< Moving Average (MA) prediction order + +#define VQ_1ST_BITS 7 ///< first stage vector of quantizer (size in bits) +#define VQ_2ND_BITS 5 ///< second stage vector of quantizer (size in bits) + +#define GC_1ST_IDX_BITS_8K 3 ///< gain codebook (first stage) index, 8k mode (size in bits) +#define GC_2ND_IDX_BITS_8K 4 ///< gain codebook (second stage) index, 8k mode (size in bits) + +#define GC_1ST_IDX_BITS_6K4 3 ///< gain codebook (first stage) index, 6.4k mode (size in bits) +#define GC_2ND_IDX_BITS_6K4 3 ///< gain codebook (second stage) index, 6.4k mode (size in bits) + +/** + * first stage LSP codebook + * (10-dimensional, with 128 entries (3.24 of G.729) + */ +static const int16_t cb_lsp_1st[1< +#include + +#include "avcodec.h" +#include "libavutil/avutil.h" +#include "get_bits.h" +#include "dsputil.h" +#include "internal.h" + + +#include "g729.h" +#include "lsp.h" +#include "celp_math.h" +#include "celp_filters.h" +#include "acelp_filters.h" +#include "acelp_pitch_delay.h" +#include "acelp_vectors.h" +#include "g729data.h" +#include "g729postfilter.h" + +/** + * minimum quantized LSF value (3.2.4) + * 0.005 in Q13 + */ +#define LSFQ_MIN 40 + +/** + * maximum quantized LSF value (3.2.4) + * 3.135 in Q13 + */ +#define LSFQ_MAX 25681 + +/** + * minimum LSF distance (3.2.4) + * 0.0391 in Q13 + */ +#define LSFQ_DIFF_MIN 321 + +/// interpolation filter length +#define INTERPOL_LEN 11 + +/** + * minimum gain pitch value (3.8, Equation 47) + * 0.2 in (1.14) + */ +#define SHARP_MIN 3277 + +/** + * maximum gain pitch value (3.8, Equation 47) + * (EE) This does not comply with the specification. + * Specification says about 0.8, which should be + * 13107 in (1.14), but reference C code uses + * 13017 (equals to 0.7945) instead of it. + */ +#define SHARP_MAX 13017 + +/** + * MR_ENERGY (mean removed energy) = mean_energy + 10 * log10(2^26 * subframe_size) in (7.13) + */ +#define MR_ENERGY 1018156 + +#define DECISION_NOISE 0 +#define DECISION_INTERMEDIATE 1 +#define DECISION_VOICE 2 + +typedef enum { + FORMAT_G729_8K = 0, + FORMAT_G729D_6K4, + FORMAT_COUNT, +} G729Formats; + +typedef struct { + uint8_t ac_index_bits[2]; ///< adaptive codebook index for second subframe (size in bits) + uint8_t parity_bit; ///< parity bit for pitch delay + uint8_t gc_1st_index_bits; ///< gain codebook (first stage) index (size in bits) + uint8_t gc_2nd_index_bits; ///< gain codebook (second stage) index (size in bits) + uint8_t fc_signs_bits; ///< number of pulses in fixed-codebook vector + uint8_t fc_indexes_bits; ///< size (in bits) of fixed-codebook index entry +} G729FormatDescription; + +typedef struct { + DSPContext dsp; + + /// past excitation signal buffer + int16_t exc_base[2*SUBFRAME_SIZE+PITCH_DELAY_MAX+INTERPOL_LEN]; + + int16_t* exc; ///< start of past excitation data in buffer + int pitch_delay_int_prev; ///< integer part of previous subframe's pitch delay (4.1.3) + + /// (2.13) LSP quantizer outputs + int16_t past_quantizer_output_buf[MA_NP + 1][10]; + int16_t* past_quantizer_outputs[MA_NP + 1]; + + int16_t lsfq[10]; ///< (2.13) quantized LSF coefficients from previous frame + int16_t lsp_buf[2][10]; ///< (0.15) LSP coefficients (previous and current frames) (3.2.5) + int16_t *lsp[2]; ///< pointers to lsp_buf + + int16_t quant_energy[4]; ///< (5.10) past quantized energy + + /// previous speech data for LP synthesis filter + int16_t syn_filter_data[10]; + + + /// residual signal buffer (used in long-term postfilter) + int16_t residual[SUBFRAME_SIZE + RES_PREV_DATA_SIZE]; + + /// previous speech data for residual calculation filter + int16_t res_filter_data[SUBFRAME_SIZE+10]; + + /// previous speech data for short-term postfilter + int16_t pos_filter_data[SUBFRAME_SIZE+10]; + + /// (1.14) pitch gain of current and five previous subframes + int16_t past_gain_pitch[6]; + + /// (14.1) gain code from current and previous subframe + int16_t past_gain_code[2]; + + /// voice decision on previous subframe (0-noise, 1-intermediate, 2-voice), G.729D + int16_t voice_decision; + + int16_t onset; ///< detected onset level (0-2) + int16_t was_periodic; ///< whether previous frame was declared as periodic or not (4.4) + int16_t ht_prev_data; ///< previous data for 4.2.3, equation 86 + int gain_coeff; ///< (1.14) gain coefficient (4.2.4) + uint16_t rand_value; ///< random number generator value (4.4.4) + int ma_predictor_prev; ///< switched MA predictor of LSP quantizer from last good frame + + /// (14.14) high-pass filter data (past input) + int hpf_f[2]; + + /// high-pass filter data (past output) + int16_t hpf_z[2]; +} G729Context; + +static const G729FormatDescription format_g729_8k = { + .ac_index_bits = {8,5}, + .parity_bit = 1, + .gc_1st_index_bits = GC_1ST_IDX_BITS_8K, + .gc_2nd_index_bits = GC_2ND_IDX_BITS_8K, + .fc_signs_bits = 4, + .fc_indexes_bits = 13, +}; + +static const G729FormatDescription format_g729d_6k4 = { + .ac_index_bits = {8,4}, + .parity_bit = 0, + .gc_1st_index_bits = GC_1ST_IDX_BITS_6K4, + .gc_2nd_index_bits = GC_2ND_IDX_BITS_6K4, + .fc_signs_bits = 2, + .fc_indexes_bits = 9, +}; + +/** + * @brief pseudo random number generator + */ +static inline uint16_t g729_prng(uint16_t value) +{ + return 31821 * value + 13849; +} + +/** + * Get parity bit of bit 2..7 + */ +static inline int get_parity(uint8_t value) +{ + return (0x6996966996696996ULL >> (value >> 2)) & 1; +} + +/** + * Decodes LSF (Line Spectral Frequencies) from L0-L3 (3.2.4). + * @param[out] lsfq (2.13) quantized LSF coefficients + * @param[in,out] past_quantizer_outputs (2.13) quantizer outputs from previous frames + * @param ma_predictor switched MA predictor of LSP quantizer + * @param vq_1st first stage vector of quantizer + * @param vq_2nd_low second stage lower vector of LSP quantizer + * @param vq_2nd_high second stage higher vector of LSP quantizer + */ +static void lsf_decode(int16_t* lsfq, int16_t* past_quantizer_outputs[MA_NP + 1], + int16_t ma_predictor, + int16_t vq_1st, int16_t vq_2nd_low, int16_t vq_2nd_high) +{ + int i,j; + static const uint8_t min_distance[2]={10, 5}; //(2.13) + int16_t* quantizer_output = past_quantizer_outputs[MA_NP]; + + for (i = 0; i < 5; i++) { + quantizer_output[i] = cb_lsp_1st[vq_1st][i ] + cb_lsp_2nd[vq_2nd_low ][i ]; + quantizer_output[i + 5] = cb_lsp_1st[vq_1st][i + 5] + cb_lsp_2nd[vq_2nd_high][i + 5]; + } + + for (j = 0; j < 2; j++) { + for (i = 1; i < 10; i++) { + int diff = (quantizer_output[i - 1] - quantizer_output[i] + min_distance[j]) >> 1; + if (diff > 0) { + quantizer_output[i - 1] -= diff; + quantizer_output[i ] += diff; + } + } + } + + for (i = 0; i < 10; i++) { + int sum = quantizer_output[i] * cb_ma_predictor_sum[ma_predictor][i]; + for (j = 0; j < MA_NP; j++) + sum += past_quantizer_outputs[j][i] * cb_ma_predictor[ma_predictor][j][i]; + + lsfq[i] = sum >> 15; + } + + ff_acelp_reorder_lsf(lsfq, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX, 10); +} + +/** + * Restores past LSP quantizer output using LSF from previous frame + * @param[in,out] lsfq (2.13) quantized LSF coefficients + * @param[in,out] past_quantizer_outputs (2.13) quantizer outputs from previous frames + * @param ma_predictor_prev MA predictor from previous frame + * @param lsfq_prev (2.13) quantized LSF coefficients from previous frame + */ +static void lsf_restore_from_previous(int16_t* lsfq, + int16_t* past_quantizer_outputs[MA_NP + 1], + int ma_predictor_prev) +{ + int16_t* quantizer_output = past_quantizer_outputs[MA_NP]; + int i,k; + + for (i = 0; i < 10; i++) { + int tmp = lsfq[i] << 15; + + for (k = 0; k < MA_NP; k++) + tmp -= past_quantizer_outputs[k][i] * cb_ma_predictor[ma_predictor_prev][k][i]; + + quantizer_output[i] = ((tmp >> 15) * cb_ma_predictor_sum_inv[ma_predictor_prev][i]) >> 12; + } +} + +/** + * Constructs new excitation signal and applies phase filter to it + * @param[out] out constructed speech signal + * @param in original excitation signal + * @param fc_cur (2.13) original fixed-codebook vector + * @param gain_code (14.1) gain code + * @param subframe_size length of the subframe + */ +static void g729d_get_new_exc( + int16_t* out, + const int16_t* in, + const int16_t* fc_cur, + int dstate, + int gain_code, + int subframe_size) +{ + int i; + int16_t fc_new[SUBFRAME_SIZE]; + + ff_celp_convolve_circ(fc_new, fc_cur, phase_filter[dstate], subframe_size); + + for(i=0; i> 14; + out[i] += (gain_code * fc_new[i] + 0x2000) >> 14; + } +} + +/** + * Makes decision about onset in current subframe + * @param past_onset decision result of previous subframe + * @param past_gain_code gain code of current and previous subframe + * + * @return onset decision result for current subframe + */ +static int g729d_onset_decision(int past_onset, const int16_t* past_gain_code) +{ + if((past_gain_code[0] >> 1) > past_gain_code[1]) + return 2; + else + return FFMAX(past_onset-1, 0); +} + +/** + * Makes decision about voice presence in current subframe + * @param onset onset level + * @param prev_voice_decision voice decision result from previous subframe + * @param past_gain_pitch pitch gain of current and previous subframes + * + * @return voice decision result for current subframe + */ +static int16_t g729d_voice_decision(int onset, int prev_voice_decision, const int16_t* past_gain_pitch) +{ + int i, low_gain_pitch_cnt, voice_decision; + + if(past_gain_pitch[0] >= 14745) // 0.9 + voice_decision = DECISION_VOICE; + else if (past_gain_pitch[0] <= 9830) // 0.6 + voice_decision = DECISION_NOISE; + else + voice_decision = DECISION_INTERMEDIATE; + + for(i=0, low_gain_pitch_cnt=0; i<6; i++) + if(past_gain_pitch[i] < 9830) + low_gain_pitch_cnt++; + + if(low_gain_pitch_cnt > 2 && !onset) + voice_decision = DECISION_NOISE; + + if(!onset && voice_decision > prev_voice_decision + 1) + voice_decision--; + + if(onset && voice_decision < DECISION_VOICE) + voice_decision++; + + return voice_decision; +} + +static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int order) +{ + int res = 0; + + while (order--) + res += *v1++ * *v2++; + + return res; +} + +static av_cold int decoder_init(AVCodecContext * avctx) +{ + G729Context* ctx = avctx->priv_data; + int i,k; + + if (avctx->channels != 1) { + av_log(avctx, AV_LOG_ERROR, "Only mono sound is supported (requested channels: %d).\n", avctx->channels); + return AVERROR(EINVAL); + } + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + /* Both 8kbit/s and 6.4kbit/s modes uses two subframes per frame. */ + avctx->frame_size = SUBFRAME_SIZE << 1; + + ctx->gain_coeff = 16384; // 1.0 in (1.14) + + for (k = 0; k < MA_NP + 1; k++) { + ctx->past_quantizer_outputs[k] = ctx->past_quantizer_output_buf[k]; + for (i = 1; i < 11; i++) + ctx->past_quantizer_outputs[k][i - 1] = (18717 * i) >> 3; + } + + ctx->lsp[0] = ctx->lsp_buf[0]; + ctx->lsp[1] = ctx->lsp_buf[1]; + memcpy(ctx->lsp[0], lsp_init, 10 * sizeof(int16_t)); + + ctx->exc = &ctx->exc_base[PITCH_DELAY_MAX+INTERPOL_LEN]; + + ctx->pitch_delay_int_prev = PITCH_DELAY_MIN; + + /* random seed initialization */ + ctx->rand_value = 21845; + + /* quantized prediction error */ + for(i=0; i<4; i++) + ctx->quant_energy[i] = -14336; // -14 in (5.10) + + ff_dsputil_init(&ctx->dsp, avctx); + ctx->dsp.scalarproduct_int16 = scalarproduct_int16_c; + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, + AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int16_t *out_frame; + GetBitContext gb; + const G729FormatDescription *format; + int frame_erasure = 0; ///< frame erasure detected during decoding + int bad_pitch = 0; ///< parity check failed + int i; + int16_t *tmp; + G729Formats packet_type; + G729Context *ctx = avctx->priv_data; + int16_t lp[2][11]; // (3.12) + uint8_t ma_predictor; ///< switched MA predictor of LSP quantizer + uint8_t quantizer_1st; ///< first stage vector of quantizer + uint8_t quantizer_2nd_lo; ///< second stage lower vector of quantizer (size in bits) + uint8_t quantizer_2nd_hi; ///< second stage higher vector of quantizer (size in bits) + + int pitch_delay_int[2]; // pitch delay, integer part + int pitch_delay_3x; // pitch delay, multiplied by 3 + int16_t fc[SUBFRAME_SIZE]; // fixed-codebook vector + int16_t synth[SUBFRAME_SIZE+10]; // fixed-codebook vector + int j, ret; + int gain_before, gain_after; + int is_periodic = 0; // whether one of the subframes is declared as periodic or not + AVFrame *frame = data; + + frame->nb_samples = SUBFRAME_SIZE<<1; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + out_frame = (int16_t*) frame->data[0]; + + if (buf_size == 10) { + packet_type = FORMAT_G729_8K; + format = &format_g729_8k; + //Reset voice decision + ctx->onset = 0; + ctx->voice_decision = DECISION_VOICE; + av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729 @ 8kbit/s"); + } else if (buf_size == 8) { + packet_type = FORMAT_G729D_6K4; + format = &format_g729d_6k4; + av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729D @ 6.4kbit/s"); + } else { + av_log(avctx, AV_LOG_ERROR, "Packet size %d is unknown.\n", buf_size); + return AVERROR_INVALIDDATA; + } + + for (i=0; i < buf_size; i++) + frame_erasure |= buf[i]; + frame_erasure = !frame_erasure; + + init_get_bits(&gb, buf, 8*buf_size); + + ma_predictor = get_bits(&gb, 1); + quantizer_1st = get_bits(&gb, VQ_1ST_BITS); + quantizer_2nd_lo = get_bits(&gb, VQ_2ND_BITS); + quantizer_2nd_hi = get_bits(&gb, VQ_2ND_BITS); + + if(frame_erasure) + lsf_restore_from_previous(ctx->lsfq, ctx->past_quantizer_outputs, + ctx->ma_predictor_prev); + else { + lsf_decode(ctx->lsfq, ctx->past_quantizer_outputs, + ma_predictor, + quantizer_1st, quantizer_2nd_lo, quantizer_2nd_hi); + ctx->ma_predictor_prev = ma_predictor; + } + + tmp = ctx->past_quantizer_outputs[MA_NP]; + memmove(ctx->past_quantizer_outputs + 1, ctx->past_quantizer_outputs, + MA_NP * sizeof(int16_t*)); + ctx->past_quantizer_outputs[0] = tmp; + + ff_acelp_lsf2lsp(ctx->lsp[1], ctx->lsfq, 10); + + ff_acelp_lp_decode(&lp[0][0], &lp[1][0], ctx->lsp[1], ctx->lsp[0], 10); + + FFSWAP(int16_t*, ctx->lsp[1], ctx->lsp[0]); + + for (i = 0; i < 2; i++) { + int gain_corr_factor; + + uint8_t ac_index; ///< adaptive codebook index + uint8_t pulses_signs; ///< fixed-codebook vector pulse signs + int fc_indexes; ///< fixed-codebook indexes + uint8_t gc_1st_index; ///< gain codebook (first stage) index + uint8_t gc_2nd_index; ///< gain codebook (second stage) index + + ac_index = get_bits(&gb, format->ac_index_bits[i]); + if(!i && format->parity_bit) + bad_pitch = get_parity(ac_index) == get_bits1(&gb); + fc_indexes = get_bits(&gb, format->fc_indexes_bits); + pulses_signs = get_bits(&gb, format->fc_signs_bits); + gc_1st_index = get_bits(&gb, format->gc_1st_index_bits); + gc_2nd_index = get_bits(&gb, format->gc_2nd_index_bits); + + if (frame_erasure) + pitch_delay_3x = 3 * ctx->pitch_delay_int_prev; + else if(!i) { + if (bad_pitch) + pitch_delay_3x = 3 * ctx->pitch_delay_int_prev; + else + pitch_delay_3x = ff_acelp_decode_8bit_to_1st_delay3(ac_index); + } else { + int pitch_delay_min = av_clip(ctx->pitch_delay_int_prev - 5, + PITCH_DELAY_MIN, PITCH_DELAY_MAX - 9); + + if(packet_type == FORMAT_G729D_6K4) + pitch_delay_3x = ff_acelp_decode_4bit_to_2nd_delay3(ac_index, pitch_delay_min); + else + pitch_delay_3x = ff_acelp_decode_5_6_bit_to_2nd_delay3(ac_index, pitch_delay_min); + } + + /* Round pitch delay to nearest (used everywhere except ff_acelp_interpolate). */ + pitch_delay_int[i] = (pitch_delay_3x + 1) / 3; + if (pitch_delay_int[i] > PITCH_DELAY_MAX) { + av_log(avctx, AV_LOG_WARNING, "pitch_delay_int %d is too large\n", pitch_delay_int[i]); + pitch_delay_int[i] = PITCH_DELAY_MAX; + } + + if (frame_erasure) { + ctx->rand_value = g729_prng(ctx->rand_value); + fc_indexes = ctx->rand_value & ((1 << format->fc_indexes_bits) - 1); + + ctx->rand_value = g729_prng(ctx->rand_value); + pulses_signs = ctx->rand_value; + } + + + memset(fc, 0, sizeof(int16_t) * SUBFRAME_SIZE); + switch (packet_type) { + case FORMAT_G729_8K: + ff_acelp_fc_pulse_per_track(fc, ff_fc_4pulses_8bits_tracks_13, + ff_fc_4pulses_8bits_track_4, + fc_indexes, pulses_signs, 3, 3); + break; + case FORMAT_G729D_6K4: + ff_acelp_fc_pulse_per_track(fc, ff_fc_2pulses_9bits_track1_gray, + ff_fc_2pulses_9bits_track2_gray, + fc_indexes, pulses_signs, 1, 4); + break; + + default: break; + } + + /* + This filter enhances harmonic components of the fixed-codebook vector to + improve the quality of the reconstructed speech. + + / fc_v[i], i < pitch_delay + fc_v[i] = < + \ fc_v[i] + gain_pitch * fc_v[i-pitch_delay], i >= pitch_delay + */ + ff_acelp_weighted_vector_sum(fc + pitch_delay_int[i], + fc + pitch_delay_int[i], + fc, 1 << 14, + av_clip(ctx->past_gain_pitch[0], SHARP_MIN, SHARP_MAX), + 0, 14, + SUBFRAME_SIZE - pitch_delay_int[i]); + + memmove(ctx->past_gain_pitch+1, ctx->past_gain_pitch, 5 * sizeof(int16_t)); + ctx->past_gain_code[1] = ctx->past_gain_code[0]; + + if (frame_erasure) { + ctx->past_gain_pitch[0] = (29491 * ctx->past_gain_pitch[0]) >> 15; // 0.90 (0.15) + ctx->past_gain_code[0] = ( 2007 * ctx->past_gain_code[0] ) >> 11; // 0.98 (0.11) + + gain_corr_factor = 0; + } else { + if (packet_type == FORMAT_G729D_6K4) { + ctx->past_gain_pitch[0] = cb_gain_1st_6k4[gc_1st_index][0] + + cb_gain_2nd_6k4[gc_2nd_index][0]; + gain_corr_factor = cb_gain_1st_6k4[gc_1st_index][1] + + cb_gain_2nd_6k4[gc_2nd_index][1]; + + /* Without check below overflow can occur in ff_acelp_update_past_gain. + It is not issue for G.729, because gain_corr_factor in it's case is always + greater than 1024, while in G.729D it can be even zero. */ + gain_corr_factor = FFMAX(gain_corr_factor, 1024); +#ifndef G729_BITEXACT + gain_corr_factor >>= 1; +#endif + } else { + ctx->past_gain_pitch[0] = cb_gain_1st_8k[gc_1st_index][0] + + cb_gain_2nd_8k[gc_2nd_index][0]; + gain_corr_factor = cb_gain_1st_8k[gc_1st_index][1] + + cb_gain_2nd_8k[gc_2nd_index][1]; + } + + /* Decode the fixed-codebook gain. */ + ctx->past_gain_code[0] = ff_acelp_decode_gain_code(&ctx->dsp, gain_corr_factor, + fc, MR_ENERGY, + ctx->quant_energy, + (const int16_t *) ma_prediction_coeff, + SUBFRAME_SIZE, 4); +#ifdef G729_BITEXACT + /* + This correction required to get bit-exact result with + reference code, because gain_corr_factor in G.729D is + two times larger than in original G.729. + + If bit-exact result is not issue then gain_corr_factor + can be simpler divided by 2 before call to g729_get_gain_code + instead of using correction below. + */ + if (packet_type == FORMAT_G729D_6K4) { + gain_corr_factor >>= 1; + ctx->past_gain_code[0] >>= 1; + } +#endif + } + ff_acelp_update_past_gain(ctx->quant_energy, gain_corr_factor, 2, frame_erasure); + + /* Routine requires rounding to lowest. */ + ff_acelp_interpolate(ctx->exc + i * SUBFRAME_SIZE, + ctx->exc + i * SUBFRAME_SIZE - pitch_delay_3x / 3, + ff_acelp_interp_filter, 6, + (pitch_delay_3x % 3) << 1, + 10, SUBFRAME_SIZE); + + ff_acelp_weighted_vector_sum(ctx->exc + i * SUBFRAME_SIZE, + ctx->exc + i * SUBFRAME_SIZE, fc, + (!ctx->was_periodic && frame_erasure) ? 0 : ctx->past_gain_pitch[0], + ( ctx->was_periodic && frame_erasure) ? 0 : ctx->past_gain_code[0], + 1 << 13, 14, SUBFRAME_SIZE); + + memcpy(synth, ctx->syn_filter_data, 10 * sizeof(int16_t)); + + if (ff_celp_lp_synthesis_filter( + synth+10, + &lp[i][1], + ctx->exc + i * SUBFRAME_SIZE, + SUBFRAME_SIZE, + 10, + 1, + 0, + 0x800)) + /* Overflow occurred, downscale excitation signal... */ + for (j = 0; j < 2 * SUBFRAME_SIZE + PITCH_DELAY_MAX + INTERPOL_LEN; j++) + ctx->exc_base[j] >>= 2; + + /* ... and make synthesis again. */ + if (packet_type == FORMAT_G729D_6K4) { + int16_t exc_new[SUBFRAME_SIZE]; + + ctx->onset = g729d_onset_decision(ctx->onset, ctx->past_gain_code); + ctx->voice_decision = g729d_voice_decision(ctx->onset, ctx->voice_decision, ctx->past_gain_pitch); + + g729d_get_new_exc(exc_new, ctx->exc + i * SUBFRAME_SIZE, fc, ctx->voice_decision, ctx->past_gain_code[0], SUBFRAME_SIZE); + + ff_celp_lp_synthesis_filter( + synth+10, + &lp[i][1], + exc_new, + SUBFRAME_SIZE, + 10, + 0, + 0, + 0x800); + } else { + ff_celp_lp_synthesis_filter( + synth+10, + &lp[i][1], + ctx->exc + i * SUBFRAME_SIZE, + SUBFRAME_SIZE, + 10, + 0, + 0, + 0x800); + } + /* Save data (without postfilter) for use in next subframe. */ + memcpy(ctx->syn_filter_data, synth+SUBFRAME_SIZE, 10 * sizeof(int16_t)); + + /* Calculate gain of unfiltered signal for use in AGC. */ + gain_before = 0; + for (j = 0; j < SUBFRAME_SIZE; j++) + gain_before += FFABS(synth[j+10]); + + /* Call postfilter and also update voicing decision for use in next frame. */ + ff_g729_postfilter( + &ctx->dsp, + &ctx->ht_prev_data, + &is_periodic, + &lp[i][0], + pitch_delay_int[0], + ctx->residual, + ctx->res_filter_data, + ctx->pos_filter_data, + synth+10, + SUBFRAME_SIZE); + + /* Calculate gain of filtered signal for use in AGC. */ + gain_after = 0; + for(j=0; jgain_coeff = ff_g729_adaptive_gain_control( + gain_before, + gain_after, + synth+10, + SUBFRAME_SIZE, + ctx->gain_coeff); + + if (frame_erasure) + ctx->pitch_delay_int_prev = FFMIN(ctx->pitch_delay_int_prev + 1, PITCH_DELAY_MAX); + else + ctx->pitch_delay_int_prev = pitch_delay_int[i]; + + memcpy(synth+8, ctx->hpf_z, 2*sizeof(int16_t)); + ff_acelp_high_pass_filter( + out_frame + i*SUBFRAME_SIZE, + ctx->hpf_f, + synth+10, + SUBFRAME_SIZE); + memcpy(ctx->hpf_z, synth+8+SUBFRAME_SIZE, 2*sizeof(int16_t)); + } + + ctx->was_periodic = is_periodic; + + /* Save signal for use in next frame. */ + memmove(ctx->exc_base, ctx->exc_base + 2 * SUBFRAME_SIZE, (PITCH_DELAY_MAX+INTERPOL_LEN)*sizeof(int16_t)); + + *got_frame_ptr = 1; + return buf_size; +} + +AVCodec ff_g729_decoder = { + .name = "g729", + .long_name = NULL_IF_CONFIG_SMALL("G.729"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_G729, + .priv_data_size = sizeof(G729Context), + .init = decoder_init, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729postfilter.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729postfilter.c new file mode 100644 index 000000000..fc903740e --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729postfilter.c @@ -0,0 +1,610 @@ +/* + * G.729, G729 Annex D postfilter + * Copyright (c) 2008 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include + +#include "avcodec.h" +#include "g729.h" +#include "acelp_pitch_delay.h" +#include "g729postfilter.h" +#include "celp_math.h" +#include "acelp_filters.h" +#include "acelp_vectors.h" +#include "celp_filters.h" + +#define FRAC_BITS 15 +#include "mathops.h" + +/** + * short interpolation filter (of length 33, according to spec) + * for computing signal with non-integer delay + */ +static const int16_t ff_g729_interp_filt_short[(ANALYZED_FRAC_DELAYS+1)*SHORT_INT_FILT_LEN] = { + 0, 31650, 28469, 23705, 18050, 12266, 7041, 2873, + 0, -1597, -2147, -1992, -1492, -933, -484, -188, +}; + +/** + * long interpolation filter (of length 129, according to spec) + * for computing signal with non-integer delay + */ +static const int16_t ff_g729_interp_filt_long[(ANALYZED_FRAC_DELAYS+1)*LONG_INT_FILT_LEN] = { + 0, 31915, 29436, 25569, 20676, 15206, 9639, 4439, + 0, -3390, -5579, -6549, -6414, -5392, -3773, -1874, + 0, 1595, 2727, 3303, 3319, 2850, 2030, 1023, + 0, -887, -1527, -1860, -1876, -1614, -1150, -579, + 0, 501, 859, 1041, 1044, 892, 631, 315, + 0, -266, -453, -543, -538, -455, -317, -156, + 0, 130, 218, 258, 253, 212, 147, 72, + 0, -59, -101, -122, -123, -106, -77, -40, +}; + +/** + * formant_pp_factor_num_pow[i] = FORMANT_PP_FACTOR_NUM^(i+1) + */ +static const int16_t formant_pp_factor_num_pow[10]= { + /* (0.15) */ + 18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83 +}; + +/** + * formant_pp_factor_den_pow[i] = FORMANT_PP_FACTOR_DEN^(i+1) + */ +static const int16_t formant_pp_factor_den_pow[10] = { + /* (0.15) */ + 22938, 16057, 11240, 7868, 5508, 3856, 2699, 1889, 1322, 925 +}; + +/** + * \brief Residual signal calculation (4.2.1 if G.729) + * \param out [out] output data filtered through A(z/FORMANT_PP_FACTOR_NUM) + * \param filter_coeffs (3.12) A(z/FORMANT_PP_FACTOR_NUM) filter coefficients + * \param in input speech data to process + * \param subframe_size size of one subframe + * + * \note in buffer must contain 10 items of previous speech data before top of the buffer + * \remark It is safe to pass the same buffer for input and output. + */ +static void residual_filter(int16_t* out, const int16_t* filter_coeffs, const int16_t* in, + int subframe_size) +{ + int i, n; + + for (n = subframe_size - 1; n >= 0; n--) { + int sum = 0x800; + for (i = 0; i < 10; i++) + sum += filter_coeffs[i] * in[n - i - 1]; + + out[n] = in[n] + (sum >> 12); + } +} + +/** + * \brief long-term postfilter (4.2.1) + * \param dsp initialized DSP context + * \param pitch_delay_int integer part of the pitch delay in the first subframe + * \param residual filtering input data + * \param residual_filt [out] speech signal with applied A(z/FORMANT_PP_FACTOR_NUM) filter + * \param subframe_size size of subframe + * + * \return 0 if long-term prediction gain is less than 3dB, 1 - otherwise + */ +static int16_t long_term_filter(DSPContext *dsp, int pitch_delay_int, + const int16_t* residual, int16_t *residual_filt, + int subframe_size) +{ + int i, k, tmp, tmp2; + int sum; + int L_temp0; + int L_temp1; + int64_t L64_temp0; + int64_t L64_temp1; + int16_t shift; + int corr_int_num, corr_int_den; + + int ener; + int16_t sh_ener; + + int16_t gain_num,gain_den; //selected signal's gain numerator and denominator + int16_t sh_gain_num, sh_gain_den; + int gain_num_square; + + int16_t gain_long_num,gain_long_den; //filtered through long interpolation filter signal's gain numerator and denominator + int16_t sh_gain_long_num, sh_gain_long_den; + + int16_t best_delay_int, best_delay_frac; + + int16_t delayed_signal_offset; + int lt_filt_factor_a, lt_filt_factor_b; + + int16_t * selected_signal; + const int16_t * selected_signal_const; //Necessary to avoid compiler warning + + int16_t sig_scaled[SUBFRAME_SIZE + RES_PREV_DATA_SIZE]; + int16_t delayed_signal[ANALYZED_FRAC_DELAYS][SUBFRAME_SIZE+1]; + int corr_den[ANALYZED_FRAC_DELAYS][2]; + + tmp = 0; + for(i=0; i 0) + for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++) + sig_scaled[i] = residual[i] >> shift; + else + for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++) + sig_scaled[i] = residual[i] << -shift; + + /* Start of best delay searching code */ + gain_num = 0; + + ener = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE, + sig_scaled + RES_PREV_DATA_SIZE, + subframe_size); + if (ener) { + sh_ener = FFMAX(av_log2(ener) - 14, 0); + ener >>= sh_ener; + /* Search for best pitch delay. + + sum{ r(n) * r(k,n) ] }^2 + R'(k)^2 := ------------------------- + sum{ r(k,n) * r(k,n) } + + + R(T) := sum{ r(n) * r(n-T) ] } + + + where + r(n-T) is integer delayed signal with delay T + r(k,n) is non-integer delayed signal with integer delay best_delay + and fractional delay k */ + + /* Find integer delay best_delay which maximizes correlation R(T). + + This is also equals to numerator of R'(0), + since the fine search (second step) is done with 1/8 + precision around best_delay. */ + corr_int_num = 0; + best_delay_int = pitch_delay_int - 1; + for (i = pitch_delay_int - 1; i <= pitch_delay_int + 1; i++) { + sum = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE, + sig_scaled + RES_PREV_DATA_SIZE - i, + subframe_size); + if (sum > corr_int_num) { + corr_int_num = sum; + best_delay_int = i; + } + } + if (corr_int_num) { + /* Compute denominator of pseudo-normalized correlation R'(0). */ + corr_int_den = dsp->scalarproduct_int16(sig_scaled - best_delay_int + RES_PREV_DATA_SIZE, + sig_scaled - best_delay_int + RES_PREV_DATA_SIZE, + subframe_size); + + /* Compute signals with non-integer delay k (with 1/8 precision), + where k is in [0;6] range. + Entire delay is qual to best_delay+(k+1)/8 + This is archieved by applying an interpolation filter of + legth 33 to source signal. */ + for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) { + ff_acelp_interpolate(&delayed_signal[k][0], + &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int], + ff_g729_interp_filt_short, + ANALYZED_FRAC_DELAYS+1, + 8 - k - 1, + SHORT_INT_FILT_LEN, + subframe_size + 1); + } + + /* Compute denominator of pseudo-normalized correlation R'(k). + + corr_den[k][0] is square root of R'(k) denominator, for int(T) == int(T0) + corr_den[k][1] is square root of R'(k) denominator, for int(T) == int(T0)+1 + + Also compute maximum value of above denominators over all k. */ + tmp = corr_int_den; + for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) { + sum = dsp->scalarproduct_int16(&delayed_signal[k][1], + &delayed_signal[k][1], + subframe_size - 1); + corr_den[k][0] = sum + delayed_signal[k][0 ] * delayed_signal[k][0 ]; + corr_den[k][1] = sum + delayed_signal[k][subframe_size] * delayed_signal[k][subframe_size]; + + tmp = FFMAX3(tmp, corr_den[k][0], corr_den[k][1]); + } + + sh_gain_den = av_log2(tmp) - 14; + if (sh_gain_den >= 0) { + + sh_gain_num = FFMAX(sh_gain_den, sh_ener); + /* Loop through all k and find delay that maximizes + R'(k) correlation. + Search is done in [int(T0)-1; intT(0)+1] range + with 1/8 precision. */ + delayed_signal_offset = 1; + best_delay_frac = 0; + gain_den = corr_int_den >> sh_gain_den; + gain_num = corr_int_num >> sh_gain_num; + gain_num_square = gain_num * gain_num; + for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) { + for (i = 0; i < 2; i++) { + int16_t gain_num_short, gain_den_short; + int gain_num_short_square; + /* Compute numerator of pseudo-normalized + correlation R'(k). */ + sum = dsp->scalarproduct_int16(&delayed_signal[k][i], + sig_scaled + RES_PREV_DATA_SIZE, + subframe_size); + gain_num_short = FFMAX(sum >> sh_gain_num, 0); + + /* + gain_num_short_square gain_num_square + R'(T)^2 = -----------------------, max R'(T)^2= -------------- + den gain_den + */ + gain_num_short_square = gain_num_short * gain_num_short; + gain_den_short = corr_den[k][i] >> sh_gain_den; + + tmp = MULL(gain_num_short_square, gain_den, FRAC_BITS); + tmp2 = MULL(gain_num_square, gain_den_short, FRAC_BITS); + + // R'(T)^2 > max R'(T)^2 + if (tmp > tmp2) { + gain_num = gain_num_short; + gain_den = gain_den_short; + gain_num_square = gain_num_short_square; + delayed_signal_offset = i; + best_delay_frac = k + 1; + } + } + } + + /* + R'(T)^2 + 2 * --------- < 1 + R(0) + */ + L64_temp0 = (int64_t)gain_num_square << ((sh_gain_num << 1) + 1); + L64_temp1 = ((int64_t)gain_den * ener) << (sh_gain_den + sh_ener); + if (L64_temp0 < L64_temp1) + gain_num = 0; + } // if(sh_gain_den >= 0) + } // if(corr_int_num) + } // if(ener) + /* End of best delay searching code */ + + if (!gain_num) { + memcpy(residual_filt, residual + RES_PREV_DATA_SIZE, subframe_size * sizeof(int16_t)); + + /* Long-term prediction gain is less than 3dB. Long-term postfilter is disabled. */ + return 0; + } + if (best_delay_frac) { + /* Recompute delayed signal with an interpolation filter of length 129. */ + ff_acelp_interpolate(residual_filt, + &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int + delayed_signal_offset], + ff_g729_interp_filt_long, + ANALYZED_FRAC_DELAYS + 1, + 8 - best_delay_frac, + LONG_INT_FILT_LEN, + subframe_size + 1); + /* Compute R'(k) correlation's numerator. */ + sum = dsp->scalarproduct_int16(residual_filt, + sig_scaled + RES_PREV_DATA_SIZE, + subframe_size); + + if (sum < 0) { + gain_long_num = 0; + sh_gain_long_num = 0; + } else { + tmp = FFMAX(av_log2(sum) - 14, 0); + sum >>= tmp; + gain_long_num = sum; + sh_gain_long_num = tmp; + } + + /* Compute R'(k) correlation's denominator. */ + sum = dsp->scalarproduct_int16(residual_filt, residual_filt, subframe_size); + + tmp = FFMAX(av_log2(sum) - 14, 0); + sum >>= tmp; + gain_long_den = sum; + sh_gain_long_den = tmp; + + /* Select between original and delayed signal. + Delayed signal will be selected if it increases R'(k) + correlation. */ + L_temp0 = gain_num * gain_num; + L_temp0 = MULL(L_temp0, gain_long_den, FRAC_BITS); + + L_temp1 = gain_long_num * gain_long_num; + L_temp1 = MULL(L_temp1, gain_den, FRAC_BITS); + + tmp = ((sh_gain_long_num - sh_gain_num) << 1) - (sh_gain_long_den - sh_gain_den); + if (tmp > 0) + L_temp0 >>= tmp; + else + L_temp1 >>= -tmp; + + /* Check if longer filter increases the values of R'(k). */ + if (L_temp1 > L_temp0) { + /* Select long filter. */ + selected_signal = residual_filt; + gain_num = gain_long_num; + gain_den = gain_long_den; + sh_gain_num = sh_gain_long_num; + sh_gain_den = sh_gain_long_den; + } else + /* Select short filter. */ + selected_signal = &delayed_signal[best_delay_frac-1][delayed_signal_offset]; + + /* Rescale selected signal to original value. */ + if (shift > 0) + for (i = 0; i < subframe_size; i++) + selected_signal[i] <<= shift; + else + for (i = 0; i < subframe_size; i++) + selected_signal[i] >>= -shift; + + /* necessary to avoid compiler warning */ + selected_signal_const = selected_signal; + } // if(best_delay_frac) + else + selected_signal_const = residual + RES_PREV_DATA_SIZE - (best_delay_int + 1 - delayed_signal_offset); +#ifdef G729_BITEXACT + tmp = sh_gain_num - sh_gain_den; + if (tmp > 0) + gain_den >>= tmp; + else + gain_num >>= -tmp; + + if (gain_num > gain_den) + lt_filt_factor_a = MIN_LT_FILT_FACTOR_A; + else { + gain_num >>= 2; + gain_den >>= 1; + lt_filt_factor_a = (gain_den << 15) / (gain_den + gain_num); + } +#else + L64_temp0 = ((int64_t)gain_num) << (sh_gain_num - 1); + L64_temp1 = ((int64_t)gain_den) << sh_gain_den; + lt_filt_factor_a = FFMAX((L64_temp1 << 15) / (L64_temp1 + L64_temp0), MIN_LT_FILT_FACTOR_A); +#endif + + /* Filter through selected filter. */ + lt_filt_factor_b = 32767 - lt_filt_factor_a + 1; + + ff_acelp_weighted_vector_sum(residual_filt, residual + RES_PREV_DATA_SIZE, + selected_signal_const, + lt_filt_factor_a, lt_filt_factor_b, + 1<<14, 15, subframe_size); + + // Long-term prediction gain is larger than 3dB. + return 1; +} + +/** + * \brief Calculate reflection coefficient for tilt compensation filter (4.2.3). + * \param dsp initialized DSP context + * \param lp_gn (3.12) coefficients of A(z/FORMANT_PP_FACTOR_NUM) filter + * \param lp_gd (3.12) coefficients of A(z/FORMANT_PP_FACTOR_DEN) filter + * \param speech speech to update + * \param subframe_size size of subframe + * + * \return (3.12) reflection coefficient + * + * \remark The routine also calculates the gain term for the short-term + * filter (gf) and multiplies the speech data by 1/gf. + * + * \note All members of lp_gn, except 10-19 must be equal to zero. + */ +static int16_t get_tilt_comp(DSPContext *dsp, int16_t *lp_gn, + const int16_t *lp_gd, int16_t* speech, + int subframe_size) +{ + int rh1,rh0; // (3.12) + int temp; + int i; + int gain_term; + + lp_gn[10] = 4096; //1.0 in (3.12) + + /* Apply 1/A(z/FORMANT_PP_FACTOR_DEN) filter to hf. */ + ff_celp_lp_synthesis_filter(lp_gn + 11, lp_gd + 1, lp_gn + 11, 22, 10, 0, 0, 0x800); + /* Now lp_gn (starting with 10) contains impulse response + of A(z/FORMANT_PP_FACTOR_NUM)/A(z/FORMANT_PP_FACTOR_DEN) filter. */ + + rh0 = dsp->scalarproduct_int16(lp_gn + 10, lp_gn + 10, 20); + rh1 = dsp->scalarproduct_int16(lp_gn + 10, lp_gn + 11, 20); + + /* downscale to avoid overflow */ + temp = av_log2(rh0) - 14; + if (temp > 0) { + rh0 >>= temp; + rh1 >>= temp; + } + + if (FFABS(rh1) > rh0 || !rh0) + return 0; + + gain_term = 0; + for (i = 0; i < 20; i++) + gain_term += FFABS(lp_gn[i + 10]); + gain_term >>= 2; // (3.12) -> (5.10) + + if (gain_term > 0x400) { // 1.0 in (5.10) + temp = 0x2000000 / gain_term; // 1.0/gain_term in (0.15) + for (i = 0; i < subframe_size; i++) + speech[i] = (speech[i] * temp + 0x4000) >> 15; + } + + return -(rh1 << 15) / rh0; +} + +/** + * \brief Apply tilt compensation filter (4.2.3). + * \param res_pst [in/out] residual signal (partially filtered) + * \param k1 (3.12) reflection coefficient + * \param subframe_size size of subframe + * \param ht_prev_data previous data for 4.2.3, equation 86 + * + * \return new value for ht_prev_data +*/ +static int16_t apply_tilt_comp(int16_t* out, int16_t* res_pst, int refl_coeff, + int subframe_size, int16_t ht_prev_data) +{ + int tmp, tmp2; + int i; + int gt, ga; + int fact, sh_fact; + + if (refl_coeff > 0) { + gt = (refl_coeff * G729_TILT_FACTOR_PLUS + 0x4000) >> 15; + fact = 0x4000; // 0.5 in (0.15) + sh_fact = 15; + } else { + gt = (refl_coeff * G729_TILT_FACTOR_MINUS + 0x4000) >> 15; + fact = 0x800; // 0.5 in (3.12) + sh_fact = 12; + } + ga = (fact << 15) / av_clip_int16(32768 - FFABS(gt)); + gt >>= 1; + + /* Apply tilt compensation filter to signal. */ + tmp = res_pst[subframe_size - 1]; + + for (i = subframe_size - 1; i >= 1; i--) { + tmp2 = (res_pst[i] << 15) + ((gt * res_pst[i-1]) << 1); + tmp2 = (tmp2 + 0x4000) >> 15; + + tmp2 = (tmp2 * ga * 2 + fact) >> sh_fact; + out[i] = tmp2; + } + tmp2 = (res_pst[0] << 15) + ((gt * ht_prev_data) << 1); + tmp2 = (tmp2 + 0x4000) >> 15; + tmp2 = (tmp2 * ga * 2 + fact) >> sh_fact; + out[0] = tmp2; + + return tmp; +} + +void ff_g729_postfilter(DSPContext *dsp, int16_t* ht_prev_data, int* voicing, + const int16_t *lp_filter_coeffs, int pitch_delay_int, + int16_t* residual, int16_t* res_filter_data, + int16_t* pos_filter_data, int16_t *speech, int subframe_size) +{ + int16_t residual_filt_buf[SUBFRAME_SIZE+11]; + int16_t lp_gn[33]; // (3.12) + int16_t lp_gd[11]; // (3.12) + int tilt_comp_coeff; + int i; + + /* Zero-filling is necessary for tilt-compensation filter. */ + memset(lp_gn, 0, 33 * sizeof(int16_t)); + + /* Calculate A(z/FORMANT_PP_FACTOR_NUM) filter coefficients. */ + for (i = 0; i < 10; i++) + lp_gn[i + 11] = (lp_filter_coeffs[i + 1] * formant_pp_factor_num_pow[i] + 0x4000) >> 15; + + /* Calculate A(z/FORMANT_PP_FACTOR_DEN) filter coefficients. */ + for (i = 0; i < 10; i++) + lp_gd[i + 1] = (lp_filter_coeffs[i + 1] * formant_pp_factor_den_pow[i] + 0x4000) >> 15; + + /* residual signal calculation (one-half of short-term postfilter) */ + memcpy(speech - 10, res_filter_data, 10 * sizeof(int16_t)); + residual_filter(residual + RES_PREV_DATA_SIZE, lp_gn + 11, speech, subframe_size); + /* Save data to use it in the next subframe. */ + memcpy(res_filter_data, speech + subframe_size - 10, 10 * sizeof(int16_t)); + + /* long-term filter. If long-term prediction gain is larger than 3dB (returned value is + nonzero) then declare current subframe as periodic. */ + *voicing = FFMAX(*voicing, long_term_filter(dsp, pitch_delay_int, + residual, residual_filt_buf + 10, + subframe_size)); + + /* shift residual for using in next subframe */ + memmove(residual, residual + subframe_size, RES_PREV_DATA_SIZE * sizeof(int16_t)); + + /* short-term filter tilt compensation */ + tilt_comp_coeff = get_tilt_comp(dsp, lp_gn, lp_gd, residual_filt_buf + 10, subframe_size); + + /* Apply second half of short-term postfilter: 1/A(z/FORMANT_PP_FACTOR_DEN) */ + ff_celp_lp_synthesis_filter(pos_filter_data + 10, lp_gd + 1, + residual_filt_buf + 10, + subframe_size, 10, 0, 0, 0x800); + memcpy(pos_filter_data, pos_filter_data + subframe_size, 10 * sizeof(int16_t)); + + *ht_prev_data = apply_tilt_comp(speech, pos_filter_data + 10, tilt_comp_coeff, + subframe_size, *ht_prev_data); +} + +/** + * \brief Adaptive gain control (4.2.4) + * \param gain_before gain of speech before applying postfilters + * \param gain_after gain of speech after applying postfilters + * \param speech [in/out] signal buffer + * \param subframe_size length of subframe + * \param gain_prev (3.12) previous value of gain coefficient + * + * \return (3.12) last value of gain coefficient + */ +int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t *speech, + int subframe_size, int16_t gain_prev) +{ + int gain; // (3.12) + int n; + int exp_before, exp_after; + + if(!gain_after && gain_before) + return 0; + + if (gain_before) { + + exp_before = 14 - av_log2(gain_before); + gain_before = bidir_sal(gain_before, exp_before); + + exp_after = 14 - av_log2(gain_after); + gain_after = bidir_sal(gain_after, exp_after); + + if (gain_before < gain_after) { + gain = (gain_before << 15) / gain_after; + gain = bidir_sal(gain, exp_after - exp_before - 1); + } else { + gain = ((gain_before - gain_after) << 14) / gain_after + 0x4000; + gain = bidir_sal(gain, exp_after - exp_before); + } + gain = (gain * G729_AGC_FAC1 + 0x4000) >> 15; // gain * (1-0.9875) + } else + gain = 0; + + for (n = 0; n < subframe_size; n++) { + // gain_prev = gain + 0.9875 * gain_prev + gain_prev = (G729_AGC_FACTOR * gain_prev + 0x4000) >> 15; + gain_prev = av_clip_int16(gain + gain_prev); + speech[n] = av_clip_int16((speech[n] * gain_prev + 0x2000) >> 14); + } + return gain_prev; +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729postfilter.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729postfilter.h new file mode 100644 index 000000000..5239fc80d --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g729postfilter.h @@ -0,0 +1,116 @@ +/* + * G.729, G729 Annex D postfilter + * Copyright (c) 2008 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef FFMPEG_G729POSTFILTER_H +#define FFMPEG_G729POSTFILTER_H + +#include +#include "dsputil.h" + +/** + * tilt compensation factor (G.729, k1>0) + * 0.2 in Q15 + */ +#define G729_TILT_FACTOR_PLUS 6554 + +/** + * tilt compensation factor (G.729, k1<0) + * 0.9 in Q15 + */ +#define G729_TILT_FACTOR_MINUS 29491 + +/* 4.2.2 */ +#define FORMANT_PP_FACTOR_NUM 18022 //0.55 in Q15 +#define FORMANT_PP_FACTOR_DEN 22938 //0.70 in Q15 + +/** + * gain adjustment factor (G.729, 4.2.4) + * 0.9875 in Q15 + */ +#define G729_AGC_FACTOR 32358 +#define G729_AGC_FAC1 (32768-G729_AGC_FACTOR) + +/** + * 1.0 / (1.0 + 0.5) in Q15 + * where 0.5 is the minimum value of + * weight factor, controlling amount of long-term postfiltering + */ +#define MIN_LT_FILT_FACTOR_A 21845 + +/** + * Short interpolation filter length + */ +#define SHORT_INT_FILT_LEN 2 + +/** + * Long interpolation filter length + */ +#define LONG_INT_FILT_LEN 8 + +/** + * Number of analyzed fractional pitch delays in second stage of long-term + * postfilter + */ +#define ANALYZED_FRAC_DELAYS 7 + +/** + * Amount of past residual signal data stored in buffer + */ +#define RES_PREV_DATA_SIZE (PITCH_DELAY_MAX + LONG_INT_FILT_LEN + 1) + +/** + * \brief Signal postfiltering (4.2) + * \param dsp initialized DSP context + * \param ht_prev_data [in/out] (Q12) pointer to variable receiving tilt + * compensation filter data from previous subframe + * \param voicing [in/out] (Q0) pointer to variable receiving voicing decision + * \param lp_filter_coeffs (Q12) LP filter coefficients + * \param pitch_delay_int integer part of the pitch delay + * \param residual [in/out] (Q0) residual signal buffer (used in long-term postfilter) + * \param res_filter_data [in/out] (Q0) speech data of previous subframe + * \param pos_filter_data [in/out] (Q0) previous speech data for short-term postfilter + * \param speech [in/out] (Q0) signal buffer + * \param subframe_size size of subframe + * + * Filtering has the following stages: + * Long-term postfilter (4.2.1) + * Short-term postfilter (4.2.2). + * Tilt-compensation (4.2.3) + */ +void ff_g729_postfilter(DSPContext *dsp, int16_t* ht_prev_data, int* voicing, + const int16_t *lp_filter_coeffs, int pitch_delay_int, + int16_t* residual, int16_t* res_filter_data, + int16_t* pos_filter_data, int16_t *speech, + int subframe_size); + +/** + * \brief Adaptive gain control (4.2.4) + * \param gain_before (Q0) gain of speech before applying postfilters + * \param gain_after (Q0) gain of speech after applying postfilters + * \param speech [in/out] (Q0) signal buffer + * \param subframe_size length of subframe + * \param gain_prev (Q12) previous value of gain coefficient + * + * \return (Q12) last value of gain coefficient + */ +int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t *speech, + int subframe_size, int16_t gain_prev); + +#endif // FFMPEG_G729POSTFILTER_H diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm.h new file mode 100644 index 000000000..e56f4cd0b --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm.h @@ -0,0 +1,31 @@ +/* + * GSM common header + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_GSM_H +#define AVCODEC_GSM_H + +/* bytes per block */ +#define GSM_BLOCK_SIZE 33 +#define GSM_MS_BLOCK_SIZE 65 + +/* samples per block */ +#define GSM_FRAME_SIZE 160 + +#endif /* AVCODEC_GSM_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm_parser.c new file mode 100644 index 000000000..f76bbef3e --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm_parser.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * GSM audio parser + * + * Splits packets into individual blocks. + */ + +#include "parser.h" +#include "gsm.h" + +typedef struct GSMParseContext { + ParseContext pc; + int block_size; + int duration; + int remaining; +} GSMParseContext; + +static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + GSMParseContext *s = s1->priv_data; + ParseContext *pc = &s->pc; + int next; + + if (!s->block_size) { + switch (avctx->codec_id) { + case AV_CODEC_ID_GSM: + s->block_size = GSM_BLOCK_SIZE; + s->duration = GSM_FRAME_SIZE; + break; + case AV_CODEC_ID_GSM_MS: + s->block_size = GSM_MS_BLOCK_SIZE; + s->duration = GSM_FRAME_SIZE * 2; + break; + default: + *poutbuf = buf; + *poutbuf_size = buf_size; + av_log(avctx, AV_LOG_ERROR, "Invalid codec_id\n"); + return buf_size; + } + } + + if (!s->remaining) + s->remaining = s->block_size; + if (s->remaining <= buf_size) { + next = s->remaining; + s->remaining = 0; + } else { + next = END_NOT_FOUND; + s->remaining -= buf_size; + } + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + s1->duration = s->duration; + + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser ff_gsm_parser = { + .codec_ids = { AV_CODEC_ID_GSM, AV_CODEC_ID_GSM_MS }, + .priv_data_size = sizeof(GSMParseContext), + .parser_parse = gsm_parse, + .parser_close = ff_parse_close, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec.c new file mode 100644 index 000000000..6817e65ac --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec.c @@ -0,0 +1,138 @@ +/* + * gsm 06.10 decoder + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * GSM decoder + */ + +#include "libavutil/channel_layout.h" +#include "avcodec.h" +#include "get_bits.h" +#include "internal.h" +#include "msgsmdec.h" + +#include "gsmdec_template.c" + +static av_cold int gsm_init(AVCodecContext *avctx) +{ + if (avctx->codec_tag == 0x0032 && + avctx->bit_rate != 13000 && + avctx->bit_rate != 17912 && + avctx->bit_rate != 35824 && + avctx->bit_rate != 71656) { + av_log(avctx, AV_LOG_ERROR, "Unsupported audio mode\n"); + return AVERROR_PATCHWELCOME; + } + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + if (!avctx->sample_rate) + avctx->sample_rate = 8000; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + switch (avctx->codec_id) { + case AV_CODEC_ID_GSM: + avctx->frame_size = GSM_FRAME_SIZE; + avctx->block_align = GSM_BLOCK_SIZE; + break; + case AV_CODEC_ID_GSM_MS: + avctx->frame_size = 2 * GSM_FRAME_SIZE; + avctx->block_align = GSM_MS_BLOCK_SIZE; + default: break; + } + + return 0; +} + +static int gsm_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AVFrame *frame = data; + int res; + GetBitContext gb; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int16_t *samples; + + if (buf_size < avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + + /* get output buffer */ + frame->nb_samples = avctx->frame_size; + if ((res = ff_get_buffer(avctx, frame, 0)) < 0) + return res; + samples = (int16_t *)frame->data[0]; + + switch (avctx->codec_id) { + case AV_CODEC_ID_GSM: + init_get_bits(&gb, buf, buf_size * 8); + if (get_bits(&gb, 4) != 0xd) + av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n"); + res = gsm_decode_block(avctx, samples, &gb); + if (res < 0) + return res; + break; + case AV_CODEC_ID_GSM_MS: + res = ff_msgsm_decode_block(avctx, samples, buf); + if (res < 0) + return res; + default: break; + } + + *got_frame_ptr = 1; + + return avctx->block_align; +} + +static void gsm_flush(AVCodecContext *avctx) +{ + GSMContext *s = avctx->priv_data; + memset(s, 0, sizeof(*s)); +} + +#if CONFIG_GSM_DECODER +AVCodec ff_gsm_decoder = { + .name = "gsm", + .long_name = NULL_IF_CONFIG_SMALL("GSM"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_GSM, + .priv_data_size = sizeof(GSMContext), + .init = gsm_init, + .decode = gsm_decode_frame, + .flush = gsm_flush, + .capabilities = CODEC_CAP_DR1, +}; +#endif +#if CONFIG_GSM_MS_DECODER +AVCodec ff_gsm_ms_decoder = { + .name = "gsm_ms", + .long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_GSM_MS, + .priv_data_size = sizeof(GSMContext), + .init = gsm_init, + .decode = gsm_decode_frame, + .flush = gsm_flush, + .capabilities = CODEC_CAP_DR1, +}; +#endif diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.c new file mode 100644 index 000000000..4324ea28a --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.c @@ -0,0 +1,94 @@ +/* + * gsm 06.10 decoder data + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "gsmdec_data.h" + +const uint16_t ff_gsm_long_term_gain_tab[4] = { + 3277, 11469, 21299, 32767 +}; + +const int16_t ff_gsm_dequant_tab[64][8] = { + { -28, -20, -12, -4, 4, 12, 20, 28}, + { -56, -40, -24, -8, 8, 24, 40, 56}, + { -84, -60, -36, -12, 12, 36, 60, 84}, + { -112, -80, -48, -16, 16, 48, 80, 112}, + { -140, -100, -60, -20, 20, 60, 100, 140}, + { -168, -120, -72, -24, 24, 72, 120, 168}, + { -196, -140, -84, -28, 28, 84, 140, 196}, + { -224, -160, -96, -32, 32, 96, 160, 224}, + { -252, -180, -108, -36, 36, 108, 180, 252}, + { -280, -200, -120, -40, 40, 120, 200, 280}, + { -308, -220, -132, -44, 44, 132, 220, 308}, + { -336, -240, -144, -48, 48, 144, 240, 336}, + { -364, -260, -156, -52, 52, 156, 260, 364}, + { -392, -280, -168, -56, 56, 168, 280, 392}, + { -420, -300, -180, -60, 60, 180, 300, 420}, + { -448, -320, -192, -64, 64, 192, 320, 448}, + { -504, -360, -216, -72, 72, 216, 360, 504}, + { -560, -400, -240, -80, 80, 240, 400, 560}, + { -616, -440, -264, -88, 88, 264, 440, 616}, + { -672, -480, -288, -96, 96, 288, 480, 672}, + { -728, -520, -312, -104, 104, 312, 520, 728}, + { -784, -560, -336, -112, 112, 336, 560, 784}, + { -840, -600, -360, -120, 120, 360, 600, 840}, + { -896, -640, -384, -128, 128, 384, 640, 896}, + { -1008, -720, -432, -144, 144, 432, 720, 1008}, + { -1120, -800, -480, -160, 160, 480, 800, 1120}, + { -1232, -880, -528, -176, 176, 528, 880, 1232}, + { -1344, -960, -576, -192, 192, 576, 960, 1344}, + { -1456, -1040, -624, -208, 208, 624, 1040, 1456}, + { -1568, -1120, -672, -224, 224, 672, 1120, 1568}, + { -1680, -1200, -720, -240, 240, 720, 1200, 1680}, + { -1792, -1280, -768, -256, 256, 768, 1280, 1792}, + { -2016, -1440, -864, -288, 288, 864, 1440, 2016}, + { -2240, -1600, -960, -320, 320, 960, 1600, 2240}, + { -2464, -1760, -1056, -352, 352, 1056, 1760, 2464}, + { -2688, -1920, -1152, -384, 384, 1152, 1920, 2688}, + { -2912, -2080, -1248, -416, 416, 1248, 2080, 2912}, + { -3136, -2240, -1344, -448, 448, 1344, 2240, 3136}, + { -3360, -2400, -1440, -480, 480, 1440, 2400, 3360}, + { -3584, -2560, -1536, -512, 512, 1536, 2560, 3584}, + { -4032, -2880, -1728, -576, 576, 1728, 2880, 4032}, + { -4480, -3200, -1920, -640, 640, 1920, 3200, 4480}, + { -4928, -3520, -2112, -704, 704, 2112, 3520, 4928}, + { -5376, -3840, -2304, -768, 768, 2304, 3840, 5376}, + { -5824, -4160, -2496, -832, 832, 2496, 4160, 5824}, + { -6272, -4480, -2688, -896, 896, 2688, 4480, 6272}, + { -6720, -4800, -2880, -960, 960, 2880, 4800, 6720}, + { -7168, -5120, -3072, -1024, 1024, 3072, 5120, 7168}, + { -8063, -5759, -3456, -1152, 1152, 3456, 5760, 8064}, + { -8959, -6399, -3840, -1280, 1280, 3840, 6400, 8960}, + { -9855, -7039, -4224, -1408, 1408, 4224, 7040, 9856}, + {-10751, -7679, -4608, -1536, 1536, 4608, 7680, 10752}, + {-11647, -8319, -4992, -1664, 1664, 4992, 8320, 11648}, + {-12543, -8959, -5376, -1792, 1792, 5376, 8960, 12544}, + {-13439, -9599, -5760, -1920, 1920, 5760, 9600, 13440}, + {-14335, -10239, -6144, -2048, 2048, 6144, 10240, 14336}, + {-16127, -11519, -6912, -2304, 2304, 6912, 11519, 16127}, + {-17919, -12799, -7680, -2560, 2560, 7680, 12799, 17919}, + {-19711, -14079, -8448, -2816, 2816, 8448, 14079, 19711}, + {-21503, -15359, -9216, -3072, 3072, 9216, 15359, 21503}, + {-23295, -16639, -9984, -3328, 3328, 9984, 16639, 23295}, + {-25087, -17919, -10752, -3584, 3584, 10752, 17919, 25087}, + {-26879, -19199, -11520, -3840, 3840, 11520, 19199, 26879}, + {-28671, -20479, -12288, -4096, 4096, 12288, 20479, 28671} +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.h new file mode 100644 index 000000000..fd89ed63e --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.h @@ -0,0 +1,43 @@ +/* + * gsm 06.10 decoder data + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_GSMDEC_DATA_H +#define AVCODEC_GSMDEC_DATA_H + +#include +#include "avcodec.h" + +typedef struct GSMContext { + // Contains first 120 elements from the previous frame + // (used by long_term_synth according to the "lag"), + // then in the following 160 elements the current + // frame is constructed. + int16_t ref_buf[280]; + int v[9]; + int lar[2][8]; + int lar_idx; + int msr; +} GSMContext; + +extern const uint16_t ff_gsm_long_term_gain_tab[4]; +extern const int16_t ff_gsm_dequant_tab[64][8]; + +#endif /* AVCODEC_GSMDEC_DATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_template.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_template.c new file mode 100644 index 000000000..0f559530e --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_template.c @@ -0,0 +1,151 @@ +/* + * gsm 06.10 decoder + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * GSM decoder + */ + +#include "get_bits.h" +#include "gsm.h" +#include "gsmdec_data.h" + +static void apcm_dequant_add(GetBitContext *gb, int16_t *dst) +{ + int i; + int maxidx = get_bits(gb, 6); + const int16_t *tab = ff_gsm_dequant_tab[maxidx]; + for (i = 0; i < 13; i++) + dst[3*i] += tab[get_bits(gb, 3)]; +} + +static inline int gsm_mult(int a, int b) +{ + return (a * b + (1 << 14)) >> 15; +} + +static void long_term_synth(int16_t *dst, int lag, int gain_idx) +{ + int i; + const int16_t *src = dst - lag; + uint16_t gain = ff_gsm_long_term_gain_tab[gain_idx]; + for (i = 0; i < 40; i++) + dst[i] = gsm_mult(gain, src[i]); +} + +static inline int decode_log_area(int coded, int factor, int offset) +{ + coded <<= 10; + coded -= offset; + return gsm_mult(coded, factor) << 1; +} + +static av_noinline int get_rrp(int filtered) +{ + int abs = FFABS(filtered); + if (abs < 11059) abs <<= 1; + else if (abs < 20070) abs += 11059; + else abs = (abs >> 2) + 26112; + return filtered < 0 ? -abs : abs; +} + +static int filter_value(int in, int rrp[8], int v[9]) +{ + int i; + for (i = 7; i >= 0; i--) { + in -= gsm_mult(rrp[i], v[i]); + v[i + 1] = v[i] + gsm_mult(rrp[i], in); + } + v[0] = in; + return in; +} + +static void short_term_synth(GSMContext *ctx, int16_t *dst, const int16_t *src) +{ + int i; + int rrp[8]; + int *lar = ctx->lar[ctx->lar_idx]; + int *lar_prev = ctx->lar[ctx->lar_idx ^ 1]; + for (i = 0; i < 8; i++) + rrp[i] = get_rrp((lar_prev[i] >> 2) + (lar_prev[i] >> 1) + (lar[i] >> 2)); + for (i = 0; i < 13; i++) + dst[i] = filter_value(src[i], rrp, ctx->v); + + for (i = 0; i < 8; i++) + rrp[i] = get_rrp((lar_prev[i] >> 1) + (lar [i] >> 1)); + for (i = 13; i < 27; i++) + dst[i] = filter_value(src[i], rrp, ctx->v); + + for (i = 0; i < 8; i++) + rrp[i] = get_rrp((lar_prev[i] >> 2) + (lar [i] >> 1) + (lar[i] >> 2)); + for (i = 27; i < 40; i++) + dst[i] = filter_value(src[i], rrp, ctx->v); + + for (i = 0; i < 8; i++) + rrp[i] = get_rrp(lar[i]); + for (i = 40; i < 160; i++) + dst[i] = filter_value(src[i], rrp, ctx->v); + + ctx->lar_idx ^= 1; +} + +static int postprocess(int16_t *data, int msr) +{ + int i; + for (i = 0; i < 160; i++) { + msr = av_clip_int16(data[i] + gsm_mult(msr, 28180)); + data[i] = av_clip_int16(msr << 1) & ~7; + } + return msr; +} + +static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, + GetBitContext *gb) +{ + GSMContext *ctx = avctx->priv_data; + int i; + int16_t *ref_dst = ctx->ref_buf + 120; + int *lar = ctx->lar[ctx->lar_idx]; + lar[0] = decode_log_area(get_bits(gb, 6), 13107, 1 << 15); + lar[1] = decode_log_area(get_bits(gb, 6), 13107, 1 << 15); + lar[2] = decode_log_area(get_bits(gb, 5), 13107, (1 << 14) + 2048*2); + lar[3] = decode_log_area(get_bits(gb, 5), 13107, (1 << 14) - 2560*2); + lar[4] = decode_log_area(get_bits(gb, 4), 19223, (1 << 13) + 94*2); + lar[5] = decode_log_area(get_bits(gb, 4), 17476, (1 << 13) - 1792*2); + lar[6] = decode_log_area(get_bits(gb, 3), 31454, (1 << 12) - 341*2); + lar[7] = decode_log_area(get_bits(gb, 3), 29708, (1 << 12) - 1144*2); + + for (i = 0; i < 4; i++) { + int lag = get_bits(gb, 7); + int gain_idx = get_bits(gb, 2); + int offset = get_bits(gb, 2); + lag = av_clip(lag, 40, 120); + long_term_synth(ref_dst, lag, gain_idx); + apcm_dequant_add(gb, ref_dst + offset); + ref_dst += 40; + } + memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf)); + short_term_synth(ctx, samples, ctx->ref_buf + 120); + // for optimal speed this could be merged with short_term_synth, + // not done yet because it is a bit ugly + ctx->msr = postprocess(samples, ctx->msr); + return 0; +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.c new file mode 100644 index 000000000..9b46f5273 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.c @@ -0,0 +1,294 @@ +/* + * LPC utility code + * Copyright (c) 2006 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/common.h" +#include "libavutil/lls.h" +#include "libavutil/internal.h" + +#define LPC_USE_DOUBLE +#include "lpc.h" +#include "libavutil/avassert.h" + + +/** + * Apply Welch window function to audio block + */ +static void lpc_apply_welch_window_c(const int32_t *data, int len, + double *w_data) +{ + int i, n2; + double w; + double c; + + /* The optimization in commit fa4ed8c does not support odd len. + * If someone wants odd len extend that change. */ + av_assert2(!(len & 1)); + + n2 = (len >> 1); + c = 2.0 / (len - 1.0); + + w_data+=n2; + data+=n2; + for(i=0; i qmax) && (sh > 0)) { + sh--; + } + + /* since negative shift values are unsupported in decoder, scale down + coefficients instead */ + if(sh == 0 && cmax > qmax) { + double scale = ((double)qmax) / cmax; + for(i=0; i=min_order-1; i--) { + if(ref[i] > 0.10) { + est = i+1; + break; + } + } + return est; +} + +int ff_lpc_calc_ref_coefs(LPCContext *s, + const int32_t *samples, int order, double *ref) +{ + double autoc[MAX_LPC_ORDER + 1]; + + s->lpc_apply_welch_window(samples, s->blocksize, s->windowed_samples); + s->lpc_compute_autocorr(s->windowed_samples, s->blocksize, order, autoc); + compute_ref_coefs(autoc, order, ref, NULL); + + return order; +} + +/** + * Calculate LPC coefficients for multiple orders + * + * @param lpc_type LPC method for determining coefficients, + * see #FFLPCType for details + */ +int ff_lpc_calc_coefs(LPCContext *s, + const int32_t *samples, int blocksize, int min_order, + int max_order, int precision, + int32_t coefs[][MAX_LPC_ORDER], int *shift, + enum FFLPCType lpc_type, int lpc_passes, + int omethod, int max_shift, int zero_shift) +{ + double autoc[MAX_LPC_ORDER+1]; + double ref[MAX_LPC_ORDER]; + double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; + int i, j, pass = 0; + int opt_order; + + av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && + lpc_type > FF_LPC_TYPE_FIXED); + av_assert0(lpc_type == FF_LPC_TYPE_CHOLESKY || lpc_type == FF_LPC_TYPE_LEVINSON); + + /* reinit LPC context if parameters have changed */ + if (blocksize != s->blocksize || max_order != s->max_order || + lpc_type != s->lpc_type) { + ff_lpc_end(s); + ff_lpc_init(s, blocksize, max_order, lpc_type); + } + + if(lpc_passes <= 0) + lpc_passes = 2; + + if (lpc_type == FF_LPC_TYPE_LEVINSON || (lpc_type == FF_LPC_TYPE_CHOLESKY && lpc_passes > 1)) { + s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples); + + s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc); + + compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1); + + for(i=0; i>pass) + fabs(eval - var[0]); + inv = 1/eval; + rinv = sqrt(inv); + for(j=0; j<=max_order; j++) + var[j] *= rinv; + weight += inv; + }else + weight++; + + m[pass&1].update_lls(&m[pass&1], var); + } + avpriv_solve_lls(&m[pass&1], 0.001, 0); + } + + for(i=0; i0; i--) + ref[i] = ref[i-1] - ref[i]; + } + + opt_order = max_order; + + if(omethod == ORDER_METHOD_EST) { + opt_order = estimate_best_order(ref, min_order, max_order); + i = opt_order-1; + quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); + } else { + for(i=min_order-1; iblocksize = blocksize; + s->max_order = max_order; + s->lpc_type = lpc_type; + + s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) * + sizeof(*s->windowed_samples)); + if (!s->windowed_buffer) + return AVERROR(ENOMEM); + s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4); + + s->lpc_apply_welch_window = lpc_apply_welch_window_c; + s->lpc_compute_autocorr = lpc_compute_autocorr_c; + + if (ARCH_X86) + ff_lpc_init_x86(s); + + return 0; +} + +av_cold void ff_lpc_end(LPCContext *s) +{ + av_freep(&s->windowed_buffer); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.h new file mode 100644 index 000000000..c323230b1 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.h @@ -0,0 +1,197 @@ +/* + * LPC utility code + * Copyright (c) 2006 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_LPC_H +#define AVCODEC_LPC_H + +#include +#include "libavutil/avassert.h" + +#define ORDER_METHOD_EST 0 +#define ORDER_METHOD_2LEVEL 1 +#define ORDER_METHOD_4LEVEL 2 +#define ORDER_METHOD_8LEVEL 3 +#define ORDER_METHOD_SEARCH 4 +#define ORDER_METHOD_LOG 5 + +#define MIN_LPC_ORDER 1 +#define MAX_LPC_ORDER 32 + +/** + * LPC analysis type + */ +enum FFLPCType { + FF_LPC_TYPE_DEFAULT = -1, ///< use the codec default LPC type + FF_LPC_TYPE_NONE = 0, ///< do not use LPC prediction or use all zero coefficients + FF_LPC_TYPE_FIXED = 1, ///< fixed LPC coefficients + FF_LPC_TYPE_LEVINSON = 2, ///< Levinson-Durbin recursion + FF_LPC_TYPE_CHOLESKY = 3, ///< Cholesky factorization + FF_LPC_TYPE_NB , ///< Not part of ABI +}; + +typedef struct LPCContext { + int blocksize; + int max_order; + enum FFLPCType lpc_type; + double *windowed_buffer; + double *windowed_samples; + + /** + * Apply a Welch window to an array of input samples. + * The output samples have the same scale as the input, but are in double + * sample format. + * @param data input samples + * @param len number of input samples + * @param w_data output samples + */ + void (*lpc_apply_welch_window)(const int32_t *data, int len, + double *w_data); + /** + * Perform autocorrelation on input samples with delay of 0 to lag. + * @param data input samples. + * constraints: no alignment needed, but must have at + * least lag*sizeof(double) valid bytes preceding it, and + * size must be at least (len+1)*sizeof(double) if data is + * 16-byte aligned or (len+2)*sizeof(double) if data is + * unaligned. + * @param len number of input samples to process + * @param lag maximum delay to calculate + * @param autoc output autocorrelation coefficients. + * constraints: array size must be at least lag+1. + */ + void (*lpc_compute_autocorr)(const double *data, int len, int lag, + double *autoc); +} LPCContext; + + +/** + * Calculate LPC coefficients for multiple orders + */ +int ff_lpc_calc_coefs(LPCContext *s, + const int32_t *samples, int blocksize, int min_order, + int max_order, int precision, + int32_t coefs[][MAX_LPC_ORDER], int *shift, + enum FFLPCType lpc_type, int lpc_passes, + int omethod, int max_shift, int zero_shift); + +int ff_lpc_calc_ref_coefs(LPCContext *s, + const int32_t *samples, int order, double *ref); + +/** + * Initialize LPCContext. + */ +int ff_lpc_init(LPCContext *s, int blocksize, int max_order, + enum FFLPCType lpc_type); +void ff_lpc_init_x86(LPCContext *s); + +/** + * Uninitialize LPCContext. + */ +void ff_lpc_end(LPCContext *s); + +#ifdef LPC_USE_DOUBLE +#define LPC_TYPE double +#else +#define LPC_TYPE float +#endif + +/** + * Schur recursion. + * Produces reflection coefficients from autocorrelation data. + */ +static inline void compute_ref_coefs(const LPC_TYPE *autoc, int max_order, + LPC_TYPE *ref, LPC_TYPE *error) +{ + int i, j; + LPC_TYPE err; + LPC_TYPE gen0[MAX_LPC_ORDER], gen1[MAX_LPC_ORDER]; + + for (i = 0; i < max_order; i++) + gen0[i] = gen1[i] = autoc[i + 1]; + + err = autoc[0]; + ref[0] = -gen1[0] / err; + err += gen1[0] * ref[0]; + if (error) + error[0] = err; + for (i = 1; i < max_order; i++) { + for (j = 0; j < max_order - i; j++) { + gen1[j] = gen1[j + 1] + ref[i - 1] * gen0[j]; + gen0[j] = gen1[j + 1] * ref[i - 1] + gen0[j]; + } + ref[i] = -gen1[0] / err; + err += gen1[0] * ref[i]; + if (error) + error[i] = err; + } +} + +/** + * Levinson-Durbin recursion. + * Produce LPC coefficients from autocorrelation data. + */ +static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order, + LPC_TYPE *lpc, int lpc_stride, int fail, + int normalize) +{ + int i, j; + LPC_TYPE err; + LPC_TYPE *lpc_last = lpc; + + av_assert2(normalize || !fail); + + if (normalize) + err = *autoc++; + + if (fail && (autoc[max_order - 1] == 0 || err <= 0)) + return -1; + + for(i=0; i>1; j++) { + LPC_TYPE f = lpc_last[ j]; + LPC_TYPE b = lpc_last[i-1-j]; + lpc[ j] = f + r * b; + lpc[i-1-j] = b + r * f; + } + + if (fail && err < 0) + return -1; + + lpc_last = lpc; + lpc += lpc_stride; + } + + return 0; +} + +#endif /* AVCODEC_LPC_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mp3_header_decompress_bsf.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mp3_header_decompress_bsf.c index df455322d..fa6b08a25 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mp3_header_decompress_bsf.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mp3_header_decompress_bsf.c @@ -41,7 +41,7 @@ static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext return 0; } - if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){ + if(avctx->extradata_size != 15 || strcmp((const char *) avctx->extradata, "FFCMP3 0.0")){ av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size); return -1; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mpegaudioenc.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mpegaudioenc.c index 63c8460c3..2d890bd2c 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mpegaudioenc.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/mpegaudioenc.c @@ -764,7 +764,7 @@ static int MPA_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } static const AVCodecDefault mp2_defaults[] = { - { "b", "128k" }, + { (const uint8_t *) "b", (const uint8_t *) "128k" }, { NULL }, }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.c new file mode 100644 index 000000000..90e83ae7a --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.c @@ -0,0 +1,38 @@ +/* + * gsm 06.10 decoder, Microsoft variant + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define BITSTREAM_READER_LE +#include "avcodec.h" +#include "msgsmdec.h" +#include "gsm.h" +#include "gsmdec_template.c" + +int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, + const uint8_t *buf) +{ + int res; + GetBitContext gb; + init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8); + res = gsm_decode_block(avctx, samples, &gb); + if (res < 0) + return res; + return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.h new file mode 100644 index 000000000..3bfd1fd40 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.h @@ -0,0 +1,30 @@ +/* + * gsm 06.10 decoder, Microsoft variant + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_MSGSMDEC_H +#define AVCODEC_MSGSMDEC_H + +#include "avcodec.h" + +int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, + const uint8_t *buf); + +#endif /* AVCODEC_MSGSMDEC_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm.c new file mode 100644 index 000000000..0a4ad0b9d --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm.c @@ -0,0 +1,571 @@ +/* + * PCM codecs + * Copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * PCM codecs + */ + +#include "libavutil/attributes.h" +#include "avcodec.h" +#include "bytestream.h" +#include "internal.h" +#include "mathops.h" +#include "pcm_tablegen.h" + +static av_cold int pcm_encode_init(AVCodecContext *avctx) +{ + avctx->frame_size = 0; + switch (avctx->codec->id) { + case AV_CODEC_ID_PCM_ALAW: + pcm_alaw_tableinit(); + break; + case AV_CODEC_ID_PCM_MULAW: + pcm_ulaw_tableinit(); + break; + default: + break; + } + + avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); + avctx->block_align = avctx->channels * avctx->bits_per_coded_sample / 8; + avctx->bit_rate = avctx->block_align * avctx->sample_rate * 8; + + return 0; +} + +/** + * Write PCM samples macro + * @param type Datatype of native machine format + * @param endian bytestream_put_xxx() suffix + * @param src Source pointer (variable name) + * @param dst Destination pointer (variable name) + * @param n Total number of samples (variable name) + * @param shift Bitshift (bits) + * @param offset Sample value offset + */ +#define ENCODE(type, endian, src, dst, n, shift, offset) \ + samples_ ## type = (const type *) src; \ + for (; n > 0; n--) { \ + register type v = (*samples_ ## type++ >> shift) + offset; \ + bytestream_put_ ## endian(&dst, v); \ + } + +#define ENCODE_PLANAR(type, endian, dst, n, shift, offset) \ + n /= avctx->channels; \ + for (c = 0; c < avctx->channels; c++) { \ + int i; \ + samples_ ## type = (const type *) frame->extended_data[c]; \ + for (i = n; i > 0; i--) { \ + register type v = (*samples_ ## type++ >> shift) + offset; \ + bytestream_put_ ## endian(&dst, v); \ + } \ + } + +static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + int n, c, sample_size, v, ret; + const short *samples; + unsigned char *dst; + const uint8_t *samples_uint8_t; + const int16_t *samples_int16_t; + const int32_t *samples_int32_t; + const int64_t *samples_int64_t; + const uint16_t *samples_uint16_t; + const uint32_t *samples_uint32_t; + + sample_size = av_get_bits_per_sample(avctx->codec->id) / 8; + n = frame->nb_samples * avctx->channels; + samples = (const short *)frame->data[0]; + + if ((ret = ff_alloc_packet2(avctx, avpkt, n * sample_size)) < 0) + return ret; + dst = avpkt->data; + + switch (avctx->codec->id) { + case AV_CODEC_ID_PCM_U32LE: + ENCODE(uint32_t, le32, samples, dst, n, 0, 0x80000000) + break; + case AV_CODEC_ID_PCM_U32BE: + ENCODE(uint32_t, be32, samples, dst, n, 0, 0x80000000) + break; + case AV_CODEC_ID_PCM_S24LE: + ENCODE(int32_t, le24, samples, dst, n, 8, 0) + break; + case AV_CODEC_ID_PCM_S24LE_PLANAR: + ENCODE_PLANAR(int32_t, le24, dst, n, 8, 0) + break; + case AV_CODEC_ID_PCM_S24BE: + ENCODE(int32_t, be24, samples, dst, n, 8, 0) + break; + case AV_CODEC_ID_PCM_U24LE: + ENCODE(uint32_t, le24, samples, dst, n, 8, 0x800000) + break; + case AV_CODEC_ID_PCM_U24BE: + ENCODE(uint32_t, be24, samples, dst, n, 8, 0x800000) + break; + case AV_CODEC_ID_PCM_S24DAUD: + for (; n > 0; n--) { + uint32_t tmp = ff_reverse[(*samples >> 8) & 0xff] + + (ff_reverse[*samples & 0xff] << 8); + tmp <<= 4; // sync flags would go here + bytestream_put_be24(&dst, tmp); + samples++; + } + break; + case AV_CODEC_ID_PCM_U16LE: + ENCODE(uint16_t, le16, samples, dst, n, 0, 0x8000) + break; + case AV_CODEC_ID_PCM_U16BE: + ENCODE(uint16_t, be16, samples, dst, n, 0, 0x8000) + break; + case AV_CODEC_ID_PCM_S8: + ENCODE(uint8_t, byte, samples, dst, n, 0, -128) + break; + case AV_CODEC_ID_PCM_S8_PLANAR: + ENCODE_PLANAR(uint8_t, byte, dst, n, 0, -128) + break; +#if HAVE_BIGENDIAN + case AV_CODEC_ID_PCM_F64LE: + ENCODE(int64_t, le64, samples, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S32LE: + case AV_CODEC_ID_PCM_F32LE: + ENCODE(int32_t, le32, samples, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S32LE_PLANAR: + ENCODE_PLANAR(int32_t, le32, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S16LE: + ENCODE(int16_t, le16, samples, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S16LE_PLANAR: + ENCODE_PLANAR(int16_t, le16, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_F64BE: + case AV_CODEC_ID_PCM_F32BE: + case AV_CODEC_ID_PCM_S32BE: + case AV_CODEC_ID_PCM_S16BE: +#else + case AV_CODEC_ID_PCM_F64BE: + ENCODE(int64_t, be64, samples, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_F32BE: + case AV_CODEC_ID_PCM_S32BE: + ENCODE(int32_t, be32, samples, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S16BE: + ENCODE(int16_t, be16, samples, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S16BE_PLANAR: + ENCODE_PLANAR(int16_t, be16, dst, n, 0, 0) + break; + case AV_CODEC_ID_PCM_F64LE: + case AV_CODEC_ID_PCM_F32LE: + case AV_CODEC_ID_PCM_S32LE: + case AV_CODEC_ID_PCM_S16LE: +#endif /* HAVE_BIGENDIAN */ + case AV_CODEC_ID_PCM_U8: + memcpy(dst, samples, n * sample_size); + break; +#if HAVE_BIGENDIAN + case AV_CODEC_ID_PCM_S16BE_PLANAR: +#else + case AV_CODEC_ID_PCM_S16LE_PLANAR: + case AV_CODEC_ID_PCM_S32LE_PLANAR: +#endif /* HAVE_BIGENDIAN */ + n /= avctx->channels; + for (c = 0; c < avctx->channels; c++) { + const uint8_t *src = frame->extended_data[c]; + bytestream_put_buffer(&dst, src, n * sample_size); + } + break; + case AV_CODEC_ID_PCM_ALAW: + for (; n > 0; n--) { + v = *samples++; + *dst++ = linear_to_alaw[(v + 32768) >> 2]; + } + break; + case AV_CODEC_ID_PCM_MULAW: + for (; n > 0; n--) { + v = *samples++; + *dst++ = linear_to_ulaw[(v + 32768) >> 2]; + } + break; + default: + return -1; + } + + *got_packet_ptr = 1; + return 0; +} + +typedef struct PCMDecode { + short table[256]; +} PCMDecode; + +static av_cold int pcm_decode_init(AVCodecContext *avctx) +{ + PCMDecode *s = avctx->priv_data; + int i; + + if (avctx->channels <= 0) { + av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); + return AVERROR(EINVAL); + } + + switch (avctx->codec_id) { + case AV_CODEC_ID_PCM_ALAW: + for (i = 0; i < 256; i++) + s->table[i] = alaw2linear(i); + break; + case AV_CODEC_ID_PCM_MULAW: + for (i = 0; i < 256; i++) + s->table[i] = ulaw2linear(i); + break; + default: + break; + } + + avctx->sample_fmt = avctx->codec->sample_fmts[0]; + + if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) + avctx->bits_per_raw_sample = av_get_bits_per_sample(avctx->codec_id); + + return 0; +} + +/** + * Read PCM samples macro + * @param size Data size of native machine format + * @param endian bytestream_get_xxx() endian suffix + * @param src Source pointer (variable name) + * @param dst Destination pointer (variable name) + * @param n Total number of samples (variable name) + * @param shift Bitshift (bits) + * @param offset Sample value offset + */ +#define DECODE(size, endian, src, dst, n, shift, offset) \ + for (; n > 0; n--) { \ + uint ## size ## _t v = bytestream_get_ ## endian(&src); \ + AV_WN ## size ## A(dst, (v - offset) << shift); \ + dst += size / 8; \ + } + +#define DECODE_PLANAR(size, endian, src, dst, n, shift, offset) \ + n /= avctx->channels; \ + for (c = 0; c < avctx->channels; c++) { \ + int i; \ + dst = frame->extended_data[c]; \ + for (i = n; i > 0; i--) { \ + uint ## size ## _t v = bytestream_get_ ## endian(&src); \ + AV_WN ## size ## A(dst, (v - offset) << shift); \ + dst += size / 8; \ + } \ + } + +static int pcm_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + const uint8_t *src = avpkt->data; + int buf_size = avpkt->size; + PCMDecode *s = avctx->priv_data; + AVFrame *frame = data; + int sample_size, c, n, ret, samples_per_block; + uint8_t *samples; + int32_t *dst_int32_t; + + sample_size = av_get_bits_per_sample(avctx->codec_id) / 8; + + /* av_get_bits_per_sample returns 0 for AV_CODEC_ID_PCM_DVD */ + samples_per_block = 1; + if (avctx->codec_id == AV_CODEC_ID_PCM_LXF) { + /* we process 40-bit blocks per channel for LXF */ + samples_per_block = 2; + sample_size = 5; + } + + if (sample_size == 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample_size\n"); + return AVERROR(EINVAL); + } + + if (avctx->channels == 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); + return AVERROR(EINVAL); + } + + if (avctx->codec_id != avctx->codec->id) { + av_log(avctx, AV_LOG_ERROR, "codec ids mismatch\n"); + return AVERROR(EINVAL); + } + + n = avctx->channels * sample_size; + + if (n && buf_size % n) { + if (buf_size < n) { + av_log(avctx, AV_LOG_ERROR, + "Invalid PCM packet, data has size %d but at least a size of %d was expected\n", + buf_size, n); + return AVERROR_INVALIDDATA; + } else + buf_size -= buf_size % n; + } + + n = buf_size / sample_size; + + /* get output buffer */ + frame->nb_samples = n * samples_per_block / avctx->channels; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + samples = frame->data[0]; + + switch (avctx->codec_id) { + case AV_CODEC_ID_PCM_U32LE: + DECODE(32, le32, src, samples, n, 0, 0x80000000) + break; + case AV_CODEC_ID_PCM_U32BE: + DECODE(32, be32, src, samples, n, 0, 0x80000000) + break; + case AV_CODEC_ID_PCM_S24LE: + DECODE(32, le24, src, samples, n, 8, 0) + break; + case AV_CODEC_ID_PCM_S24LE_PLANAR: + DECODE_PLANAR(32, le24, src, samples, n, 8, 0); + break; + case AV_CODEC_ID_PCM_S24BE: + DECODE(32, be24, src, samples, n, 8, 0) + break; + case AV_CODEC_ID_PCM_U24LE: + DECODE(32, le24, src, samples, n, 8, 0x800000) + break; + case AV_CODEC_ID_PCM_U24BE: + DECODE(32, be24, src, samples, n, 8, 0x800000) + break; + case AV_CODEC_ID_PCM_S24DAUD: + for (; n > 0; n--) { + uint32_t v = bytestream_get_be24(&src); + v >>= 4; // sync flags are here + AV_WN16A(samples, ff_reverse[(v >> 8) & 0xff] + + (ff_reverse[v & 0xff] << 8)); + samples += 2; + } + break; + case AV_CODEC_ID_PCM_U16LE: + DECODE(16, le16, src, samples, n, 0, 0x8000) + break; + case AV_CODEC_ID_PCM_U16BE: + DECODE(16, be16, src, samples, n, 0, 0x8000) + break; + case AV_CODEC_ID_PCM_S8: + for (; n > 0; n--) + *samples++ = *src++ + 128; + break; + case AV_CODEC_ID_PCM_S8_PLANAR: + n /= avctx->channels; + for (c = 0; c < avctx->channels; c++) { + int i; + samples = frame->extended_data[c]; + for (i = n; i > 0; i--) + *samples++ = *src++ + 128; + } + break; +#if HAVE_BIGENDIAN + case AV_CODEC_ID_PCM_F64LE: + DECODE(64, le64, src, samples, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S32LE: + case AV_CODEC_ID_PCM_F32LE: + DECODE(32, le32, src, samples, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S32LE_PLANAR: + DECODE_PLANAR(32, le32, src, samples, n, 0, 0); + break; + case AV_CODEC_ID_PCM_S16LE: + DECODE(16, le16, src, samples, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S16LE_PLANAR: + DECODE_PLANAR(16, le16, src, samples, n, 0, 0); + break; + case AV_CODEC_ID_PCM_F64BE: + case AV_CODEC_ID_PCM_F32BE: + case AV_CODEC_ID_PCM_S32BE: + case AV_CODEC_ID_PCM_S16BE: +#else + case AV_CODEC_ID_PCM_F64BE: + DECODE(64, be64, src, samples, n, 0, 0) + break; + case AV_CODEC_ID_PCM_F32BE: + case AV_CODEC_ID_PCM_S32BE: + DECODE(32, be32, src, samples, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S16BE: + DECODE(16, be16, src, samples, n, 0, 0) + break; + case AV_CODEC_ID_PCM_S16BE_PLANAR: + DECODE_PLANAR(16, be16, src, samples, n, 0, 0); + break; + case AV_CODEC_ID_PCM_F64LE: + case AV_CODEC_ID_PCM_F32LE: + case AV_CODEC_ID_PCM_S32LE: + case AV_CODEC_ID_PCM_S16LE: +#endif /* HAVE_BIGENDIAN */ + case AV_CODEC_ID_PCM_U8: + memcpy(samples, src, n * sample_size); + break; +#if HAVE_BIGENDIAN + case AV_CODEC_ID_PCM_S16BE_PLANAR: +#else + case AV_CODEC_ID_PCM_S16LE_PLANAR: + case AV_CODEC_ID_PCM_S32LE_PLANAR: +#endif /* HAVE_BIGENDIAN */ + n /= avctx->channels; + for (c = 0; c < avctx->channels; c++) { + samples = frame->extended_data[c]; + bytestream_get_buffer(&src, samples, n * sample_size); + } + break; + case AV_CODEC_ID_PCM_ZORK: + for (; n > 0; n--) { + int v = *src++; + if (v < 128) + v = 128 - v; + *samples++ = v; + } + break; + case AV_CODEC_ID_PCM_ALAW: + case AV_CODEC_ID_PCM_MULAW: + for (; n > 0; n--) { + AV_WN16A(samples, s->table[*src++]); + samples += 2; + } + break; + case AV_CODEC_ID_PCM_LXF: + { + int i; + n /= avctx->channels; + for (c = 0; c < avctx->channels; c++) { + dst_int32_t = (int32_t *)frame->extended_data[c]; + for (i = 0; i < n; i++) { + // extract low 20 bits and expand to 32 bits + *dst_int32_t++ = (src[2] << 28) | + (src[1] << 20) | + (src[0] << 12) | + ((src[2] & 0x0F) << 8) | + src[1]; + // extract high 20 bits and expand to 32 bits + *dst_int32_t++ = (src[4] << 24) | + (src[3] << 16) | + ((src[2] & 0xF0) << 8) | + (src[4] << 4) | + (src[3] >> 4); + src += 5; + } + } + break; + } + default: + return -1; + } + + *got_frame_ptr = 1; + + return buf_size; +} + +#define PCM_ENCODER_0(id_, sample_fmt_, name_, long_name_) +#define PCM_ENCODER_1(id_, sample_fmt_, name_, long_name_) \ +AVCodec ff_ ## name_ ## _encoder = { \ + .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ + .type = AVMEDIA_TYPE_AUDIO, \ + .id = AV_CODEC_ID_ ## id_, \ + .init = pcm_encode_init, \ + .encode2 = pcm_encode_frame, \ + .capabilities = CODEC_CAP_VARIABLE_FRAME_SIZE, \ + .sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_, \ + AV_SAMPLE_FMT_NONE }, \ +} + +#define PCM_ENCODER_2(cf, id, sample_fmt, name, long_name) \ + PCM_ENCODER_ ## cf(id, sample_fmt, name, long_name) +#define PCM_ENCODER_3(cf, id, sample_fmt, name, long_name) \ + PCM_ENCODER_2(cf, id, sample_fmt, name, long_name) +#define PCM_ENCODER(id, sample_fmt, name, long_name) \ + PCM_ENCODER_3(CONFIG_ ## id ## _ENCODER, id, sample_fmt, name, long_name) + +#define PCM_DECODER_0(id, sample_fmt, name, long_name) +#define PCM_DECODER_1(id_, sample_fmt_, name_, long_name_) \ +AVCodec ff_ ## name_ ## _decoder = { \ + .name = #name_, \ + .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ + .type = AVMEDIA_TYPE_AUDIO, \ + .id = AV_CODEC_ID_ ## id_, \ + .priv_data_size = sizeof(PCMDecode), \ + .init = pcm_decode_init, \ + .decode = pcm_decode_frame, \ + .capabilities = CODEC_CAP_DR1, \ + .sample_fmts = (const enum AVSampleFormat[]){ sample_fmt_, \ + AV_SAMPLE_FMT_NONE }, \ +} + +#define PCM_DECODER_2(cf, id, sample_fmt, name, long_name) \ + PCM_DECODER_ ## cf(id, sample_fmt, name, long_name) +#define PCM_DECODER_3(cf, id, sample_fmt, name, long_name) \ + PCM_DECODER_2(cf, id, sample_fmt, name, long_name) +#define PCM_DECODER(id, sample_fmt, name, long_name) \ + PCM_DECODER_3(CONFIG_ ## id ## _DECODER, id, sample_fmt, name, long_name) + +#define PCM_CODEC(id, sample_fmt_, name, long_name_) \ + PCM_ENCODER(id, sample_fmt_, name, long_name_); \ + PCM_DECODER(id, sample_fmt_, name, long_name_) + +/* Note: Do not forget to add new entries to the Makefile as well. */ +PCM_CODEC (PCM_ALAW, AV_SAMPLE_FMT_S16, pcm_alaw, "PCM A-law / G.711 A-law"); +PCM_CODEC (PCM_F32BE, AV_SAMPLE_FMT_FLT, pcm_f32be, "PCM 32-bit floating point big-endian"); +PCM_CODEC (PCM_F32LE, AV_SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian"); +PCM_CODEC (PCM_F64BE, AV_SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian"); +PCM_CODEC (PCM_F64LE, AV_SAMPLE_FMT_DBL, pcm_f64le, "PCM 64-bit floating point little-endian"); +PCM_DECODER(PCM_LXF, AV_SAMPLE_FMT_S32P,pcm_lxf, "PCM signed 20-bit little-endian planar"); +PCM_CODEC (PCM_MULAW, AV_SAMPLE_FMT_S16, pcm_mulaw, "PCM mu-law / G.711 mu-law"); +PCM_CODEC (PCM_S8, AV_SAMPLE_FMT_U8, pcm_s8, "PCM signed 8-bit"); +PCM_CODEC (PCM_S8_PLANAR, AV_SAMPLE_FMT_U8P, pcm_s8_planar, "PCM signed 8-bit planar"); +PCM_CODEC (PCM_S16BE, AV_SAMPLE_FMT_S16, pcm_s16be, "PCM signed 16-bit big-endian"); +PCM_CODEC (PCM_S16BE_PLANAR, AV_SAMPLE_FMT_S16P,pcm_s16be_planar, "PCM signed 16-bit big-endian planar"); +PCM_CODEC (PCM_S16LE, AV_SAMPLE_FMT_S16, pcm_s16le, "PCM signed 16-bit little-endian"); +PCM_CODEC (PCM_S16LE_PLANAR, AV_SAMPLE_FMT_S16P,pcm_s16le_planar, "PCM signed 16-bit little-endian planar"); +PCM_CODEC (PCM_S24BE, AV_SAMPLE_FMT_S32, pcm_s24be, "PCM signed 24-bit big-endian"); +PCM_CODEC (PCM_S24DAUD, AV_SAMPLE_FMT_S16, pcm_s24daud, "PCM D-Cinema audio signed 24-bit"); +PCM_CODEC (PCM_S24LE, AV_SAMPLE_FMT_S32, pcm_s24le, "PCM signed 24-bit little-endian"); +PCM_CODEC (PCM_S24LE_PLANAR, AV_SAMPLE_FMT_S32P,pcm_s24le_planar, "PCM signed 24-bit little-endian planar"); +PCM_CODEC (PCM_S32BE, AV_SAMPLE_FMT_S32, pcm_s32be, "PCM signed 32-bit big-endian"); +PCM_CODEC (PCM_S32LE, AV_SAMPLE_FMT_S32, pcm_s32le, "PCM signed 32-bit little-endian"); +PCM_CODEC (PCM_S32LE_PLANAR, AV_SAMPLE_FMT_S32P,pcm_s32le_planar, "PCM signed 32-bit little-endian planar"); +PCM_CODEC (PCM_U8, AV_SAMPLE_FMT_U8, pcm_u8, "PCM unsigned 8-bit"); +PCM_CODEC (PCM_U16BE, AV_SAMPLE_FMT_S16, pcm_u16be, "PCM unsigned 16-bit big-endian"); +PCM_CODEC (PCM_U16LE, AV_SAMPLE_FMT_S16, pcm_u16le, "PCM unsigned 16-bit little-endian"); +PCM_CODEC (PCM_U24BE, AV_SAMPLE_FMT_S32, pcm_u24be, "PCM unsigned 24-bit big-endian"); +PCM_CODEC (PCM_U24LE, AV_SAMPLE_FMT_S32, pcm_u24le, "PCM unsigned 24-bit little-endian"); +PCM_CODEC (PCM_U32BE, AV_SAMPLE_FMT_S32, pcm_u32be, "PCM unsigned 32-bit big-endian"); +PCM_CODEC (PCM_U32LE, AV_SAMPLE_FMT_S32, pcm_u32le, "PCM unsigned 32-bit little-endian"); +PCM_DECODER(PCM_ZORK, AV_SAMPLE_FMT_U8, pcm_zork, "PCM Zork"); + diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm_tablegen.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm_tablegen.c new file mode 100644 index 000000000..bf8e7fb70 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm_tablegen.c @@ -0,0 +1,39 @@ +/* + * Generate a header file for hardcoded PCM tables + * + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#define CONFIG_HARDCODED_TABLES 0 +#include "pcm_tablegen.h" +#include "tableprint.h" + +int main(void) +{ + pcm_alaw_tableinit(); + pcm_ulaw_tableinit(); + + write_fileheader(); + + WRITE_ARRAY("static const", uint8_t, linear_to_alaw); + WRITE_ARRAY("static const", uint8_t, linear_to_ulaw); + + return 0; +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm_tablegen.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm_tablegen.h new file mode 100644 index 000000000..1387210a5 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/pcm_tablegen.h @@ -0,0 +1,119 @@ +/* + * Header file for hardcoded PCM tables + * + * Copyright (c) 2010 Reimar Döffinger + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_PCM_TABLEGEN_H +#define AVCODEC_PCM_TABLEGEN_H + +#include +#include "libavutil/attributes.h" + +/* from g711.c by SUN microsystems (unrestricted use) */ + +#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ +#define QUANT_MASK (0xf) /* Quantization field mask. */ +#define NSEGS (8) /* Number of A-law segments. */ +#define SEG_SHIFT (4) /* Left shift for segment number. */ +#define SEG_MASK (0x70) /* Segment field mask. */ + +#define BIAS (0x84) /* Bias for linear code. */ + +/* + * alaw2linear() - Convert an A-law value to 16-bit linear PCM + * + */ +static av_cold int alaw2linear(unsigned char a_val) +{ + int t; + int seg; + + a_val ^= 0x55; + + t = a_val & QUANT_MASK; + seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; + if(seg) t= (t + t + 1 + 32) << (seg + 2); + else t= (t + t + 1 ) << 3; + + return (a_val & SIGN_BIT) ? t : -t; +} + +static av_cold int ulaw2linear(unsigned char u_val) +{ + int t; + + /* Complement to obtain normal u-law value. */ + u_val = ~u_val; + + /* + * Extract and bias the quantization bits. Then + * shift up by the segment number and subtract out the bias. + */ + t = ((u_val & QUANT_MASK) << 3) + BIAS; + t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; + + return (u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS); +} + +#if CONFIG_HARDCODED_TABLES +#define pcm_alaw_tableinit() +#define pcm_ulaw_tableinit() +#include "libavcodec/pcm_tables.h" +#else +/* 16384 entries per table */ +static uint8_t linear_to_alaw[16384]; +static uint8_t linear_to_ulaw[16384]; + +static av_cold void build_xlaw_table(uint8_t *linear_to_xlaw, + int (*xlaw2linear)(unsigned char), + int mask) +{ + int i, j, v, v1, v2; + + j = 0; + for(i=0;i<128;i++) { + if (i != 127) { + v1 = xlaw2linear(i ^ mask); + v2 = xlaw2linear((i + 1) ^ mask); + v = (v1 + v2 + 4) >> 3; + } else { + v = 8192; + } + for(;j 0) + linear_to_xlaw[8192 - j] = (i ^ (mask ^ 0x80)); + } + } + linear_to_xlaw[0] = linear_to_xlaw[1]; +} + +static void pcm_alaw_tableinit(void) +{ + build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5); +} + +static void pcm_ulaw_tableinit(void) +{ + build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff); +} +#endif /* CONFIG_HARDCODED_TABLES */ + +#endif /* AVCODEC_PCM_TABLEGEN_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/sbrdsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/sbrdsp.c new file mode 100644 index 000000000..b4d5824e9 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/sbrdsp.c @@ -0,0 +1,291 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) + * Copyright (c) 2009-2010 Alex Converse + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/intfloat.h" +#include "sbrdsp.h" + +static void sbr_sum64x5_c(float *z) +{ + int k; + for (k = 0; k < 64; k++) { + float f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256]; + z[k] = f; + } +} + +static float sbr_sum_square_c(float (*x)[2], int n) +{ + float sum0 = 0.0f, sum1 = 0.0f; + int i; + + for (i = 0; i < n; i += 2) + { + sum0 += x[i + 0][0] * x[i + 0][0]; + sum1 += x[i + 0][1] * x[i + 0][1]; + sum0 += x[i + 1][0] * x[i + 1][0]; + sum1 += x[i + 1][1] * x[i + 1][1]; + } + + return sum0 + sum1; +} + +static void sbr_neg_odd_64_c(float *x) +{ + union av_intfloat32 *xi = (union av_intfloat32*) x; + int i; + for (i = 1; i < 64; i += 4) { + xi[i + 0].i ^= 1U << 31; + xi[i + 2].i ^= 1U << 31; + } +} + +static void sbr_qmf_pre_shuffle_c(float *z) +{ + union av_intfloat32 *zi = (union av_intfloat32*) z; + int k; + zi[64].i = zi[0].i; + zi[65].i = zi[1].i; + for (k = 1; k < 31; k += 2) { + zi[64 + 2 * k + 0].i = zi[64 - k].i ^ (1U << 31); + zi[64 + 2 * k + 1].i = zi[ k + 1].i; + zi[64 + 2 * k + 2].i = zi[63 - k].i ^ (1U << 31); + zi[64 + 2 * k + 3].i = zi[ k + 2].i; + } + + zi[64 + 2 * 31 + 0].i = zi[64 - 31].i ^ (1U << 31); + zi[64 + 2 * 31 + 1].i = zi[31 + 1].i; +} + +static void sbr_qmf_post_shuffle_c(float W[32][2], const float *z) +{ + const union av_intfloat32 *zi = (const union av_intfloat32*) z; + union av_intfloat32 *Wi = (union av_intfloat32*) W; + int k; + for (k = 0; k < 32; k += 2) { + Wi[2 * k + 0].i = zi[63 - k].i ^ (1U << 31); + Wi[2 * k + 1].i = zi[ k + 0].i; + Wi[2 * k + 2].i = zi[62 - k].i ^ (1U << 31); + Wi[2 * k + 3].i = zi[ k + 1].i; + } +} + +static void sbr_qmf_deint_neg_c(float *v, const float *src) +{ + const union av_intfloat32 *si = (const union av_intfloat32*)src; + union av_intfloat32 *vi = (union av_intfloat32*)v; + int i; + for (i = 0; i < 32; i++) { + vi[ i].i = si[63 - 2 * i ].i; + vi[63 - i].i = si[63 - 2 * i - 1].i ^ (1U << 31); + } +} + +static void sbr_qmf_deint_bfly_c(float *v, const float *src0, const float *src1) +{ + int i; + for (i = 0; i < 64; i++) { + v[ i] = src0[i] - src1[63 - i]; + v[127 - i] = src0[i] + src1[63 - i]; + } +} + +static av_always_inline void autocorrelate(const float x[40][2], + float phi[3][2][2], int lag) +{ + int i; + float real_sum = 0.0f; + float imag_sum = 0.0f; + if (lag) { + for (i = 1; i < 38; i++) { + real_sum += x[i][0] * x[i+lag][0] + x[i][1] * x[i+lag][1]; + imag_sum += x[i][0] * x[i+lag][1] - x[i][1] * x[i+lag][0]; + } + phi[2-lag][1][0] = real_sum + x[ 0][0] * x[lag][0] + x[ 0][1] * x[lag][1]; + phi[2-lag][1][1] = imag_sum + x[ 0][0] * x[lag][1] - x[ 0][1] * x[lag][0]; + if (lag == 1) { + phi[0][0][0] = real_sum + x[38][0] * x[39][0] + x[38][1] * x[39][1]; + phi[0][0][1] = imag_sum + x[38][0] * x[39][1] - x[38][1] * x[39][0]; + } + } else { + for (i = 1; i < 38; i++) { + real_sum += x[i][0] * x[i][0] + x[i][1] * x[i][1]; + } + phi[2][1][0] = real_sum + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1]; + phi[1][0][0] = real_sum + x[38][0] * x[38][0] + x[38][1] * x[38][1]; + } +} + +static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2]) +{ +#if 0 + /* This code is slower because it multiplies memory accesses. + * It is left for educational purposes and because it may offer + * a better reference for writing arch-specific DSP functions. */ + autocorrelate(x, phi, 0); + autocorrelate(x, phi, 1); + autocorrelate(x, phi, 2); +#else + float real_sum2 = x[0][0] * x[2][0] + x[0][1] * x[2][1]; + float imag_sum2 = x[0][0] * x[2][1] - x[0][1] * x[2][0]; + float real_sum1 = 0.0f, imag_sum1 = 0.0f, real_sum0 = 0.0f; + int i; + for (i = 1; i < 38; i++) { + real_sum0 += x[i][0] * x[i ][0] + x[i][1] * x[i ][1]; + real_sum1 += x[i][0] * x[i + 1][0] + x[i][1] * x[i + 1][1]; + imag_sum1 += x[i][0] * x[i + 1][1] - x[i][1] * x[i + 1][0]; + real_sum2 += x[i][0] * x[i + 2][0] + x[i][1] * x[i + 2][1]; + imag_sum2 += x[i][0] * x[i + 2][1] - x[i][1] * x[i + 2][0]; + } + phi[2 - 2][1][0] = real_sum2; + phi[2 - 2][1][1] = imag_sum2; + phi[2 ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1]; + phi[1 ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1]; + phi[2 - 1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1]; + phi[2 - 1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0]; + phi[0 ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1]; + phi[0 ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0]; +#endif +} + +static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end) +{ + float alpha[4]; + int i; + + alpha[0] = alpha1[0] * bw * bw; + alpha[1] = alpha1[1] * bw * bw; + alpha[2] = alpha0[0] * bw; + alpha[3] = alpha0[1] * bw; + + for (i = start; i < end; i++) { + X_high[i][0] = + X_low[i - 2][0] * alpha[0] - + X_low[i - 2][1] * alpha[1] + + X_low[i - 1][0] * alpha[2] - + X_low[i - 1][1] * alpha[3] + + X_low[i][0]; + X_high[i][1] = + X_low[i - 2][1] * alpha[0] + + X_low[i - 2][0] * alpha[1] + + X_low[i - 1][1] * alpha[2] + + X_low[i - 1][0] * alpha[3] + + X_low[i][1]; + } +} + +static void sbr_hf_g_filt_c(float (*Y)[2], const float (*X_high)[40][2], + const float *g_filt, int m_max, intptr_t ixh) +{ + int m; + + for (m = 0; m < m_max; m++) { + Y[m][0] = X_high[m][ixh][0] * g_filt[m]; + Y[m][1] = X_high[m][ixh][1] * g_filt[m]; + } +} + +static av_always_inline void sbr_hf_apply_noise(float (*Y)[2], + const float *s_m, + const float *q_filt, + int noise, + float phi_sign0, + float phi_sign1, + int m_max) +{ + int m; + + for (m = 0; m < m_max; m++) { + float y0 = Y[m][0]; + float y1 = Y[m][1]; + noise = (noise + 1) & 0x1ff; + if (s_m[m]) { + y0 += s_m[m] * phi_sign0; + y1 += s_m[m] * phi_sign1; + } else { + y0 += q_filt[m] * ff_sbr_noise_table[noise][0]; + y1 += q_filt[m] * ff_sbr_noise_table[noise][1]; + } + Y[m][0] = y0; + Y[m][1] = y1; + phi_sign1 = -phi_sign1; + } +} + +static void sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max) +{ + sbr_hf_apply_noise(Y, s_m, q_filt, noise, 1.0, 0.0, m_max); +} + +static void sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max) +{ + float phi_sign = 1 - 2 * (kx & 1); + sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, phi_sign, m_max); +} + +static void sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max) +{ + sbr_hf_apply_noise(Y, s_m, q_filt, noise, -1.0, 0.0, m_max); +} + +static void sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max) +{ + float phi_sign = 1 - 2 * (kx & 1); + sbr_hf_apply_noise(Y, s_m, q_filt, noise, 0.0, -phi_sign, m_max); +} + +av_cold void ff_sbrdsp_init(SBRDSPContext *s) +{ + s->sum64x5 = sbr_sum64x5_c; + s->sum_square = sbr_sum_square_c; + s->neg_odd_64 = sbr_neg_odd_64_c; + s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_c; + s->qmf_post_shuffle = sbr_qmf_post_shuffle_c; + s->qmf_deint_neg = sbr_qmf_deint_neg_c; + s->qmf_deint_bfly = sbr_qmf_deint_bfly_c; + s->autocorrelate = sbr_autocorrelate_c; + s->hf_gen = sbr_hf_gen_c; + s->hf_g_filt = sbr_hf_g_filt_c; + + s->hf_apply_noise[0] = sbr_hf_apply_noise_0; + s->hf_apply_noise[1] = sbr_hf_apply_noise_1; + s->hf_apply_noise[2] = sbr_hf_apply_noise_2; + s->hf_apply_noise[3] = sbr_hf_apply_noise_3; + + if (ARCH_ARM) + ff_sbrdsp_init_arm(s); + if (ARCH_X86) + ff_sbrdsp_init_x86(s); + if (ARCH_MIPS) + ff_sbrdsp_init_mips(s); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c index 5d8460c90..e45366c02 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c @@ -97,7 +97,7 @@ static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx, } found: - if (consumed && !buf_size && next == END_NOT_FOUND || + if ((consumed && !buf_size && next == END_NOT_FOUND) || ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; *poutbuf_size = 0; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c index 0edfddd7d..a832c58e9 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c @@ -163,8 +163,8 @@ static void set_sample_rate_params(AVCodecContext *avctx) TAKDecContext *s = avctx->priv_data; int shift = 3 - (avctx->sample_rate / 11025); shift = FFMAX(0, shift); - s->uval = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << shift; - s->subframe_scale = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << 1; + s->uval = FFALIGN((avctx->sample_rate + 511) >> 9, 4) << shift; + s->subframe_scale = FFALIGN((avctx->sample_rate + 511) >> 9, 4) << 1; } static av_cold int tak_decode_init(AVCodecContext *avctx) @@ -190,7 +190,7 @@ static void decode_lpc(int32_t *coeffs, int mode, int length) if (mode == 1) { int a1 = *coeffs++; - for (i = 0; i < length - 1 >> 1; i++) { + for (i = 0; i < (length - 1) >> 1; i++) { *coeffs += a1; coeffs[1] += *coeffs; a1 = coeffs[1]; @@ -204,7 +204,7 @@ static void decode_lpc(int32_t *coeffs, int mode, int length) coeffs[1] = a2; if (length > 2) { coeffs += 2; - for (i = 0; i < length - 2 >> 1; i++) { + for (i = 0; i < (length - 2) >> 1; i++) { int a3 = *coeffs + a1; int a4 = a3 + a2; *coeffs = a4; @@ -436,8 +436,8 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, int32_t *p2 = &tfilter[i - 1]; for (j = 0; j < (i + 1) / 2; j++) { - x = *p1 + (s->predictors[i] * *p2 + 256 >> 9); - *p2 += s->predictors[i] * *p1 + 256 >> 9; + x = *p1 + ((s->predictors[i] * *p2 + 256) >> 9); + *p2 += (s->predictors[i] * *p1 + 256) >> 9; *p1++ = x; p2--; } @@ -579,7 +579,7 @@ static int decorrelate(TAKDecContext *s, int c1, int c2, int length) for (i = 0; i < length; i++) { int32_t a = p1[i]; int32_t b = p2[i]; - b = dfactor * (b >> dshift) + 128 >> 8 << dshift; + b = (dfactor * (b >> dshift) + 128) >> 8 << dshift; p1[i] = b - a; } break; @@ -767,7 +767,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, } else { if (s->ti.codec == TAK_CODEC_MONO_STEREO) { for (chan = 0; chan < avctx->channels; chan++) - if (ret = decode_channel(s, chan)) + if ((ret = decode_channel(s, chan))) return ret; if (avctx->channels == 2) { @@ -777,7 +777,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, } s->dmode = get_bits(gb, 3); - if (ret = decorrelate(s, 0, 1, s->nb_samples - 1)) + if ((ret = decorrelate(s, 0, 1, s->nb_samples - 1))) return ret; } } else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) { @@ -825,18 +825,18 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, for (i = 0; i < chan; i++) { if (s->mcdparams[i].present && s->mcdparams[i].index == 1) - if (ret = decode_channel(s, s->mcdparams[i].chan2)) + if ((ret = decode_channel(s, s->mcdparams[i].chan2))) return ret; - if (ret = decode_channel(s, s->mcdparams[i].chan1)) + if ((ret = decode_channel(s, s->mcdparams[i].chan1))) return ret; if (s->mcdparams[i].present) { s->dmode = mc_dmodes[s->mcdparams[i].index]; - if (ret = decorrelate(s, + if ((ret = decorrelate(s, s->mcdparams[i].chan2, s->mcdparams[i].chan1, - s->nb_samples - 1)) + s->nb_samples - 1))) return ret; } } @@ -894,6 +894,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, samples[i] <<= 8; } break; + default: break; } *got_frame_ptr = 1; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech.c new file mode 100644 index 000000000..09c30c7aa --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech.c @@ -0,0 +1,367 @@ +/* + * DSP Group TrueSpeech compatible decoder + * Copyright (c) 2005 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/channel_layout.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/internal.h" +#include "avcodec.h" +#include "dsputil.h" +#include "get_bits.h" +#include "internal.h" + +#include "truespeech_data.h" +/** + * @file + * TrueSpeech decoder. + */ + +/** + * TrueSpeech decoder context + */ +typedef struct { + DSPContext dsp; + /* input data */ + DECLARE_ALIGNED(16, uint8_t, buffer)[32]; + int16_t vector[8]; ///< input vector: 5/5/4/4/4/3/3/3 + int offset1[2]; ///< 8-bit value, used in one copying offset + int offset2[4]; ///< 7-bit value, encodes offsets for copying and for two-point filter + int pulseoff[4]; ///< 4-bit offset of pulse values block + int pulsepos[4]; ///< 27-bit variable, encodes 7 pulse positions + int pulseval[4]; ///< 7x2-bit pulse values + int flag; ///< 1-bit flag, shows how to choose filters + /* temporary data */ + int filtbuf[146]; // some big vector used for storing filters + int prevfilt[8]; // filter from previous frame + int16_t tmp1[8]; // coefficients for adding to out + int16_t tmp2[8]; // coefficients for adding to out + int16_t tmp3[8]; // coefficients for adding to out + int16_t cvector[8]; // correlated input vector + int filtval; // gain value for one function + int16_t newvec[60]; // tmp vector + int16_t filters[32]; // filters for every subframe +} TSContext; + +static av_cold int truespeech_decode_init(AVCodecContext * avctx) +{ + TSContext *c = avctx->priv_data; + + if (avctx->channels != 1) { + avpriv_request_sample(avctx, "Channel count %d", avctx->channels); + return AVERROR_PATCHWELCOME; + } + + avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + ff_dsputil_init(&c->dsp, avctx); + + return 0; +} + +static void truespeech_read_frame(TSContext *dec, const uint8_t *input) +{ + GetBitContext gb; + + dec->dsp.bswap_buf((uint32_t *)dec->buffer, (const uint32_t *)input, 8); + init_get_bits(&gb, dec->buffer, 32 * 8); + + dec->vector[7] = ts_codebook[7][get_bits(&gb, 3)]; + dec->vector[6] = ts_codebook[6][get_bits(&gb, 3)]; + dec->vector[5] = ts_codebook[5][get_bits(&gb, 3)]; + dec->vector[4] = ts_codebook[4][get_bits(&gb, 4)]; + dec->vector[3] = ts_codebook[3][get_bits(&gb, 4)]; + dec->vector[2] = ts_codebook[2][get_bits(&gb, 4)]; + dec->vector[1] = ts_codebook[1][get_bits(&gb, 5)]; + dec->vector[0] = ts_codebook[0][get_bits(&gb, 5)]; + dec->flag = get_bits1(&gb); + + dec->offset1[0] = get_bits(&gb, 4) << 4; + dec->offset2[3] = get_bits(&gb, 7); + dec->offset2[2] = get_bits(&gb, 7); + dec->offset2[1] = get_bits(&gb, 7); + dec->offset2[0] = get_bits(&gb, 7); + + dec->offset1[1] = get_bits(&gb, 4); + dec->pulseval[1] = get_bits(&gb, 14); + dec->pulseval[0] = get_bits(&gb, 14); + + dec->offset1[1] |= get_bits(&gb, 4) << 4; + dec->pulseval[3] = get_bits(&gb, 14); + dec->pulseval[2] = get_bits(&gb, 14); + + dec->offset1[0] |= get_bits1(&gb); + dec->pulsepos[0] = get_bits_long(&gb, 27); + dec->pulseoff[0] = get_bits(&gb, 4); + + dec->offset1[0] |= get_bits1(&gb) << 1; + dec->pulsepos[1] = get_bits_long(&gb, 27); + dec->pulseoff[1] = get_bits(&gb, 4); + + dec->offset1[0] |= get_bits1(&gb) << 2; + dec->pulsepos[2] = get_bits_long(&gb, 27); + dec->pulseoff[2] = get_bits(&gb, 4); + + dec->offset1[0] |= get_bits1(&gb) << 3; + dec->pulsepos[3] = get_bits_long(&gb, 27); + dec->pulseoff[3] = get_bits(&gb, 4); +} + +static void truespeech_correlate_filter(TSContext *dec) +{ + int16_t tmp[8]; + int i, j; + + for(i = 0; i < 8; i++){ + if(i > 0){ + memcpy(tmp, dec->cvector, i * sizeof(*tmp)); + for(j = 0; j < i; j++) + dec->cvector[j] = ((tmp[i - j - 1] * dec->vector[i]) + + (dec->cvector[j] << 15) + 0x4000) >> 15; + } + dec->cvector[i] = (8 - dec->vector[i]) >> 3; + } + for(i = 0; i < 8; i++) + dec->cvector[i] = (dec->cvector[i] * ts_decay_994_1000[i]) >> 15; + + dec->filtval = dec->vector[0]; +} + +static void truespeech_filters_merge(TSContext *dec) +{ + int i; + + if(!dec->flag){ + for(i = 0; i < 8; i++){ + dec->filters[i + 0] = dec->prevfilt[i]; + dec->filters[i + 8] = dec->prevfilt[i]; + } + }else{ + for(i = 0; i < 8; i++){ + dec->filters[i + 0]=(dec->cvector[i] * 21846 + dec->prevfilt[i] * 10923 + 16384) >> 15; + dec->filters[i + 8]=(dec->cvector[i] * 10923 + dec->prevfilt[i] * 21846 + 16384) >> 15; + } + } + for(i = 0; i < 8; i++){ + dec->filters[i + 16] = dec->cvector[i]; + dec->filters[i + 24] = dec->cvector[i]; + } +} + +static void truespeech_apply_twopoint_filter(TSContext *dec, int quart) +{ + int16_t tmp[146 + 60], *ptr0, *ptr1; + const int16_t *filter; + int i, t, off; + + t = dec->offset2[quart]; + if(t == 127){ + memset(dec->newvec, 0, 60 * sizeof(*dec->newvec)); + return; + } + for(i = 0; i < 146; i++) + tmp[i] = dec->filtbuf[i]; + off = (t / 25) + dec->offset1[quart >> 1] + 18; + off = av_clip(off, 0, 145); + ptr0 = tmp + 145 - off; + ptr1 = tmp + 146; + filter = ts_order2_coeffs + (t % 25) * 2; + for(i = 0; i < 60; i++){ + t = (ptr0[0] * filter[0] + ptr0[1] * filter[1] + 0x2000) >> 14; + ptr0++; + dec->newvec[i] = t; + ptr1[i] = t; + } +} + +static void truespeech_place_pulses(TSContext *dec, int16_t *out, int quart) +{ + int16_t tmp[7]; + int i, j, t; + const int16_t *ptr1; + int16_t *ptr2; + int coef; + + memset(out, 0, 60 * sizeof(*out)); + for(i = 0; i < 7; i++) { + t = dec->pulseval[quart] & 3; + dec->pulseval[quart] >>= 2; + tmp[6 - i] = ts_pulse_scales[dec->pulseoff[quart] * 4 + t]; + } + + coef = dec->pulsepos[quart] >> 15; + ptr1 = ts_pulse_values + 30; + ptr2 = tmp; + for(i = 0, j = 3; (i < 30) && (j > 0); i++){ + t = *ptr1++; + if(coef >= t) + coef -= t; + else{ + out[i] = *ptr2++; + ptr1 += 30; + j--; + } + } + coef = dec->pulsepos[quart] & 0x7FFF; + ptr1 = ts_pulse_values; + for(i = 30, j = 4; (i < 60) && (j > 0); i++){ + t = *ptr1++; + if(coef >= t) + coef -= t; + else{ + out[i] = *ptr2++; + ptr1 += 30; + j--; + } + } + +} + +static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart) +{ + int i; + + memmove(dec->filtbuf, &dec->filtbuf[60], 86 * sizeof(*dec->filtbuf)); + for(i = 0; i < 60; i++){ + dec->filtbuf[i + 86] = out[i] + dec->newvec[i] - (dec->newvec[i] >> 3); + out[i] += dec->newvec[i]; + } +} + +static void truespeech_synth(TSContext *dec, int16_t *out, int quart) +{ + int i,k; + int t[8]; + int16_t *ptr0, *ptr1; + + ptr0 = dec->tmp1; + ptr1 = dec->filters + quart * 8; + for(i = 0; i < 60; i++){ + int sum = 0; + for(k = 0; k < 8; k++) + sum += ptr0[k] * ptr1[k]; + sum = (sum + (out[i] << 12) + 0x800) >> 12; + out[i] = av_clip(sum, -0x7FFE, 0x7FFE); + for(k = 7; k > 0; k--) + ptr0[k] = ptr0[k - 1]; + ptr0[0] = out[i]; + } + + for(i = 0; i < 8; i++) + t[i] = (ts_decay_35_64[i] * ptr1[i]) >> 15; + + ptr0 = dec->tmp2; + for(i = 0; i < 60; i++){ + int sum = 0; + for(k = 0; k < 8; k++) + sum += ptr0[k] * t[k]; + for(k = 7; k > 0; k--) + ptr0[k] = ptr0[k - 1]; + ptr0[0] = out[i]; + out[i] = ((out[i] << 12) - sum) >> 12; + } + + for(i = 0; i < 8; i++) + t[i] = (ts_decay_3_4[i] * ptr1[i]) >> 15; + + ptr0 = dec->tmp3; + for(i = 0; i < 60; i++){ + int sum = out[i] << 12; + for(k = 0; k < 8; k++) + sum += ptr0[k] * t[k]; + for(k = 7; k > 0; k--) + ptr0[k] = ptr0[k - 1]; + ptr0[0] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE); + + sum = ((ptr0[1] * (dec->filtval - (dec->filtval >> 2))) >> 4) + sum; + sum = sum - (sum >> 3); + out[i] = av_clip((sum + 0x800) >> 12, -0x7FFE, 0x7FFE); + } +} + +static void truespeech_save_prevvec(TSContext *c) +{ + int i; + + for(i = 0; i < 8; i++) + c->prevfilt[i] = c->cvector[i]; +} + +static int truespeech_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + TSContext *c = avctx->priv_data; + + int i, j; + int16_t *samples; + int iterations, ret; + + iterations = buf_size / 32; + + if (!iterations) { + av_log(avctx, AV_LOG_ERROR, + "Too small input buffer (%d bytes), need at least 32 bytes\n", buf_size); + return -1; + } + + /* get output buffer */ + frame->nb_samples = iterations * 240; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + samples = (int16_t *)frame->data[0]; + + memset(samples, 0, iterations * 240 * sizeof(*samples)); + + for(j = 0; j < iterations; j++) { + truespeech_read_frame(c, buf); + buf += 32; + + truespeech_correlate_filter(c); + truespeech_filters_merge(c); + + for(i = 0; i < 4; i++) { + truespeech_apply_twopoint_filter(c, i); + truespeech_place_pulses (c, samples, i); + truespeech_update_filters(c, samples, i); + truespeech_synth (c, samples, i); + samples += 60; + } + + truespeech_save_prevvec(c); + } + + *got_frame_ptr = 1; + + return buf_size; +} + +AVCodec ff_truespeech_decoder = { + .name = "truespeech", + .long_name = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_TRUESPEECH, + .priv_data_size = sizeof(TSContext), + .init = truespeech_decode_init, + .decode = truespeech_decode_frame, + .capabilities = CODEC_CAP_DR1, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech_data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech_data.h new file mode 100644 index 000000000..73ebda5e8 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech_data.h @@ -0,0 +1,159 @@ +/* + * DSP Group TrueSpeech compatible decoder + * copyright (c) 2005 Konstantin Shishkov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_TRUESPEECH_DATA_H +#define AVCODEC_TRUESPEECH_DATA_H + +#include + +/* codebooks fo expanding input filter */ +static const int16_t ts_cb_0[32] = { + 0x8240, 0x8364, 0x84CE, 0x865D, 0x8805, 0x89DE, 0x8BD7, 0x8DF4, + 0x9051, 0x92E2, 0x95DE, 0x990F, 0x9C81, 0xA079, 0xA54C, 0xAAD2, + 0xB18A, 0xB90A, 0xC124, 0xC9CC, 0xD339, 0xDDD3, 0xE9D6, 0xF893, + 0x096F, 0x1ACA, 0x29EC, 0x381F, 0x45F9, 0x546A, 0x63C3, 0x73B5, +}; + +static const int16_t ts_cb_1[32] = { + 0x9F65, 0xB56B, 0xC583, 0xD371, 0xE018, 0xEBB4, 0xF61C, 0xFF59, + 0x085B, 0x1106, 0x1952, 0x214A, 0x28C9, 0x2FF8, 0x36E6, 0x3D92, + 0x43DF, 0x49BB, 0x4F46, 0x5467, 0x5930, 0x5DA3, 0x61EC, 0x65F9, + 0x69D4, 0x6D5A, 0x709E, 0x73AD, 0x766B, 0x78F0, 0x7B5A, 0x7DA5, +}; + +static const int16_t ts_cb_2[16] = { + 0x96F8, 0xA3B4, 0xAF45, 0xBA53, 0xC4B1, 0xCECC, 0xD86F, 0xE21E, + 0xEBF3, 0xF640, 0x00F7, 0x0C20, 0x1881, 0x269A, 0x376B, 0x4D60, +}; + +static const int16_t ts_cb_3[16] = { + 0xC654, 0xDEF2, 0xEFAA, 0xFD94, 0x096A, 0x143F, 0x1E7B, 0x282C, + 0x3176, 0x3A89, 0x439F, 0x4CA2, 0x557F, 0x5E50, 0x6718, 0x6F8D, +}; + +static const int16_t ts_cb_4[16] = { + 0xABE7, 0xBBA8, 0xC81C, 0xD326, 0xDD0E, 0xE5D4, 0xEE22, 0xF618, + 0xFE28, 0x064F, 0x0EB7, 0x17B8, 0x21AA, 0x2D8B, 0x3BA2, 0x4DF9, +}; + +static const int16_t ts_cb_5[8] = { + 0xD51B, 0xF12E, 0x042E, 0x13C7, 0x2260, 0x311B, 0x40DE, 0x5385, +}; + +static const int16_t ts_cb_6[8] = { + 0xB550, 0xC825, 0xD980, 0xE997, 0xF883, 0x0752, 0x1811, 0x2E18, +}; + +static const int16_t ts_cb_7[8] = { + 0xCEF0, 0xE4F9, 0xF6BB, 0x0646, 0x14F5, 0x23FF, 0x356F, 0x4A8D, +}; + +static const int16_t * const ts_codebook[8] = { + ts_cb_0, ts_cb_1, ts_cb_2, ts_cb_3, ts_cb_4, ts_cb_5, ts_cb_6, ts_cb_7 +}; + +/* table used for decoding pulse positions */ +static const int16_t ts_pulse_values[120] = { + 0x0E46, 0x0CCC, 0x0B6D, 0x0A28, 0x08FC, 0x07E8, 0x06EB, 0x0604, + 0x0532, 0x0474, 0x03C9, 0x0330, 0x02A8, 0x0230, 0x01C7, 0x016C, + 0x011E, 0x00DC, 0x00A5, 0x0078, 0x0054, 0x0038, 0x0023, 0x0014, + 0x000A, 0x0004, 0x0001, 0x0000, 0x0000, 0x0000, + + 0x0196, 0x017A, 0x015F, 0x0145, 0x012C, 0x0114, 0x00FD, 0x00E7, + 0x00D2, 0x00BE, 0x00AB, 0x0099, 0x0088, 0x0078, 0x0069, 0x005B, + 0x004E, 0x0042, 0x0037, 0x002D, 0x0024, 0x001C, 0x0015, 0x000F, + 0x000A, 0x0006, 0x0003, 0x0001, 0x0000, 0x0000, + + 0x001D, 0x001C, 0x001B, 0x001A, 0x0019, 0x0018, 0x0017, 0x0016, + 0x0015, 0x0014, 0x0013, 0x0012, 0x0011, 0x0010, 0x000F, 0x000E, + 0x000D, 0x000C, 0x000B, 0x000A, 0x0009, 0x0008, 0x0007, 0x0006, + 0x0005, 0x0004, 0x0003, 0x0002, 0x0001, 0x0000, + + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001 +}; + +/* filter for correlated input filter */ +static const int16_t ts_decay_994_1000[8] = + { 0x7F3B, 0x7E78, 0x7DB6, 0x7CF5, 0x7C35, 0x7B76, 0x7AB8, 0x79FC }; + +/* two-point filters table */ +static const int16_t ts_order2_coeffs[25 * 2] = { + 0xED2F, 0x5239, + 0x54F1, 0xE4A9, + 0x2620, 0xEE3E, + 0x09D6, 0x2C40, + 0xEFB5, 0x2BE0, + + 0x3FE1, 0x3339, + 0x442F, 0xE6FE, + 0x4458, 0xF9DF, + 0xF231, 0x43DB, + 0x3DB0, 0xF705, + + 0x4F7B, 0xFEFB, + 0x26AD, 0x0CDC, + 0x33C2, 0x0739, + 0x12BE, 0x43A2, + 0x1BDF, 0x1F3E, + + 0x0211, 0x0796, + 0x2AEB, 0x163F, + 0x050D, 0x3A38, + 0x0D1E, 0x0D78, + 0x150F, 0x3346, + + 0x38A4, 0x0B7D, + 0x2D5D, 0x1FDF, + 0x19B7, 0x2822, + 0x0D99, 0x1F12, + 0x194C, 0x0CE6 +}; + +/* possible pulse values */ +static const int16_t ts_pulse_scales[64] = { + 0x0002, 0x0006, 0xFFFE, 0xFFFA, + 0x0004, 0x000C, 0xFFFC, 0xFFF4, + 0x0006, 0x0012, 0xFFFA, 0xFFEE, + 0x000A, 0x001E, 0xFFF6, 0xFFE2, + 0x0010, 0x0030, 0xFFF0, 0xFFD0, + 0x0019, 0x004B, 0xFFE7, 0xFFB5, + 0x0028, 0x0078, 0xFFD8, 0xFF88, + 0x0040, 0x00C0, 0xFFC0, 0xFF40, + 0x0065, 0x012F, 0xFF9B, 0xFED1, + 0x00A1, 0x01E3, 0xFF5F, 0xFE1D, + 0x0100, 0x0300, 0xFF00, 0xFD00, + 0x0196, 0x04C2, 0xFE6A, 0xFB3E, + 0x0285, 0x078F, 0xFD7B, 0xF871, + 0x0400, 0x0C00, 0xFC00, 0xF400, + 0x0659, 0x130B, 0xF9A7, 0xECF5, + 0x0A14, 0x1E3C, 0xF5EC, 0xE1C4 +}; + +/* filters used in final output calculations */ +static const int16_t ts_decay_35_64[8] = + { 0x4666, 0x26B8, 0x154C, 0x0BB6, 0x0671, 0x038B, 0x01F3, 0x0112 }; +static const int16_t ts_decay_3_4[8] = + { 0x6000, 0x4800, 0x3600, 0x2880, 0x1E60, 0x16C8, 0x1116, 0x0CD1 }; + +#endif /* AVCODEC_TRUESPEECH_DATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/lpc.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/lpc.c new file mode 100644 index 000000000..8a74755d1 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/lpc.c @@ -0,0 +1,159 @@ +/* + * MMX optimized LPC DSP utils + * Copyright (c) 2007 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/lpc.h" + +DECLARE_ASM_CONST(16, double, pd_1)[2] = { 1.0, 1.0 }; +DECLARE_ASM_CONST(16, double, pd_2)[2] = { 2.0, 2.0 }; + +#if HAVE_SSE2_INLINE + +static void lpc_apply_welch_window_sse2(const int32_t *data, int len, + double *w_data) +{ + double c = 2.0 / (len-1.0); + int n2 = len>>1; + x86_reg i = -n2*sizeof(int32_t); + x86_reg j = n2*sizeof(int32_t); + __asm__ volatile( + "movsd %4, %%xmm7 \n\t" + "movapd "MANGLE(pd_1)", %%xmm6 \n\t" + "movapd "MANGLE(pd_2)", %%xmm5 \n\t" + "movlhps %%xmm7, %%xmm7 \n\t" + "subpd %%xmm5, %%xmm7 \n\t" + "addsd %%xmm6, %%xmm7 \n\t" + "test $1, %5 \n\t" + "jz 2f \n\t" +#define WELCH(MOVPD, offset)\ + "1: \n\t"\ + "movapd %%xmm7, %%xmm1 \n\t"\ + "mulpd %%xmm1, %%xmm1 \n\t"\ + "movapd %%xmm6, %%xmm0 \n\t"\ + "subpd %%xmm1, %%xmm0 \n\t"\ + "pshufd $0x4e, %%xmm0, %%xmm1 \n\t"\ + "cvtpi2pd (%3,%0), %%xmm2 \n\t"\ + "cvtpi2pd "#offset"*4(%3,%1), %%xmm3 \n\t"\ + "mulpd %%xmm0, %%xmm2 \n\t"\ + "mulpd %%xmm1, %%xmm3 \n\t"\ + "movapd %%xmm2, (%2,%0,2) \n\t"\ + MOVPD" %%xmm3, "#offset"*8(%2,%1,2) \n\t"\ + "subpd %%xmm5, %%xmm7 \n\t"\ + "sub $8, %1 \n\t"\ + "add $8, %0 \n\t"\ + "jl 1b \n\t"\ + + WELCH("movupd", -1) + "jmp 3f \n\t" + "2: \n\t" + WELCH("movapd", -2) + "3: \n\t" + :"+&r"(i), "+&r"(j) + :"r"(w_data+n2), "r"(data+n2), "m"(c), "r"(len) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm5", "%xmm6", "%xmm7") + ); +#undef WELCH +} + +static void lpc_compute_autocorr_sse2(const double *data, int len, int lag, + double *autoc) +{ + int j; + + if((x86_reg)data & 15) + data++; + + for(j=0; jlpc_apply_welch_window = lpc_apply_welch_window_sse2; + c->lpc_compute_autocorr = lpc_compute_autocorr_sse2; + } +#endif /* HAVE_SSE2_INLINE */ +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c index 9c6f7950a..464911905 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c @@ -235,7 +235,9 @@ DECL_IMDCT_BLOCKS(avx,avx) av_cold void ff_mpadsp_init_x86(MPADSPContext *s) { +#if HAVE_SSE2_INLINE || HAVE_YASM int cpu_flags = av_get_cpu_flags(); +#endif int i, j; for (j = 0; j < 4; j++) { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/sbrdsp_init.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/sbrdsp_init.c new file mode 100644 index 000000000..2b912d0e9 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/sbrdsp_init.c @@ -0,0 +1,76 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2012 Christophe Gisquet + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/sbrdsp.h" + +float ff_sbr_sum_square_sse(float (*x)[2], int n); +void ff_sbr_sum64x5_sse(float *z); +void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2], + const float *g_filt, int m_max, intptr_t ixh); +void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end); +void ff_sbr_neg_odd_64_sse(float *z); +void ff_sbr_qmf_post_shuffle_sse(float W[32][2], const float *z); +void ff_sbr_qmf_deint_bfly_sse(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_pre_shuffle_sse2(float *z); + +void ff_sbr_hf_apply_noise_0_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_1_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_2_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_3_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); + +av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + s->neg_odd_64 = ff_sbr_neg_odd_64_sse; + s->sum_square = ff_sbr_sum_square_sse; + s->sum64x5 = ff_sbr_sum64x5_sse; + s->hf_g_filt = ff_sbr_hf_g_filt_sse; + s->hf_gen = ff_sbr_hf_gen_sse; + s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_sse; + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse2; + s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_sse2; + s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_sse2; + s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_sse2; + s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_sse2; + s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_sse2; + } +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aacdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aacdec.c new file mode 100644 index 000000000..aed4981b4 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aacdec.c @@ -0,0 +1,101 @@ +/* + * raw ADTS AAC demuxer + * Copyright (c) 2008 Michael Niedermayer + * Copyright (c) 2009 Robert Swain ( rob opendot cl ) + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "libavutil/intreadwrite.h" +#include "avformat.h" +#include "internal.h" +#include "rawdec.h" +#include "id3v1.h" +#include "apetag.h" + +static int adts_aac_probe(AVProbeData *p) +{ + int max_frames = 0, first_frames = 0; + int fsize, frames; + const uint8_t *buf0 = p->buf; + const uint8_t *buf2; + const uint8_t *buf; + const uint8_t *end = buf0 + p->buf_size - 7; + + buf = buf0; + + for(; buf < end; buf= buf2+1) { + buf2 = buf; + + for(frames = 0; buf2 < end; frames++) { + uint32_t header = AV_RB16(buf2); + if((header&0xFFF6) != 0xFFF0) + break; + fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF; + if(fsize < 7) + break; + fsize = FFMIN(fsize, end - buf2); + buf2 += fsize; + } + max_frames = FFMAX(max_frames, frames); + if(buf == buf0) + first_frames= frames; + } + if (first_frames>=3) return AVPROBE_SCORE_EXTENSION + 1; + else if(max_frames>500)return AVPROBE_SCORE_EXTENSION; + else if(max_frames>=3) return AVPROBE_SCORE_EXTENSION / 2; + else if(max_frames>=1) return 1; + else return 0; +} + +static int adts_aac_read_header(AVFormatContext *s) +{ + AVStream *st; + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = s->iformat->raw_codec_id; + st->need_parsing = AVSTREAM_PARSE_FULL_RAW; + + ff_id3v1_read(s); + if (s->pb->seekable && + !av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) { + int64_t cur = avio_tell(s->pb); + ff_ape_parse_tag(s); + avio_seek(s->pb, cur, SEEK_SET); + } + + //LCM of all possible ADTS sample rates + avpriv_set_pts_info(st, 64, 1, 28224000); + + return 0; +} + +AVInputFormat ff_aac_demuxer = { + .name = "aac", + .long_name = NULL_IF_CONFIG_SMALL("raw ADTS AAC (Advanced Audio Coding)"), + .read_probe = adts_aac_probe, + .read_header = adts_aac_read_header, + .read_packet = ff_raw_read_partial_packet, + .flags = AVFMT_GENERIC_INDEX, + .extensions = "aac", + .raw_codec_id = AV_CODEC_ID_AAC, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c index ab9373671..6b8267d10 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c @@ -62,15 +62,15 @@ static int ape_tag_read_field(AVFormatContext *s) if (!st) return AVERROR(ENOMEM); - size -= avio_get_str(pb, size, filename, sizeof(filename)); + size -= avio_get_str(pb, size, (char *) filename, sizeof(filename)); if (size <= 0) { av_log(s, AV_LOG_WARNING, "Skipping binary tag '%s'.\n", key); return 0; } - av_dict_set(&st->metadata, key, filename, 0); + av_dict_set(&st->metadata, (const char *) key, (const char *) filename, 0); - if ((id = ff_guess_image2_codec(filename)) != AV_CODEC_ID_NONE) { + if ((id = ff_guess_image2_codec((const char *) filename)) != AV_CODEC_ID_NONE) { AVPacket pkt; int ret; @@ -108,7 +108,7 @@ static int ape_tag_read_field(AVFormatContext *s) return c; } value[c] = 0; - av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); + av_dict_set(&s->metadata, (const char *) key, (const char *) value, AV_DICT_DONT_STRDUP_VAL); } return 0; } @@ -128,7 +128,7 @@ int64_t ff_ape_parse_tag(AVFormatContext *s) avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET); avio_read(pb, buf, 8); /* APETAGEX */ - if (strncmp(buf, APE_TAG_PREAMBLE, 8)) { + if (strncmp((const char *) buf, APE_TAG_PREAMBLE, 8)) { return 0; } @@ -194,7 +194,7 @@ int ff_ape_write_tag(AVFormatContext *s) while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) { int val_len; - if (!string_is_ascii(e->key)) { + if (!string_is_ascii((const unsigned char *) e->key)) { av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n"); continue; } @@ -203,7 +203,7 @@ int ff_ape_write_tag(AVFormatContext *s) avio_wl32(dyn_bc, val_len); // value length avio_wl32(dyn_bc, 0); // item flags avio_put_str(dyn_bc, e->key); // key - avio_write(dyn_bc, e->value, val_len); // value + avio_write(dyn_bc, (const unsigned char *) e->value, val_len); // value count++; } if (!count) @@ -215,7 +215,7 @@ int ff_ape_write_tag(AVFormatContext *s) size += 20; // header - avio_write(s->pb, "APETAGEX", 8); // id + avio_write(s->pb, (const unsigned char *) "APETAGEX", 8); // id avio_wl32(s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, size); avio_wl32(s->pb, count); @@ -223,7 +223,7 @@ int ff_ape_write_tag(AVFormatContext *s) avio_write(s->pb, dyn_buf, size - 20); // footer - avio_write(s->pb, "APETAGEX", 8); // id + avio_write(s->pb, (const unsigned char *) "APETAGEX", 8); // id avio_wl32(s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, size); // size avio_wl32(s->pb, count); // tag count diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c index 7e1f7e45a..a69d14b5b 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c @@ -91,7 +91,7 @@ static int dtshd_read_header(AVFormatContext *s) value = av_malloc(chunk_size); if (!value) goto skip; - avio_read(pb, value, chunk_size); + avio_read(pb, (unsigned char *) value, chunk_size); value[chunk_size - 1] = 0; av_dict_set(&s->metadata, "fileinfo", value, AV_DICT_DONT_STRDUP_VAL); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/spdifdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/spdifdec.c new file mode 100644 index 000000000..033fca28b --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/spdifdec.c @@ -0,0 +1,241 @@ +/* + * IEC 61937 demuxer + * Copyright (c) 2010 Anssi Hannula + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * IEC 61937 demuxer, used for compressed data in S/PDIF + * @author Anssi Hannula + */ + +#include "avformat.h" +#include "spdif.h" +#include "libavcodec/ac3.h" +#include "libavcodec/aacadtsdec.h" +#include "libavutil/internal.h" + +static int spdif_get_offset_and_codec(AVFormatContext *s, + enum IEC61937DataType data_type, + const char *buf, int *offset, + enum AVCodecID *codec) +{ + AACADTSHeaderInfo aac_hdr; + GetBitContext gbc; + + switch (data_type & 0xff) { + case IEC61937_AC3: + *offset = AC3_FRAME_SIZE << 2; + *codec = AV_CODEC_ID_AC3; + break; + case IEC61937_MPEG1_LAYER1: + *offset = spdif_mpeg_pkt_offset[1][0]; + *codec = AV_CODEC_ID_MP1; + break; + case IEC61937_MPEG1_LAYER23: + *offset = spdif_mpeg_pkt_offset[1][0]; + *codec = AV_CODEC_ID_MP3; + break; + case IEC61937_MPEG2_EXT: + *offset = 4608; + *codec = AV_CODEC_ID_MP3; + break; + case IEC61937_MPEG2_AAC: + init_get_bits(&gbc, (const uint8_t *) buf, AAC_ADTS_HEADER_SIZE * 8); + if (avpriv_aac_parse_header(&gbc, &aac_hdr)) { + if (s) /* be silent during a probe */ + av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n"); + return AVERROR_INVALIDDATA; + } + *offset = aac_hdr.samples << 2; + *codec = AV_CODEC_ID_AAC; + break; + case IEC61937_MPEG2_LAYER1_LSF: + *offset = spdif_mpeg_pkt_offset[0][0]; + *codec = AV_CODEC_ID_MP1; + break; + case IEC61937_MPEG2_LAYER2_LSF: + *offset = spdif_mpeg_pkt_offset[0][1]; + *codec = AV_CODEC_ID_MP2; + break; + case IEC61937_MPEG2_LAYER3_LSF: + *offset = spdif_mpeg_pkt_offset[0][2]; + *codec = AV_CODEC_ID_MP3; + break; + case IEC61937_DTS1: + *offset = 2048; + *codec = AV_CODEC_ID_DTS; + break; + case IEC61937_DTS2: + *offset = 4096; + *codec = AV_CODEC_ID_DTS; + break; + case IEC61937_DTS3: + *offset = 8192; + *codec = AV_CODEC_ID_DTS; + break; + default: + if (s) { /* be silent during a probe */ + avpriv_request_sample(s, "Data type 0x%04x in IEC 61937", + data_type); + } + return AVERROR_PATCHWELCOME; + } + return 0; +} + +/* Largest offset between bursts we currently handle, i.e. AAC with + aac_hdr.samples = 4096 */ +#define SPDIF_MAX_OFFSET 16384 + +static int spdif_probe(AVProbeData *p) +{ + enum AVCodecID codec; + return ff_spdif_probe (p->buf, p->buf_size, &codec); +} + +int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec) +{ + const uint8_t *buf = p_buf; + const uint8_t *probe_end = p_buf + FFMIN(2 * SPDIF_MAX_OFFSET, buf_size - 1); + const uint8_t *expected_code = buf + 7; + uint32_t state = 0; + int sync_codes = 0; + int consecutive_codes = 0; + int offset; + + for (; buf < probe_end; buf++) { + state = (state << 8) | *buf; + + if (state == (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2)) + && buf[1] < 0x37) { + sync_codes++; + + if (buf == expected_code) { + if (++consecutive_codes >= 2) + return AVPROBE_SCORE_MAX; + } else + consecutive_codes = 0; + + if (buf + 4 + AAC_ADTS_HEADER_SIZE > p_buf + buf_size) + break; + + /* continue probing to find more sync codes */ + probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p_buf + buf_size - 1); + + /* skip directly to the next sync code */ + if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1], + (const char *) &buf[5], &offset, codec)) { + if (buf + offset >= p_buf + buf_size) + break; + expected_code = buf + offset; + buf = expected_code - 7; + } + } + } + + if (!sync_codes) + return 0; + + if (sync_codes >= 6) + /* good amount of sync codes but with unexpected offsets */ + return AVPROBE_SCORE_EXTENSION; + + /* some sync codes were found */ + return AVPROBE_SCORE_EXTENSION / 4; +} + +static int spdif_read_header(AVFormatContext *s) +{ + s->ctx_flags |= AVFMTCTX_NOHEADER; + return 0; +} + +int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVIOContext *pb = s->pb; + enum IEC61937DataType data_type; + enum AVCodecID codec_id; + uint32_t state = 0; + int pkt_size_bits, offset, ret; + + while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { + state = (state << 8) | avio_r8(pb); + if (url_feof(pb)) + return AVERROR_EOF; + } + + data_type = avio_rl16(pb); + pkt_size_bits = avio_rl16(pb); + + if (pkt_size_bits % 16) + avpriv_request_sample(s, "Packet not ending at a 16-bit boundary"); + + ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); + if (ret) + return ret; + + pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; + + if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { + av_free_packet(pkt); + return AVERROR_EOF; + } + ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); + + ret = spdif_get_offset_and_codec(s, data_type, (const char *) pkt->data, + &offset, &codec_id); + if (ret) { + av_free_packet(pkt); + return ret; + } + + /* skip over the padding to the beginning of the next frame */ + avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE); + + if (!s->nb_streams) { + /* first packet, create a stream */ + AVStream *st = avformat_new_stream(s, NULL); + if (!st) { + av_free_packet(pkt); + return AVERROR(ENOMEM); + } + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = codec_id; + } else if (codec_id != s->streams[0]->codec->codec_id) { + avpriv_report_missing_feature(s, "Codec change in IEC 61937"); + return AVERROR_PATCHWELCOME; + } + + if (!s->bit_rate && s->streams[0]->codec->sample_rate) + /* stream bitrate matches 16-bit stereo PCM bitrate for currently + supported codecs */ + s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate; + + return 0; +} + +AVInputFormat ff_spdif_demuxer = { + .name = "spdif", + .long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"), + .read_probe = spdif_probe, + .read_header = spdif_read_header, + .read_packet = ff_spdif_read_packet, + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.c new file mode 100644 index 000000000..361dc9848 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.c @@ -0,0 +1,180 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * linear least squares model + */ + +#include +#include + +#include "config.h" +#include "attributes.h" +#include "version.h" +#include "lls.h" + +static void update_lls(LLSModel *m, double *var) +{ + int i, j; + + for (i = 0; i <= m->indep_count; i++) { + for (j = i; j <= m->indep_count; j++) { + m->covariance[i][j] += var[i] * var[j]; + } + } +} + +void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) +{ + int i, j, k; + double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0]; + double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1]; + double *covar_y = m->covariance[0]; + int count = m->indep_count; + + for (i = 0; i < count; i++) { + for (j = i; j < count; j++) { + double sum = covar[i][j]; + + for (k = i - 1; k >= 0; k--) + sum -= factor[i][k] * factor[j][k]; + + if (i == j) { + if (sum < threshold) + sum = 1.0; + factor[i][i] = sqrt(sum); + } else { + factor[j][i] = sum / factor[i][i]; + } + } + } + + for (i = 0; i < count; i++) { + double sum = covar_y[i + 1]; + + for (k = i - 1; k >= 0; k--) + sum -= factor[i][k] * m->coeff[0][k]; + + m->coeff[0][i] = sum / factor[i][i]; + } + + for (j = count - 1; j >= min_order; j--) { + for (i = j; i >= 0; i--) { + double sum = m->coeff[0][i]; + + for (k = i + 1; k <= j; k++) + sum -= factor[k][i] * m->coeff[j][k]; + + m->coeff[j][i] = sum / factor[i][i]; + } + + m->variance[j] = covar_y[0]; + + for (i = 0; i <= j; i++) { + double sum = m->coeff[j][i] * covar[i][i] - 2 * covar_y[i + 1]; + + for (k = 0; k < i; k++) + sum += 2 * m->coeff[j][k] * covar[k][i]; + + m->variance[j] += m->coeff[j][i] * sum; + } + } +} + +static double evaluate_lls(LLSModel *m, double *param, int order) +{ + int i; + double out = 0; + + for (i = 0; i <= order; i++) + out += param[i] * m->coeff[order][i]; + + return out; +} + +av_cold void avpriv_init_lls(LLSModel *m, int indep_count) +{ + memset(m, 0, sizeof(LLSModel)); + m->indep_count = indep_count; + m->update_lls = update_lls; + m->evaluate_lls = evaluate_lls; + if (ARCH_X86) + ff_init_lls_x86(m); +} + +#if FF_API_LLS_PRIVATE +av_cold void av_init_lls(LLSModel *m, int indep_count) +{ + avpriv_init_lls(m, indep_count); +} +void av_update_lls(LLSModel *m, double *param, double decay) +{ + m->update_lls(m, param); +} +void av_solve_lls(LLSModel *m, double threshold, int min_order) +{ + avpriv_solve_lls(m, threshold, min_order); +} +double av_evaluate_lls(LLSModel *m, double *param, int order) +{ + return m->evaluate_lls(m, param, order); +} +#endif /* FF_API_LLS_PRIVATE */ + +#ifdef TEST + +#include +#include +#include "lfg.h" + +int main(void) +{ + LLSModel m; + int i, order; + AVLFG lfg; + + av_lfg_init(&lfg, 1); + avpriv_init_lls(&m, 3); + + for (i = 0; i < 100; i++) { + LOCAL_ALIGNED(32, double, var, [4]); + double eval; + + var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2; + var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + m.update_lls(&m, var); + avpriv_solve_lls(&m, 0.001, 0); + for (order = 0; order < 3; order++) { + eval = m.evaluate_lls(&m, var + 1, order); + printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n", + var[0], order, eval, sqrt(m.variance[order] / (i + 1)), + m.coeff[order][0], m.coeff[order][1], + m.coeff[order][2]); + } + } + return 0; +} + +#endif diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.h new file mode 100644 index 000000000..c62d78a23 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.h @@ -0,0 +1,71 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LLS_H +#define AVUTIL_LLS_H + +#include "common.h" +#include "mem.h" +#include "version.h" + +#define MAX_VARS 32 +#define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4) + +//FIXME avoid direct access to LLSModel from outside + +/** + * Linear least squares model. + */ +typedef struct LLSModel { + DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]); + DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]); + double variance[MAX_VARS]; + int indep_count; + /** + * Take the outer-product of var[] with itself, and add to the covariance matrix. + * @param m this context + * @param var training samples, starting with the value to be predicted + * 32-byte aligned, and any padding elements must be initialized + * (i.e not denormal/nan). + */ + void (*update_lls)(struct LLSModel *m, double *var); + /** + * Inner product of var[] and the LPC coefs. + * @param m this context + * @param var training samples, excluding the value to be predicted. unaligned. + * @param order lpc order + */ + double (*evaluate_lls)(struct LLSModel *m, double *var, int order); +} LLSModel; + +void avpriv_init_lls(LLSModel *m, int indep_count); +void ff_init_lls_x86(LLSModel *m); +void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order); + +#if FF_API_LLS_PRIVATE +void av_init_lls(LLSModel *m, int indep_count); +void av_update_lls(LLSModel *m, double *param, double decay); +void av_solve_lls(LLSModel *m, double threshold, int min_order); +double av_evaluate_lls(LLSModel *m, double *param, int order); +#endif /* FF_API_LLS_PRIVATE */ + +#endif /* AVUTIL_LLS_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/x86/lls_init.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/x86/lls_init.c new file mode 100644 index 000000000..181ca38da --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/x86/lls_init.c @@ -0,0 +1,41 @@ +/* + * linear least squares model + * + * Copyright (c) 2013 Loren Merritt + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/lls.h" +#include "libavutil/x86/cpu.h" + +void ff_update_lls_sse2(LLSModel *m, double *var); +void ff_update_lls_avx(LLSModel *m, double *var); +double ff_evaluate_lls_sse2(LLSModel *m, double *var, int order); + +av_cold void ff_init_lls_x86(LLSModel *m) +{ + int cpu_flags = av_get_cpu_flags(); + if (EXTERNAL_SSE2(cpu_flags)) { + m->update_lls = ff_update_lls_sse2; + if (m->indep_count >= 4) + m->evaluate_lls = ff_evaluate_lls_sse2; + } + if (EXTERNAL_AVX(cpu_flags)) { + m->update_lls = ff_update_lls_avx; + } +} diff --git a/Plugins/FFMPEG/FFMPEGDecoder.m b/Plugins/FFMPEG/FFMPEGDecoder.m index 803a11d15..3fa214637 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.m +++ b/Plugins/FFMPEG/FFMPEGDecoder.m @@ -310,12 +310,12 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) + (NSArray *)fileTypes { - return [NSArray arrayWithObjects:@"wma", @"asf", @"xwma", @"tak", @"mp3", @"mp2", @"m2a", @"mpa", @"ape", @"ac3", @"dts", @"dtshd", nil]; + return [NSArray arrayWithObjects:@"wma", @"asf", @"xwma", @"tak", @"mp3", @"mp2", @"m2a", @"mpa", @"ape", @"ac3", @"dts", @"dtshd", @"at3", @"wav", nil]; } + (NSArray *)mimeTypes { - return [NSArray arrayWithObjects:@"application/wma", @"application/x-wma", @"audio/x-wma", @"audio/x-ms-wma", @"audio/x-tak", @"audio/mpeg", @"audio/x-mp3", @"audio/x-mp2", @"audio/x-ape", @"audio/x-ac3", @"audio/x-dts", @"audio/x-dtshd", nil]; + return [NSArray arrayWithObjects:@"application/wma", @"application/x-wma", @"audio/x-wma", @"audio/x-ms-wma", @"audio/x-tak", @"audio/mpeg", @"audio/x-mp3", @"audio/x-mp2", @"audio/x-ape", @"audio/x-ac3", @"audio/x-dts", @"audio/x-dtshd", @"audio/x-at3", @"audio/wav", nil]; }