Added a whole bunch of formats for WAV support
parent
21b78fde9f
commit
570fd380f8
|
@ -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 */,
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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,
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
||||
};
|
|
@ -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
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
@ -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 */
|
|
@ -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 }
|
||||
};
|
|
@ -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 */
|
|
@ -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));
|
||||
}
|
|
@ -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 */
|
|
@ -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 },
|
||||
};
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
|
@ -2224,18 +2227,20 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
|||
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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,
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 */
|
|
@ -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,
|
||||
};
|
|
@ -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
|
|
@ -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}
|
||||
};
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 */
|
|
@ -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");
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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 */
|
|
@ -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 */
|
||||
}
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue