Added a whole bunch of formats for WAV support

CQTexperiment
Chris Moeller 2013-10-10 23:25:26 -07:00
parent 21b78fde9f
commit 570fd380f8
73 changed files with 21297 additions and 94 deletions

View File

@ -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 = "<group>"; };
8384909A1807BE1300E7332D /* synth_filter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = synth_filter.c; sourceTree = "<group>"; };
8384909B1807BE1300E7332D /* synth_filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = synth_filter.h; sourceTree = "<group>"; };
8384909E1807C12300E7332D /* adpcm_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm_data.c; sourceTree = "<group>"; };
8384909F1807C12300E7332D /* adpcm_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm_data.h; sourceTree = "<group>"; };
838490A01807C12300E7332D /* adpcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm.c; sourceTree = "<group>"; };
838490A11807C12300E7332D /* adpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adpcm.h; sourceTree = "<group>"; };
838490A21807C12300E7332D /* pcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pcm.c; sourceTree = "<group>"; };
838490A81807C1C300E7332D /* gsm_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gsm_parser.c; sourceTree = "<group>"; };
838490A91807C1C300E7332D /* gsm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gsm.h; sourceTree = "<group>"; };
838490AA1807C1C300E7332D /* gsmdec_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gsmdec_data.c; sourceTree = "<group>"; };
838490AB1807C1C300E7332D /* gsmdec_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gsmdec_data.h; sourceTree = "<group>"; };
838490AC1807C1C300E7332D /* gsmdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gsmdec.c; sourceTree = "<group>"; };
838490AD1807C1C300E7332D /* msgsmdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = msgsmdec.c; sourceTree = "<group>"; };
838490AE1807C1C300E7332D /* msgsmdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgsmdec.h; sourceTree = "<group>"; };
838490AF1807C1C300E7332D /* truespeech_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = truespeech_data.h; sourceTree = "<group>"; };
838490B01807C1C300E7332D /* truespeech.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = truespeech.c; sourceTree = "<group>"; };
838490BA1807C30900E7332D /* pcm_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pcm_tablegen.h; sourceTree = "<group>"; };
838490BC1807C34900E7332D /* atrac3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac3.c; sourceTree = "<group>"; };
838490BD1807C34900E7332D /* atrac3data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atrac3data.h; sourceTree = "<group>"; };
838490C01807C37300E7332D /* atrac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac.c; sourceTree = "<group>"; };
838490C11807C37300E7332D /* atrac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atrac.h; sourceTree = "<group>"; };
838490CA1807C47E00E7332D /* g729.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g729.h; sourceTree = "<group>"; };
838490CB1807C47E00E7332D /* g729data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g729data.h; sourceTree = "<group>"; };
838490CC1807C47E00E7332D /* g729dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g729dec.c; sourceTree = "<group>"; };
838490CD1807C47E00E7332D /* g729postfilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g729postfilter.c; sourceTree = "<group>"; };
838490CE1807C47E00E7332D /* g729postfilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g729postfilter.h; sourceTree = "<group>"; };
838490CF1807C47E00E7332D /* g726.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g726.c; sourceTree = "<group>"; };
838490D01807C47E00E7332D /* g723_1_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g723_1_data.h; sourceTree = "<group>"; };
838490D11807C47E00E7332D /* g723_1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g723_1.c; sourceTree = "<group>"; };
838490D21807C47E00E7332D /* g722dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g722dec.c; sourceTree = "<group>"; };
838490D31807C47E00E7332D /* g722.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g722.c; sourceTree = "<group>"; };
838490D41807C47E00E7332D /* g722.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g722.h; sourceTree = "<group>"; };
838490E01807C57B00E7332D /* aac_adtstoasc_bsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aac_adtstoasc_bsf.c; sourceTree = "<group>"; };
838490E11807C57B00E7332D /* aac_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aac_parser.c; sourceTree = "<group>"; };
838490E21807C57B00E7332D /* aacadtsdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacadtsdec.c; sourceTree = "<group>"; };
838490E31807C57B00E7332D /* aacadtsdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacadtsdec.h; sourceTree = "<group>"; };
838490E51807C57B00E7332D /* aacdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacdec.c; sourceTree = "<group>"; };
838490E61807C57B00E7332D /* aacdectab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacdectab.h; sourceTree = "<group>"; };
838490E71807C57B00E7332D /* aacps_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacps_tablegen.h; sourceTree = "<group>"; };
838490E81807C57B00E7332D /* aacps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacps.c; sourceTree = "<group>"; };
838490EA1807C57B00E7332D /* aacpsdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacpsdsp.c; sourceTree = "<group>"; };
838490EC1807C57B00E7332D /* aacsbr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacsbr.c; sourceTree = "<group>"; };
838490ED1807C57B00E7332D /* aacsbr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacsbr.h; sourceTree = "<group>"; };
838490EE1807C57B00E7332D /* aacsbrdata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aacsbrdata.h; sourceTree = "<group>"; };
838490FE1807C58500E7332D /* aacdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aacdec.c; sourceTree = "<group>"; };
838491001807CDC000E7332D /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = "<group>"; };
838491011807CDC000E7332D /* lpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lpc.h; sourceTree = "<group>"; };
838491041807CDEC00E7332D /* cbrt_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cbrt_tablegen.h; sourceTree = "<group>"; };
838491061807CDF400E7332D /* lls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lls.c; sourceTree = "<group>"; };
838491071807CDF400E7332D /* lls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lls.h; sourceTree = "<group>"; };
8384910A1807CE2A00E7332D /* lls_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lls_init.c; sourceTree = "<group>"; };
8384910C1807CEB600E7332D /* sbrdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbrdsp.c; sourceTree = "<group>"; };
8384910E1807CEC400E7332D /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = "<group>"; };
838491101807CEF400E7332D /* sbrdsp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbrdsp_init.c; sourceTree = "<group>"; };
838491121807D06100E7332D /* spdifdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spdifdec.c; sourceTree = "<group>"; };
8393B7DF18052BB000913C76 /* mp3dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3dec.c; sourceTree = "<group>"; };
8393B7E018052BB000913C76 /* mpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg.c; sourceTree = "<group>"; };
8393B7E118052BB000913C76 /* mpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpeg.h; sourceTree = "<group>"; };
@ -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 */,
);

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,119 @@
/*
* MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter
* Copyright (c) 2009 Alex Converse <alex.converse@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
*/
#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,
};

View File

@ -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,
};

View File

@ -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;
}

View File

@ -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 <stdint.h>
#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 */

File diff suppressed because it is too large Load Diff

View File

@ -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 <stdint.h>
/* @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 */

View File

@ -0,0 +1,970 @@
/*
* MPEG-4 Parametric Stereo decoding functions
* Copyright (c) 2010 Alex Converse <alex.converse@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
*/
#include <stdint.h>
#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);
}

View File

@ -0,0 +1,215 @@
/*
* Header file for hardcoded Parametric Stereo tables
*
* Copyright (c) 2010 Alex Converse <alex.converse@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
*/
#ifndef AACPS_TABLEGEN_H
#define AACPS_TABLEGEN_H
#include <math.h>
#include <stdint.h>
#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 */

View File

@ -0,0 +1,163 @@
/*
* MPEG-4 Parametric Stereo data tables
* Copyright (c) 2010 Alex Converse <alex.converse@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
*/
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
};

View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 2010 Alex Converse <alex.converse@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
*/
#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);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
/*
* AAC Spectral Band Replication function declarations
* Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
* Copyright (c) 2010 Alex Converse <alex.converse@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 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 */

View File

@ -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 <stdint.h>
#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 */

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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 <stdint.h>
#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 */

View File

@ -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 <stdint.h>
/* 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 }
};

View File

@ -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 <stdint.h>
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 */

View File

@ -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 <math.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#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<nIn; i+=2){
p3[2*i+0] = inlo[i ] + inhi[i ];
p3[2*i+1] = inlo[i ] - inhi[i ];
p3[2*i+2] = inlo[i+1] + inhi[i+1];
p3[2*i+3] = inlo[i+1] - inhi[i+1];
}
/* loop2 */
p1 = temp;
for (j = nIn; j != 0; j--) {
float s1 = 0.0;
float s2 = 0.0;
for (i = 0; i < 48; i += 2) {
s1 += p1[i] * qmf_window[i];
s2 += p1[i+1] * qmf_window[i+1];
}
pOut[0] = s2;
pOut[1] = s1;
p1 += 2;
pOut += 2;
}
/* Update the delay buffer. */
memcpy(delayBuf, temp + nIn*2, 46*sizeof(float));
}

View File

@ -0,0 +1,97 @@
/*
* common functions for the ATRAC family of decoders
*
* Copyright (c) 2009-2013 Maxim Poliakovski
* Copyright (c) 2009 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
* ATRAC common header
*/
#ifndef AVCODEC_ATRAC_H
#define AVCODEC_ATRAC_H
/**
* Gain control parameters for one subband.
*/
typedef struct AtracGainInfo {
int num_points; ///< number of gain control points
int lev_code[7]; ///< level at corresponding control point
int loc_code[7]; ///< location of gain control points
} AtracGainInfo;
/**
* Gain compensation context structure.
*/
typedef struct AtracGCContext {
float gain_tab1[16]; ///< gain compensation level table
float gain_tab2[31]; ///< gain compensation interpolation table
int id2exp_offset; ///< offset for converting level index into level exponent
int loc_scale; ///< scale of location code = 2^loc_scale samples
int loc_size; ///< size of location code in samples
} AtracGCContext;
extern float ff_atrac_sf_table[64];
/**
* Generate common tables.
*/
void ff_atrac_generate_tables(void);
/**
* Initialize gain compensation context.
*
* @param gctx pointer to gain compensation context to initialize
* @param id2exp_offset offset for converting level index into level exponent
* @param loc_scale location size factor
*/
void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset,
int loc_scale);
/**
* Apply gain compensation and perform the MDCT overlapping part.
*
* @param gctx pointer to gain compensation context
* @param in input buffer
* @param prev previous buffer to perform overlap against
* @param gc_now gain control information for current frame
* @param gc_next gain control information for next frame
* @param num_samples number of samples to process
* @param out output data goes here
*/
void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev,
AtracGainInfo *gc_now, AtracGainInfo *gc_next,
int num_samples, float *out);
/**
* Quadrature mirror synthesis filter.
*
* @param inlo lower part of spectrum
* @param inhi higher part of spectrum
* @param nIn size of spectrum buffer
* @param pOut out buffer
* @param delayBuf delayBuf buffer
* @param temp temp buffer
*/
void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut,
float *delayBuf, float *temp);
#endif /* AVCODEC_ATRAC_H */

View File

@ -0,0 +1,953 @@
/*
* ATRAC3 compatible decoder
* Copyright (c) 2006-2008 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
* ATRAC3 compatible decoder.
* This decoder handles Sony's ATRAC3 data.
*
* Container formats used to store ATRAC3 data:
* RealMedia (.rm), RIFF WAV (.wav, .at3), Sony OpenMG (.oma, .aa3).
*
* To use this decoder, a calling application must supply the extradata
* bytes provided in the containers above.
*/
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#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]; ///<qmf delay buffers
float delay_buf2[46];
float delay_buf3[46];
} ChannelUnit;
typedef struct ATRAC3Context {
GetBitContext gb;
//@{
/** stream data */
int coding_mode;
ChannelUnit *units;
//@}
//@{
/** joint-stereo related variables */
int matrix_coeff_index_prev[4];
int matrix_coeff_index_now[4];
int matrix_coeff_index_next[4];
int weighting_delay[6];
//@}
//@{
/** data buffers */
uint8_t *decoded_bytes_buffer;
float temp_buf[1070];
//@}
//@{
/** extradata */
int scrambled_stream;
//@}
AtracGCContext gainc_ctx;
FFTContext mdct_ctx;
FmtConvertContext fmt_conv;
AVFloatDSPContext fdsp;
} ATRAC3Context;
static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE];
static VLC_TYPE atrac3_vlc_table[4096][2];
static VLC spectral_coeff_tab[7];
static float gain_tab1[16];
static float gain_tab2[31];
/**
* Regular 512 points IMDCT without overlapping, with the exception of the
* swapping of odd bands caused by the reverse spectra of the QMF.
*
* @param odd_band 1 if the band is an odd band
*/
static void imlt(ATRAC3Context *q, float *input, float *output, int odd_band)
{
int i;
if (odd_band) {
/**
* Reverse the odd bands before IMDCT, this is an effect of the QMF
* transform or it gives better compression to do it this way.
* FIXME: It should be possible to handle this in imdct_calc
* for that to happen a modification of the prerotation step of
* all SIMD code and C code is needed.
* Or fix the functions before so they generate a pre reversed spectrum.
*/
for (i = 0; i < 128; i++)
FFSWAP(float, input[i], input[255 - i]);
}
q->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 },
};

View File

@ -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 <stdint.h>
/* 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 */

View File

@ -0,0 +1,51 @@
/*
* Header file for hardcoded AAC cube-root table
*
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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 <stdint.h>
#include <math.h>
#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 */

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -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 <steveu at coppice.org>
* 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]);
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) CMU 1993 Computer Science, Speech Group
* Chengxiang Lu and Alex Hauptmann
* Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
* 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 <stdint.h>
#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 */

View File

@ -0,0 +1,149 @@
/*
* Copyright (c) CMU 1993 Computer Science, Speech Group
* Chengxiang Lu and Alex Hauptmann
* Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
* 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,
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 <limits.h>
#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<<dex) >> 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<<c->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

View File

@ -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

View File

@ -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 <stdint.h>
#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<<VQ_1ST_BITS][10] = { /* (2.13) */
{ 1486, 2168, 3751, 9074, 12134, 13944, 17983, 19173, 21190, 21820},
{ 1730, 2640, 3450, 4870, 6126, 7876, 15644, 17817, 20294, 21902},
{ 1568, 2256, 3088, 4874, 11063, 13393, 18307, 19293, 21109, 21741},
{ 1733, 2512, 3357, 4708, 6977, 10296, 17024, 17956, 19145, 20350},
{ 1744, 2436, 3308, 8731, 10432, 12007, 15614, 16639, 21359, 21913},
{ 1786, 2369, 3372, 4521, 6795, 12963, 17674, 18988, 20855, 21640},
{ 1631, 2433, 3361, 6328, 10709, 12013, 13277, 13904, 19441, 21088},
{ 1489, 2364, 3291, 6250, 9227, 10403, 13843, 15278, 17721, 21451},
{ 1869, 2533, 3475, 4365, 9152, 14513, 15908, 17022, 20611, 21411},
{ 2070, 3025, 4333, 5854, 7805, 9231, 10597, 16047, 20109, 21834},
{ 1910, 2673, 3419, 4261, 11168, 15111, 16577, 17591, 19310, 20265},
{ 1141, 1815, 2624, 4623, 6495, 9588, 13968, 16428, 19351, 21286},
{ 2192, 3171, 4707, 5808, 10904, 12500, 14162, 15664, 21124, 21789},
{ 1286, 1907, 2548, 3453, 9574, 11964, 15978, 17344, 19691, 22495},
{ 1921, 2720, 4604, 6684, 11503, 12992, 14350, 15262, 16997, 20791},
{ 2052, 2759, 3897, 5246, 6638, 10267, 15834, 16814, 18149, 21675},
{ 1798, 2497, 5617, 11449, 13189, 14711, 17050, 18195, 20307, 21182},
{ 1009, 1647, 2889, 5709, 9541, 12354, 15231, 18494, 20966, 22033},
{ 3016, 3794, 5406, 7469, 12488, 13984, 15328, 16334, 19952, 20791},
{ 2203, 3040, 3796, 5442, 11987, 13512, 14931, 16370, 17856, 18803},
{ 2912, 4292, 7988, 9572, 11562, 13244, 14556, 16529, 20004, 21073},
{ 2861, 3607, 5923, 7034, 9234, 12054, 13729, 18056, 20262, 20974},
{ 3069, 4311, 5967, 7367, 11482, 12699, 14309, 16233, 18333, 19172},
{ 2434, 3661, 4866, 5798, 10383, 11722, 13049, 15668, 18862, 19831},
{ 2020, 2605, 3860, 9241, 13275, 14644, 16010, 17099, 19268, 20251},
{ 1877, 2809, 3590, 4707, 11056, 12441, 15622, 17168, 18761, 19907},
{ 2107, 2873, 3673, 5799, 13579, 14687, 15938, 17077, 18890, 19831},
{ 1612, 2284, 2944, 3572, 8219, 13959, 15924, 17239, 18592, 20117},
{ 2420, 3156, 6542, 10215, 12061, 13534, 15305, 16452, 18717, 19880},
{ 1667, 2612, 3534, 5237, 10513, 11696, 12940, 16798, 18058, 19378},
{ 2388, 3017, 4839, 9333, 11413, 12730, 15024, 16248, 17449, 18677},
{ 1875, 2786, 4231, 6320, 8694, 10149, 11785, 17013, 18608, 19960},
{ 679, 1411, 4654, 8006, 11446, 13249, 15763, 18127, 20361, 21567},
{ 1838, 2596, 3578, 4608, 5650, 11274, 14355, 15886, 20579, 21754},
{ 1303, 1955, 2395, 3322, 12023, 13764, 15883, 18077, 20180, 21232},
{ 1438, 2102, 2663, 3462, 8328, 10362, 13763, 17248, 19732, 22344},
{ 860, 1904, 6098, 7775, 9815, 12007, 14821, 16709, 19787, 21132},
{ 1673, 2723, 3704, 6125, 7668, 9447, 13683, 14443, 20538, 21731},
{ 1246, 1849, 2902, 4508, 7221, 12710, 14835, 16314, 19335, 22720},
{ 1525, 2260, 3862, 5659, 7342, 11748, 13370, 14442, 18044, 21334},
{ 1196, 1846, 3104, 7063, 10972, 12905, 14814, 17037, 19922, 22636},
{ 2147, 3106, 4475, 6511, 8227, 9765, 10984, 12161, 18971, 21300},
{ 1585, 2405, 2994, 4036, 11481, 13177, 14519, 15431, 19967, 21275},
{ 1778, 2688, 3614, 4680, 9465, 11064, 12473, 16320, 19742, 20800},
{ 1862, 2586, 3492, 6719, 11708, 13012, 14364, 16128, 19610, 20425},
{ 1395, 2156, 2669, 3386, 10607, 12125, 13614, 16705, 18976, 21367},
{ 1444, 2117, 3286, 6233, 9423, 12981, 14998, 15853, 17188, 21857},
{ 2004, 2895, 3783, 4897, 6168, 7297, 12609, 16445, 19297, 21465},
{ 1495, 2863, 6360, 8100, 11399, 14271, 15902, 17711, 20479, 22061},
{ 2484, 3114, 5718, 7097, 8400, 12616, 14073, 14847, 20535, 21396},
{ 2424, 3277, 5296, 6284, 11290, 12903, 16022, 17508, 19333, 20283},
{ 2565, 3778, 5360, 6989, 8782, 10428, 14390, 15742, 17770, 21734},
{ 2727, 3384, 6613, 9254, 10542, 12236, 14651, 15687, 20074, 21102},
{ 1916, 2953, 6274, 8088, 9710, 10925, 12392, 16434, 20010, 21183},
{ 3384, 4366, 5349, 7667, 11180, 12605, 13921, 15324, 19901, 20754},
{ 3075, 4283, 5951, 7619, 9604, 11010, 12384, 14006, 20658, 21497},
{ 1751, 2455, 5147, 9966, 11621, 13176, 14739, 16470, 20788, 21756},
{ 1442, 2188, 3330, 6813, 8929, 12135, 14476, 15306, 19635, 20544},
{ 2294, 2895, 4070, 8035, 12233, 13416, 14762, 17367, 18952, 19688},
{ 1937, 2659, 4602, 6697, 9071, 12863, 14197, 15230, 16047, 18877},
{ 2071, 2663, 4216, 9445, 10887, 12292, 13949, 14909, 19236, 20341},
{ 1740, 2491, 3488, 8138, 9656, 11153, 13206, 14688, 20896, 21907},
{ 2199, 2881, 4675, 8527, 10051, 11408, 14435, 15463, 17190, 20597},
{ 1943, 2988, 4177, 6039, 7478, 8536, 14181, 15551, 17622, 21579},
{ 1825, 3175, 7062, 9818, 12824, 15450, 18330, 19856, 21830, 22412},
{ 2464, 3046, 4822, 5977, 7696, 15398, 16730, 17646, 20588, 21320},
{ 2550, 3393, 5305, 6920, 10235, 14083, 18143, 19195, 20681, 21336},
{ 3003, 3799, 5321, 6437, 7919, 11643, 15810, 16846, 18119, 18980},
{ 3455, 4157, 6838, 8199, 9877, 12314, 15905, 16826, 19949, 20892},
{ 3052, 3769, 4891, 5810, 6977, 10126, 14788, 15990, 19773, 20904},
{ 3671, 4356, 5827, 6997, 8460, 12084, 14154, 14939, 19247, 20423},
{ 2716, 3684, 5246, 6686, 8463, 10001, 12394, 14131, 16150, 19776},
{ 1945, 2638, 4130, 7995, 14338, 15576, 17057, 18206, 20225, 20997},
{ 2304, 2928, 4122, 4824, 5640, 13139, 15825, 16938, 20108, 21054},
{ 1800, 2516, 3350, 5219, 13406, 15948, 17618, 18540, 20531, 21252},
{ 1436, 2224, 2753, 4546, 9657, 11245, 15177, 16317, 17489, 19135},
{ 2319, 2899, 4980, 6936, 8404, 13489, 15554, 16281, 20270, 20911},
{ 2187, 2919, 4610, 5875, 7390, 12556, 14033, 16794, 20998, 21769},
{ 2235, 2923, 5121, 6259, 8099, 13589, 15340, 16340, 17927, 20159},
{ 1765, 2638, 3751, 5730, 7883, 10108, 13633, 15419, 16808, 18574},
{ 3460, 5741, 9596, 11742, 14413, 16080, 18173, 19090, 20845, 21601},
{ 3735, 4426, 6199, 7363, 9250, 14489, 16035, 17026, 19873, 20876},
{ 3521, 4778, 6887, 8680, 12717, 14322, 15950, 18050, 20166, 21145},
{ 2141, 2968, 6865, 8051, 10010, 13159, 14813, 15861, 17528, 18655},
{ 4148, 6128, 9028, 10871, 12686, 14005, 15976, 17208, 19587, 20595},
{ 4403, 5367, 6634, 8371, 10163, 11599, 14963, 16331, 17982, 18768},
{ 4091, 5386, 6852, 8770, 11563, 13290, 15728, 16930, 19056, 20102},
{ 2746, 3625, 5299, 7504, 10262, 11432, 13172, 15490, 16875, 17514},
{ 2248, 3556, 8539, 10590, 12665, 14696, 16515, 17824, 20268, 21247},
{ 1279, 1960, 3920, 7793, 10153, 14753, 16646, 18139, 20679, 21466},
{ 2440, 3475, 6737, 8654, 12190, 14588, 17119, 17925, 19110, 19979},
{ 1879, 2514, 4497, 7572, 10017, 14948, 16141, 16897, 18397, 19376},
{ 2804, 3688, 7490, 10086, 11218, 12711, 16307, 17470, 20077, 21126},
{ 2023, 2682, 3873, 8268, 10255, 11645, 15187, 17102, 18965, 19788},
{ 2823, 3605, 5815, 8595, 10085, 11469, 16568, 17462, 18754, 19876},
{ 2851, 3681, 5280, 7648, 9173, 10338, 14961, 16148, 17559, 18474},
{ 1348, 2645, 5826, 8785, 10620, 12831, 16255, 18319, 21133, 22586},
{ 2141, 3036, 4293, 6082, 7593, 10629, 17158, 18033, 21466, 22084},
{ 1608, 2375, 3384, 6878, 9970, 11227, 16928, 17650, 20185, 21120},
{ 2774, 3616, 5014, 6557, 7788, 8959, 17068, 18302, 19537, 20542},
{ 1934, 4813, 6204, 7212, 8979, 11665, 15989, 17811, 20426, 21703},
{ 2288, 3507, 5037, 6841, 8278, 9638, 15066, 16481, 21653, 22214},
{ 2951, 3771, 4878, 7578, 9016, 10298, 14490, 15242, 20223, 20990},
{ 3256, 4791, 6601, 7521, 8644, 9707, 13398, 16078, 19102, 20249},
{ 1827, 2614, 3486, 6039, 12149, 13823, 16191, 17282, 21423, 22041},
{ 1000, 1704, 3002, 6335, 8471, 10500, 14878, 16979, 20026, 22427},
{ 1646, 2286, 3109, 7245, 11493, 12791, 16824, 17667, 18981, 20222},
{ 1708, 2501, 3315, 6737, 8729, 9924, 16089, 17097, 18374, 19917},
{ 2623, 3510, 4478, 5645, 9862, 11115, 15219, 18067, 19583, 20382},
{ 2518, 3434, 4728, 6388, 8082, 9285, 13162, 18383, 19819, 20552},
{ 1726, 2383, 4090, 6303, 7805, 12845, 14612, 17608, 19269, 20181},
{ 2860, 3735, 4838, 6044, 7254, 8402, 14031, 16381, 18037, 19410},
{ 4247, 5993, 7952, 9792, 12342, 14653, 17527, 18774, 20831, 21699},
{ 3502, 4051, 5680, 6805, 8146, 11945, 16649, 17444, 20390, 21564},
{ 3151, 4893, 5899, 7198, 11418, 13073, 15124, 17673, 20520, 21861},
{ 3960, 4848, 5926, 7259, 8811, 10529, 15661, 16560, 18196, 20183},
{ 4499, 6604, 8036, 9251, 10804, 12627, 15880, 17512, 20020, 21046},
{ 4251, 5541, 6654, 8318, 9900, 11686, 15100, 17093, 20572, 21687},
{ 3769, 5327, 7865, 9360, 10684, 11818, 13660, 15366, 18733, 19882},
{ 3083, 3969, 6248, 8121, 9798, 10994, 12393, 13686, 17888, 19105},
{ 2731, 4670, 7063, 9201, 11346, 13735, 16875, 18797, 20787, 22360},
{ 1187, 2227, 4737, 7214, 9622, 12633, 15404, 17968, 20262, 23533},
{ 1911, 2477, 3915, 10098, 11616, 12955, 16223, 17138, 19270, 20729},
{ 1764, 2519, 3887, 6944, 9150, 12590, 16258, 16984, 17924, 18435},
{ 1400, 3674, 7131, 8718, 10688, 12508, 15708, 17711, 19720, 21068},
{ 2322, 3073, 4287, 8108, 9407, 10628, 15862, 16693, 19714, 21474},
{ 2630, 3339, 4758, 8360, 10274, 11333, 12880, 17374, 19221, 19936},
{ 1721, 2577, 5553, 7195, 8651, 10686, 15069, 16953, 18703, 19929}
};
/**
* second stage LSP codebook, high and low parts
(both 5-dimensional, with 32 entries (3.2.4 of G.729)
*/
static const int16_t cb_lsp_2nd[1<<VQ_2ND_BITS][10] = { /* (2.13) */
{ -435, -815, -742, 1033, -518, 582, -1201, 829, 86, 385},
{ -833, -891, 463, -8, -1251, 1450, 72, -231, 864, 661},
{-1021, 231, -306, 321, -220, -163, -526, -754, -1633, 267},
{ 57, -198, -339, -33, -1468, 573, 796, -169, -631, 816},
{ 171, -350, 294, 1660, 453, 519, 291, 159, -640, -1296},
{ -701, -842, -58, 950, 892, 1549, 715, 527, -714, -193},
{ 584, 31, -289, 356, -333, -457, 612, -283, -1381, -741},
{ -109, -808, 231, 77, -87, -344, 1341, 1087, -654, -569},
{ -859, 1236, 550, 854, 714, -543, -1752, -195, -98, -276},
{ -877, -954, -1248, -299, 212, -235, -728, 949, 1517, 895},
{ -77, 344, -620, 763, 413, 502, -362, -960, -483, 1386},
{ -314, -307, -256, -1260, -429, 450, -466, -108, 1010, 2223},
{ 711, 693, 521, 650, 1305, -28, -378, 744, -1005, 240},
{ -112, -271, -500, 946, 1733, 271, -15, 909, -259, 1688},
{ 575, -10, -468, -199, 1101, -1011, 581, -53, -747, 878},
{ 145, -285, -1280, -398, 36, -498, -1377, 18, -444, 1483},
{-1133, -835, 1350, 1284, -95, 1015, -222, 443, 372, -354},
{-1459, -1237, 416, -213, 466, 669, 659, 1640, 932, 534},
{ -15, 66, 468, 1019, -748, 1385, -182, -907, -721, -262},
{ -338, 148, 1445, 75, -760, 569, 1247, 337, 416, -121},
{ 389, 239, 1568, 981, 113, 369, -1003, -507, -587, -904},
{ -312, -98, 949, 31, 1104, 72, -141, 1465, 63, -785},
{ 1127, 584, 835, 277, -1159, 208, 301, -882, 117, -404},
{ 539, -114, 856, -493, 223, -912, 623, -76, 276, -440},
{ 2197, 2337, 1268, 670, 304, -267, -525, 140, 882, -139},
{-1596, 550, 801, -456, -56, -697, 865, 1060, 413, 446},
{ 1154, 593, -77, 1237, -31, 581, -1037, -895, 669, 297},
{ 397, 558, 203, -797, -919, 3, 692, -292, 1050, 782},
{ 334, 1475, 632, -80, 48, -1061, -484, 362, -597, -852},
{ -545, -330, -429, -680, 1133, -1182, -744, 1340, 262, 63},
{ 1320, 827, -398, -576, 341, -774, -483, -1247, -70, 98},
{ -163, 674, -11, -886, 531, -1125, -265, -242, 724, 934}
};
/**
* gain codebook (first stage), 8k mode (3.9.2 of G.729)
*/
static const int16_t cb_gain_1st_8k[1<<GC_1ST_IDX_BITS_8K][2] = { /*(0.14) (2.13) */
{ 3242 , 9949 },
{ 1551 , 2425 },
{ 2678 , 27162 },
{ 1921 , 9291 },
{ 1831 , 5022 },
{ 1 , 1516 },
{ 356 , 14756 },
{ 57 , 5404 },
};
/**
* gain codebook (second stage), 8k mode (3.9.2 of G.729)
*/
static const int16_t cb_gain_2nd_8k[1<<GC_2ND_IDX_BITS_8K][2] = { /*(1.14) (1.13) */
{ 5142 , 592 },
{ 17299 , 1861 },
{ 6160 , 2395 },
{ 16112 , 3392 },
{ 826 , 2005 },
{ 18973 , 5935 },
{ 1994 , 0 },
{ 15434 , 237 },
{ 10573 , 2966 },
{ 15132 , 4914 },
{ 11569 , 1196 },
{ 14194 , 1630 },
{ 8091 , 4861 },
{ 15161 , 14276 },
{ 9120 , 525 },
{ 13260 , 3256 },
};
/**
* gain codebook (first stage), 6.4k mode (D.3.9.2 of G.729)
*/
static const int16_t cb_gain_1st_6k4[1<<GC_1ST_IDX_BITS_6K4][2] =
{ /*(0.14) (1.14)*/
{ 5849, 0 },
{ 3171, 9280 },
{ 3617, 6747 },
{ 4987, 22294 },
{ 2929, 1078 },
{ 6068, 6093 },
{ 9425, 2731 },
{ 3915, 12872 },
};
/**
* gain codebook (second stage), 6.4k mode (D.3.9.2 of G.729)
*/
static const int16_t cb_gain_2nd_6k4[1<<GC_2ND_IDX_BITS_6K4][2] =
{ /*(1.14) (1.14)*/
{ 0, 4175 },
{10828, 27602 },
{16423, 15724 },
{ 4478, 7324 },
{ 3988, 0 },
{10291, 11385 },
{11956, 10735 },
{ 7876, 7821 },
};
/**
* 4th order Moving Average (MA) Predictor codebook (3.2.4 of G.729)
*
* float cb_ma_predictor_float[2][MA_NP][10] = {
* {
* {0.2570, 0.2780, 0.2800, 0.2736, 0.2757, 0.2764, 0.2675, 0.2678, 0.2779, 0.2647},
* {0.2142, 0.2194, 0.2331, 0.2230, 0.2272, 0.2252, 0.2148, 0.2123, 0.2115, 0.2096},
* {0.1670, 0.1523, 0.1567, 0.1580, 0.1601, 0.1569, 0.1589, 0.1555, 0.1474, 0.1571},
* {0.1238, 0.0925, 0.0798, 0.0923, 0.0890, 0.0828, 0.1010, 0.0988, 0.0872, 0.1060},
* },
* {
* {0.2360, 0.2405, 0.2499, 0.2495, 0.2517, 0.2591, 0.2636, 0.2625, 0.2551, 0.2310},
* {0.1285, 0.0925, 0.0779, 0.1060, 0.1183, 0.1176, 0.1277, 0.1268, 0.1193, 0.1211},
* {0.0981, 0.0589, 0.0401, 0.0654, 0.0761, 0.0728, 0.0841, 0.0826, 0.0776, 0.0891},
* {0.0923, 0.0486, 0.0287, 0.0498, 0.0526, 0.0482, 0.0621, 0.0636, 0.0584, 0.0794},
* },
* };
* 15
* cb_ma_predictor[j][k][i] = floor( 2 * cb_ma_predictor_float[j][k][i] )
*
* j=0..1, i=0..9, k=0..MA_NP-1
*/
static const int16_t cb_ma_predictor[2][MA_NP][10] = { /* (0.15) */
{
{ 8421, 9109, 9175, 8965, 9034, 9057, 8765, 8775, 9106, 8673},
{ 7018, 7189, 7638, 7307, 7444, 7379, 7038, 6956, 6930, 6868},
{ 5472, 4990, 5134, 5177, 5246, 5141, 5206, 5095, 4830, 5147},
{ 4056, 3031, 2614, 3024, 2916, 2713, 3309, 3237, 2857, 3473}
},
{
{ 7733, 7880, 8188, 8175, 8247, 8490, 8637, 8601, 8359, 7569},
{ 4210, 3031, 2552, 3473, 3876, 3853, 4184, 4154, 3909, 3968},
{ 3214, 1930, 1313, 2143, 2493, 2385, 2755, 2706, 2542, 2919},
{ 3024, 1592, 940, 1631, 1723, 1579, 2034, 2084, 1913, 2601}
}
};
/**
* 15 3
* cb_ma_predictor_sum[j][i] = floor( 2 * (1.0 - sum ( cb_ma_predictor_float[j][k][i] ) ) )
* k=0
* j=0..1, i=0..9
*/
static const int16_t cb_ma_predictor_sum[2][10] = { /* (0.15) */
{ 7798, 8447, 8205, 8293, 8126, 8477, 8447, 8703, 9043, 8604},
{14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708}
};
/**
* 12
* 2
* cb_ma_predictor_sum_inv[j][i] = floor(---------------------------------------------)
* 3
* 1.0 - sum ( cb_ma_predictor_float[j][k][i] )
* k=0
* j=0..1, i=0..9
*/
static const int16_t cb_ma_predictor_sum_inv[2][10] = { /* (3.12) */
{17210, 15888, 16357, 16183, 16516, 15833, 15888, 15421, 14840, 15597},
{ 9202, 7320, 6788, 7738, 8170, 8154, 8856, 8818, 8366, 8544}
};
/**
* MA prediction coefficients (3.9.1 of G.729, near Equation 69)
*/
static const uint16_t ma_prediction_coeff[4] = { /* (0.13) */
5571, 4751, 2785, 1556
};
/**
* initial LSP coefficients belongs to virtual frame preceding the
* first frame of the stream
*/
static const int16_t lsp_init[10]= { /* (0.15) */
30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000,-26000
};
/**
* additional "phase" post-processing filter impulse response (D.6.2 of G.729)
*
* Table contains three impulse responses, correspond to
* different amounts of spreading.
*/
static const int16_t phase_filter[3][40] =
{
{ // maximum spreading (for noise-like segments)
14690, 11518, 1268, -2762, -5672, 7514, -36, -2808, -3041, 4823,
2952, -8425, 3785, 1455, 2179, -8638, 8051, -2104, -1455, 777,
1108, -2386, 2254, -364, -675, -2104, 6046, -5682, 1072, 3123,
-5059, 5312, -2330, -3729, 6924, -3890, 675, -1776, 29, 10145,
},
{ // medium spreading
30274, 3831, -4037, 2972, -1049, -1003, 2477, -3044, 2815, -2232,
1753, -1612, 1714, -1776, 1543, -1009, 429, -170, 472, -1265,
2176, -2707, 2523, -1622, 344, 826, -1530, 1724, -1658, 1701,
-2064, 2644, -3061, 2897, -1979, 557, 780, -1370, 842, 655,
},
{ // no spreading (for voiced speech)
32767, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
}
};
#endif /* AVCODEC_G729DATA_H */

View File

@ -0,0 +1,728 @@
/*
* 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
*/
#include <inttypes.h>
#include <string.h>
#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<subframe_size; i++)
{
out[i] = in[i];
out[i] -= (gain_code * fc_cur[i] + 0x2000) >> 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; j<SUBFRAME_SIZE; j++)
gain_after += FFABS(synth[j+10]);
ctx->gain_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,
};

View File

@ -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 <inttypes.h>
#include <limits.h>
#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<subframe_size + RES_PREV_DATA_SIZE; i++)
tmp |= FFABS(residual[i]);
if(!tmp)
shift = 3;
else
shift = av_log2(tmp) - 11;
if (shift > 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;
}

View File

@ -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 <stdint.h>
#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

View File

@ -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 */

View File

@ -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,
};

View File

@ -0,0 +1,138 @@
/*
* gsm 06.10 decoder
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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

View File

@ -0,0 +1,94 @@
/*
* gsm 06.10 decoder data
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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 <stdint.h>
#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}
};

View File

@ -0,0 +1,43 @@
/*
* gsm 06.10 decoder data
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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 <stdint.h>
#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 */

View File

@ -0,0 +1,151 @@
/*
* gsm 06.10 decoder
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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;
}

View File

@ -0,0 +1,294 @@
/*
* LPC utility code
* Copyright (c) 2006 Justin Ruggles <justin.ruggles@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
*/
#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<n2; i++) {
w = c - n2 + i;
w = 1.0 - (w * w);
w_data[-i-1] = data[-i-1] * w;
w_data[+i ] = data[+i ] * w;
}
}
/**
* Calculate autocorrelation data from audio samples
* A Welch window function is applied before calculation.
*/
static void lpc_compute_autocorr_c(const double *data, int len, int lag,
double *autoc)
{
int i, j;
for(j=0; j<lag; j+=2){
double sum0 = 1.0, sum1 = 1.0;
for(i=j; i<len; i++){
sum0 += data[i] * data[i-j];
sum1 += data[i] * data[i-j-1];
}
autoc[j ] = sum0;
autoc[j+1] = sum1;
}
if(j==lag){
double sum = 1.0;
for(i=j-1; i<len; i+=2){
sum += data[i ] * data[i-j ]
+ data[i+1] * data[i-j+1];
}
autoc[j] = sum;
}
}
/**
* Quantize LPC coefficients
*/
static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
int32_t *lpc_out, int *shift, int max_shift, int zero_shift)
{
int i;
double cmax, error;
int32_t qmax;
int sh;
/* define maximum levels */
qmax = (1 << (precision - 1)) - 1;
/* find maximum coefficient value */
cmax = 0.0;
for(i=0; i<order; i++) {
cmax= FFMAX(cmax, fabs(lpc_in[i]));
}
/* if maximum value quantizes to zero, return all zeros */
if(cmax * (1 << max_shift) < 1.0) {
*shift = zero_shift;
memset(lpc_out, 0, sizeof(int32_t) * order);
return;
}
/* calculate level shift which scales max coeff to available bits */
sh = max_shift;
while((cmax * (1 << sh) > 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<order; i++) {
lpc_in[i] *= scale;
}
}
/* output quantized coefficients and level shift */
error=0;
for(i=0; i<order; i++) {
error -= lpc_in[i] * (1 << sh);
lpc_out[i] = av_clip(lrintf(error), -qmax, qmax);
error -= lpc_out[i];
}
*shift = sh;
}
static int estimate_best_order(double *ref, int min_order, int max_order)
{
int i, est;
est = min_order;
for(i=max_order-1; 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<max_order; i++)
ref[i] = fabs(lpc[i][i]);
pass++;
}
if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
LLSModel m[2];
LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]);
double av_uninit(weight);
memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var));
for(j=0; j<max_order; j++)
m[0].coeff[max_order-1][j] = -lpc[max_order-1][j];
for(; pass<lpc_passes; pass++){
avpriv_init_lls(&m[pass&1], max_order);
weight=0;
for(i=max_order; i<blocksize; i++){
for(j=0; j<=max_order; j++)
var[j]= samples[i-j];
if(pass){
double eval, inv, rinv;
eval= m[pass&1].evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
eval= (512>>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; i<max_order; i++){
for(j=0; j<max_order; j++)
lpc[i][j]=-m[(pass-1)&1].coeff[i][j];
ref[i]= sqrt(m[(pass-1)&1].variance[i] / weight) * (blocksize - max_order) / 4000;
}
for(i=max_order-1; i>0; 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; i<max_order; i++) {
quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
}
}
return opt_order;
}
av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order,
enum FFLPCType lpc_type)
{
s->blocksize = 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);
}

View File

@ -0,0 +1,197 @@
/*
* LPC utility code
* Copyright (c) 2006 Justin Ruggles <justin.ruggles@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
*/
#ifndef AVCODEC_LPC_H
#define AVCODEC_LPC_H
#include <stdint.h>
#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<max_order; i++) {
LPC_TYPE r = -autoc[i];
if (normalize) {
for(j=0; j<i; j++)
r -= lpc_last[j] * autoc[i-j-1];
r /= err;
err *= 1.0 - (r * r);
}
lpc[i] = r;
for(j=0; j < (i+1)>>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 */

View File

@ -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;
}

View File

@ -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 },
};

View File

@ -0,0 +1,38 @@
/*
* gsm 06.10 decoder, Microsoft variant
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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);
}

View File

@ -0,0 +1,30 @@
/*
* gsm 06.10 decoder, Microsoft variant
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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 */

View File

@ -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");

View File

@ -0,0 +1,39 @@
/*
* Generate a header file for hardcoded PCM tables
*
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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 <stdlib.h>
#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;
}

View File

@ -0,0 +1,119 @@
/*
* Header file for hardcoded PCM tables
*
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
*
* 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 <stdint.h>
#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<v;j++) {
linear_to_xlaw[8192 + j] = (i ^ mask);
if (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 */

View File

@ -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 <alex.converse@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
*/
#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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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,
};

View File

@ -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 <stdint.h>
/* 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 */

View File

@ -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; j<lag; j+=2){
x86_reg i = -len*sizeof(double);
if(j == lag-2) {
__asm__ volatile(
"movsd "MANGLE(pd_1)", %%xmm0 \n\t"
"movsd "MANGLE(pd_1)", %%xmm1 \n\t"
"movsd "MANGLE(pd_1)", %%xmm2 \n\t"
"1: \n\t"
"movapd (%2,%0), %%xmm3 \n\t"
"movupd -8(%3,%0), %%xmm4 \n\t"
"movapd (%3,%0), %%xmm5 \n\t"
"mulpd %%xmm3, %%xmm4 \n\t"
"mulpd %%xmm3, %%xmm5 \n\t"
"mulpd -16(%3,%0), %%xmm3 \n\t"
"addpd %%xmm4, %%xmm1 \n\t"
"addpd %%xmm5, %%xmm0 \n\t"
"addpd %%xmm3, %%xmm2 \n\t"
"add $16, %0 \n\t"
"jl 1b \n\t"
"movhlps %%xmm0, %%xmm3 \n\t"
"movhlps %%xmm1, %%xmm4 \n\t"
"movhlps %%xmm2, %%xmm5 \n\t"
"addsd %%xmm3, %%xmm0 \n\t"
"addsd %%xmm4, %%xmm1 \n\t"
"addsd %%xmm5, %%xmm2 \n\t"
"movsd %%xmm0, (%1) \n\t"
"movsd %%xmm1, 8(%1) \n\t"
"movsd %%xmm2, 16(%1) \n\t"
:"+&r"(i)
:"r"(autoc+j), "r"(data+len), "r"(data+len-j)
:"memory"
);
} else {
__asm__ volatile(
"movsd "MANGLE(pd_1)", %%xmm0 \n\t"
"movsd "MANGLE(pd_1)", %%xmm1 \n\t"
"1: \n\t"
"movapd (%3,%0), %%xmm3 \n\t"
"movupd -8(%4,%0), %%xmm4 \n\t"
"mulpd %%xmm3, %%xmm4 \n\t"
"mulpd (%4,%0), %%xmm3 \n\t"
"addpd %%xmm4, %%xmm1 \n\t"
"addpd %%xmm3, %%xmm0 \n\t"
"add $16, %0 \n\t"
"jl 1b \n\t"
"movhlps %%xmm0, %%xmm3 \n\t"
"movhlps %%xmm1, %%xmm4 \n\t"
"addsd %%xmm3, %%xmm0 \n\t"
"addsd %%xmm4, %%xmm1 \n\t"
"movsd %%xmm0, %1 \n\t"
"movsd %%xmm1, %2 \n\t"
:"+&r"(i), "=m"(autoc[j]), "=m"(autoc[j+1])
:"r"(data+len), "r"(data+len-j)
);
}
}
}
#endif /* HAVE_SSE2_INLINE */
av_cold void ff_lpc_init_x86(LPCContext *c)
{
#if HAVE_SSE2_INLINE
int cpu_flags = av_get_cpu_flags();
if (HAVE_SSE2_INLINE && cpu_flags & (AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW)) {
c->lpc_apply_welch_window = lpc_apply_welch_window_sse2;
c->lpc_compute_autocorr = lpc_compute_autocorr_sse2;
}
#endif /* HAVE_SSE2_INLINE */
}

View File

@ -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++) {

View File

@ -0,0 +1,76 @@
/*
* AAC Spectral Band Replication decoding functions
* Copyright (c) 2012 Christophe Gisquet <christophe.gisquet@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
*/
#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;
}
}

View File

@ -0,0 +1,101 @@
/*
* raw ADTS AAC demuxer
* Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
* 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,
};

View File

@ -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

View File

@ -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);

View File

@ -0,0 +1,241 @@
/*
* IEC 61937 demuxer
* Copyright (c) 2010 Anssi Hannula <anssi.hannula at iki.fi>
*
* 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,
};

View File

@ -0,0 +1,180 @@
/*
* linear least squares model
*
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
*
* 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 <math.h>
#include <string.h>
#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 <stdio.h>
#include <limits.h>
#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

View File

@ -0,0 +1,71 @@
/*
* linear least squares model
*
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
*
* 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 */

View File

@ -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;
}
}

View File

@ -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];
}