mirror of
https://github.com/godotengine/godot.git
synced 2024-11-24 13:12:42 +00:00
Merge pull request #6830 from akien-mga/thirdparty
Move most "drivers" as toggleable "modules" and split their thirdparty libraries in an own tree
This commit is contained in:
commit
89132224a6
77
SConstruct
77
SConstruct
@ -119,23 +119,20 @@ opts.Add('platform','Platform: '+str(platform_list)+'.',"")
|
||||
opts.Add('p','Platform (same as platform=).',"")
|
||||
opts.Add('tools','Build Tools (Including Editor): (yes/no)','yes')
|
||||
opts.Add('gdscript','Build GDSCript support: (yes/no)','yes')
|
||||
opts.Add('vorbis','Build Ogg Vorbis Support: (yes/no)','yes')
|
||||
opts.Add('opus','Build Opus Audio Format Support: (yes/no)','yes')
|
||||
opts.Add('libogg','Ogg library for ogg container support (system/builtin)','builtin')
|
||||
opts.Add('libvorbis','Ogg Vorbis library for vorbis support (system/builtin)','builtin')
|
||||
opts.Add('libtheora','Theora library for theora module (system/builtin)','builtin')
|
||||
opts.Add('opus','Opus and opusfile library for Opus format support: (system/builtin)','builtin')
|
||||
opts.Add('minizip','Build Minizip Archive Support: (yes/no)','yes')
|
||||
opts.Add('squish','Squish BC Texture Compression in editor (yes/no)','yes')
|
||||
opts.Add('theora','Theora Video (yes/no)','yes')
|
||||
opts.Add('theoralib','Theora Video (yes/no)','no')
|
||||
opts.Add('freetype','Freetype support in editor','builtin')
|
||||
opts.Add('squish','Squish library for BC Texture Compression in editor (system/builtin)','builtin')
|
||||
opts.Add('freetype','Freetype library for TTF support via freetype module (system/builtin)','builtin')
|
||||
opts.Add('xml','XML Save/Load support (yes/no)','yes')
|
||||
opts.Add('png','PNG Image loader support (yes/no)','yes')
|
||||
opts.Add('jpg','JPG Image loader support (yes/no)','yes')
|
||||
opts.Add('webp','WEBP Image loader support (yes/no)','yes')
|
||||
opts.Add('dds','DDS Texture loader support (yes/no)','yes')
|
||||
opts.Add('pvr','PVR (PowerVR) Texture loader support (yes/no)','yes')
|
||||
opts.Add('etc1','etc1 Texture compression support (yes/no)','yes')
|
||||
opts.Add('builtin_zlib','Use built-in zlib (yes/no)','yes')
|
||||
opts.Add('openssl','Use OpenSSL (yes/no/builtin)','no')
|
||||
opts.Add('musepack','Musepack Audio (yes/no)','yes')
|
||||
opts.Add('libpng','libpng library for image loader support (system/builtin)','builtin')
|
||||
opts.Add('libwebp','libwebp library for webp module (system/builtin)','builtin')
|
||||
opts.Add('openssl','OpenSSL library for openssl module (system/builtin)','builtin')
|
||||
opts.Add('libmpcdec','libmpcdec library for mpc module (system/builtin)','builtin')
|
||||
opts.Add('enet','ENet library (system/builtin)','builtin')
|
||||
opts.Add('glew','GLEW library for the gl_context (system/builtin)','builtin')
|
||||
opts.Add("CXX", "C++ Compiler")
|
||||
opts.Add("CC", "C Compiler")
|
||||
opts.Add("CCFLAGS", "Custom flags for the C++ compiler");
|
||||
@ -157,7 +154,7 @@ for k in platform_opts.keys():
|
||||
opts.Add(o[0],o[1],o[2])
|
||||
|
||||
for x in module_list:
|
||||
opts.Add('module_'+x+'_enabled', "Enable module '"+x+"'.", "yes")
|
||||
opts.Add('module_'+x+'_enabled', "Enable module '"+x+"' (yes/no)", "yes")
|
||||
|
||||
opts.Update(env_base) # update environment
|
||||
Help(opts.GenerateHelpText(env_base)) # generate help
|
||||
@ -253,14 +250,6 @@ if selected_platform in platform_list:
|
||||
#must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
|
||||
detect.configure(env)
|
||||
|
||||
|
||||
if (env["freetype"]!="no"):
|
||||
env.Append(CCFLAGS=['-DFREETYPE_ENABLED'])
|
||||
if (env["freetype"]=="builtin"):
|
||||
env.Append(CPPPATH=['#drivers/freetype'])
|
||||
env.Append(CPPPATH=['#drivers/freetype/freetype/include'])
|
||||
|
||||
|
||||
#env['platform_libsuffix'] = env['LIBSUFFIX']
|
||||
|
||||
suffix="."+selected_platform
|
||||
@ -321,46 +310,9 @@ if selected_platform in platform_list:
|
||||
if (env.use_ptrcall):
|
||||
env.Append(CPPFLAGS=['-DPTRCALL_ENABLED']);
|
||||
|
||||
if (env['musepack']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DMUSEPACK_ENABLED']);
|
||||
|
||||
#if (env['openssl']!='no'):
|
||||
# env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
||||
# if (env['openssl']=="builtin"):
|
||||
# env.Append(CPPPATH=['#drivers/builtin_openssl2'])
|
||||
|
||||
if (env["builtin_zlib"]=='yes'):
|
||||
env.Append(CPPPATH=['#drivers/builtin_zlib/zlib'])
|
||||
|
||||
# to test 64 bits compiltion
|
||||
# env.Append(CPPFLAGS=['-m64'])
|
||||
|
||||
if (env_base['squish']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DSQUISH_ENABLED']);
|
||||
|
||||
if (env['vorbis']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DVORBIS_ENABLED']);
|
||||
if (env['opus']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DOPUS_ENABLED']);
|
||||
|
||||
|
||||
if (env['theora']=='yes'):
|
||||
env['theoralib']='yes'
|
||||
env.Append(CPPFLAGS=['-DTHEORA_ENABLED']);
|
||||
if (env['theoralib']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DTHEORALIB_ENABLED']);
|
||||
|
||||
if (env['png']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DPNG_ENABLED']);
|
||||
if (env['dds']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DDDS_ENABLED']);
|
||||
if (env['pvr']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DPVR_ENABLED']);
|
||||
if (env['jpg']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DJPG_ENABLED']);
|
||||
if (env['webp']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DWEBP_ENABLED']);
|
||||
|
||||
if (env['tools']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DTOOLS_ENABLED'])
|
||||
if (env['disable_3d']=='yes'):
|
||||
@ -379,9 +331,6 @@ if selected_platform in platform_list:
|
||||
if (env['colored']=='yes'):
|
||||
methods.colored(sys,env)
|
||||
|
||||
if (env['etc1']=='yes'):
|
||||
env.Append(CPPFLAGS=['-DETC1_ENABLED'])
|
||||
|
||||
Export('env')
|
||||
|
||||
#build subdirs, the build order is dependent on link order.
|
||||
|
97
drivers/SCsub
vendored
97
drivers/SCsub
vendored
@ -1,78 +1,47 @@
|
||||
Import('env')
|
||||
|
||||
env_drivers = env.Clone()
|
||||
|
||||
env.drivers_sources=[]
|
||||
#env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
env_drivers.Append(CPPPATH=["vorbis"])
|
||||
|
||||
Export('env_drivers')
|
||||
if ("builtin_zlib" in env and env["builtin_zlib"] == "yes"):
|
||||
SConscript("zlib/SCsub");
|
||||
|
||||
# OS drivers
|
||||
SConscript('unix/SCsub');
|
||||
SConscript('windows/SCsub');
|
||||
|
||||
# Sounds drivers
|
||||
SConscript('alsa/SCsub');
|
||||
SConscript('pulseaudio/SCsub');
|
||||
SConscript('windows/SCsub');
|
||||
if (env["platform"] == "windows"):
|
||||
SConscript("rtaudio/SCsub");
|
||||
|
||||
# Graphics drivers
|
||||
SConscript('gles2/SCsub');
|
||||
SConscript('gl_context/SCsub');
|
||||
SConscript('pnm/SCsub');
|
||||
|
||||
if (env['openssl']!='no'):
|
||||
env.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
||||
env_drivers.Append(CPPFLAGS=['-DOPENSSL_ENABLED']);
|
||||
if (env['openssl']=="builtin"):
|
||||
env_drivers.Append(CPPPATH=['#drivers/builtin_openssl2'])
|
||||
SConscript("builtin_openssl2/SCsub");
|
||||
|
||||
SConscript('openssl/SCsub')
|
||||
|
||||
|
||||
if (env["png"]=="yes"):
|
||||
SConscript("png/SCsub");
|
||||
if (env["jpg"]=="yes"):
|
||||
#SConscript("jpg/SCsub");
|
||||
SConscript("jpegd/SCsub");
|
||||
if (env["webp"]=="yes"):
|
||||
SConscript("webp/SCsub");
|
||||
SConscript("dds/SCsub");
|
||||
SConscript("pvr/SCsub");
|
||||
SConscript("etc1/SCsub")
|
||||
if (env["builtin_zlib"]=="yes"):
|
||||
SConscript("builtin_zlib/SCsub");
|
||||
|
||||
SConscript("rtaudio/SCsub");
|
||||
# Core dependencies
|
||||
SConscript("png/SCsub");
|
||||
SConscript("nrex/SCsub");
|
||||
SConscript("chibi/SCsub");
|
||||
if (env["vorbis"]=="yes" or env["theoralib"]=="yes" or env["opus"]=="yes"):
|
||||
SConscript("ogg/SCsub");
|
||||
if (env["vorbis"]=="yes"):
|
||||
SConscript("vorbis/SCsub");
|
||||
if (env["opus"]=="yes"):
|
||||
SConscript('opus/SCsub');
|
||||
|
||||
# Tools override
|
||||
# FIXME: Should likely be integrated in the tools/ codebase
|
||||
if (env["tools"]=="yes"):
|
||||
SConscript("convex_decomp/SCsub");
|
||||
|
||||
if (env["theoralib"]=="yes"):
|
||||
SConscript("theora/SCsub");
|
||||
if (env['musepack']=='yes'):
|
||||
SConscript("mpc/SCsub");
|
||||
if (env["squish"]=="yes" and env["tools"]=="yes"):
|
||||
SConscript("squish/SCsub");
|
||||
if (env["freetype"]!="no"):
|
||||
SConscript("freetype/SCsub");
|
||||
|
||||
num = 0
|
||||
cur_base = ""
|
||||
total = len(env.drivers_sources)
|
||||
max_src = 64
|
||||
list = []
|
||||
lib_list = []
|
||||
|
||||
import string
|
||||
|
||||
if env['vsproj']=="yes":
|
||||
env.AddToVSProject(env.drivers_sources)
|
||||
|
||||
if (env.split_drivers): #split drivers, this used to be needed for windows until separate builders for windows were created
|
||||
|
||||
# Split drivers, this used to be needed for windows until separate builders for windows were created
|
||||
# FIXME: Check if still needed now that the drivers were made more lightweight
|
||||
if (env.split_drivers):
|
||||
import string
|
||||
|
||||
num = 0
|
||||
cur_base = ""
|
||||
max_src = 64
|
||||
list = []
|
||||
lib_list = []
|
||||
|
||||
for f in env.drivers_sources:
|
||||
fname = ""
|
||||
@ -84,14 +53,14 @@ if (env.split_drivers): #split drivers, this used to be needed for windows until
|
||||
base = string.join(fname.split("/")[:2], "/")
|
||||
if base != cur_base and len(list) > max_src:
|
||||
if num > 0:
|
||||
lib = env_drivers.Library("drivers"+str(num), list)
|
||||
lib = env.Library("drivers"+str(num), list)
|
||||
lib_list.append(lib)
|
||||
list = []
|
||||
num = num+1
|
||||
cur_base = base
|
||||
list.append(f)
|
||||
|
||||
lib = env_drivers.Library("drivers"+str(num), list)
|
||||
lib = env.Library("drivers"+str(num), list)
|
||||
lib_list.append(lib)
|
||||
|
||||
if len(lib_list) > 0:
|
||||
@ -99,15 +68,15 @@ if (env.split_drivers): #split drivers, this used to be needed for windows until
|
||||
if os.name=='posix' and sys.platform=='msys':
|
||||
env.Replace(ARFLAGS=['rcsT'])
|
||||
|
||||
lib = env_drivers.Library("drivers_collated", lib_list)
|
||||
lib = env.Library("drivers_collated", lib_list)
|
||||
lib_list = [lib]
|
||||
|
||||
drivers_base=[]
|
||||
env_drivers.add_source_files(drivers_base,"*.cpp")
|
||||
lib_list.insert(0, env_drivers.Library("drivers", drivers_base))
|
||||
env.add_source_files(drivers_base,"*.cpp")
|
||||
lib_list.insert(0, env.Library("drivers", drivers_base))
|
||||
|
||||
env.Prepend(LIBS=lib_list)
|
||||
else:
|
||||
env_drivers.add_source_files(env.drivers_sources,"*.cpp")
|
||||
lib = env_drivers.Library("drivers",env.drivers_sources)
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
lib = env.Library("drivers",env.drivers_sources)
|
||||
env.Prepend(LIBS=[lib])
|
||||
|
@ -1,5 +1,5 @@
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
@ -1,663 +0,0 @@
|
||||
Import('env')
|
||||
Import('env_drivers')
|
||||
|
||||
openssl_sources = [
|
||||
"ssl/t1_lib.c",
|
||||
"ssl/t1_ext.c",
|
||||
"ssl/s3_srvr.c",
|
||||
"ssl/t1_enc.c",
|
||||
"ssl/t1_meth.c",
|
||||
"ssl/s23_clnt.c",
|
||||
"ssl/ssl_asn1.c",
|
||||
"ssl/tls_srp.c",
|
||||
"ssl/kssl.c",
|
||||
"ssl/d1_both.c",
|
||||
"ssl/t1_clnt.c",
|
||||
"ssl/bio_ssl.c",
|
||||
"ssl/d1_srtp.c",
|
||||
"ssl/t1_reneg.c",
|
||||
"ssl/ssl_cert.c",
|
||||
"ssl/s3_lib.c",
|
||||
"ssl/d1_srvr.c",
|
||||
"ssl/s23_meth.c",
|
||||
"ssl/ssl_stat.c",
|
||||
"ssl/ssl_err.c",
|
||||
"ssl/ssl_algs.c",
|
||||
"ssl/s3_cbc.c",
|
||||
"ssl/d1_clnt.c",
|
||||
"ssl/s3_pkt.c",
|
||||
"ssl/d1_meth.c",
|
||||
"ssl/s3_both.c",
|
||||
"ssl/s2_enc.c",
|
||||
"ssl/s3_meth.c",
|
||||
"ssl/s3_enc.c",
|
||||
"ssl/s23_pkt.c",
|
||||
"ssl/s2_pkt.c",
|
||||
"ssl/d1_pkt.c",
|
||||
"ssl/ssl_rsa.c",
|
||||
"ssl/s23_srvr.c",
|
||||
"ssl/s2_meth.c",
|
||||
"ssl/s3_clnt.c",
|
||||
"ssl/s23_lib.c",
|
||||
"ssl/t1_srvr.c",
|
||||
"ssl/ssl_lib.c",
|
||||
"ssl/ssl_txt.c",
|
||||
"ssl/s2_srvr.c",
|
||||
"ssl/ssl_sess.c",
|
||||
"ssl/s2_clnt.c",
|
||||
"ssl/d1_lib.c",
|
||||
"ssl/s2_lib.c",
|
||||
"ssl/ssl_err2.c",
|
||||
"ssl/ssl_ciph.c",
|
||||
"crypto/dsa/dsa_lib.c",
|
||||
"crypto/dsa/dsa_pmeth.c",
|
||||
"crypto/dsa/dsa_ossl.c",
|
||||
"crypto/dsa/dsa_gen.c",
|
||||
"crypto/dsa/dsa_asn1.c",
|
||||
"crypto/dsa/dsa_prn.c",
|
||||
"crypto/dsa/dsa_sign.c",
|
||||
"crypto/dsa/dsa_key.c",
|
||||
"crypto/dsa/dsa_vrf.c",
|
||||
"crypto/dsa/dsa_err.c",
|
||||
"crypto/dsa/dsa_ameth.c",
|
||||
"crypto/dsa/dsa_depr.c",
|
||||
"crypto/x509/x509_lu.c",
|
||||
"crypto/x509/x509cset.c",
|
||||
"crypto/x509/x509_set.c",
|
||||
"crypto/x509/x509_d2.c",
|
||||
"crypto/x509/x509_txt.c",
|
||||
"crypto/x509/x509rset.c",
|
||||
"crypto/x509/by_dir.c",
|
||||
"crypto/x509/x509_vpm.c",
|
||||
"crypto/x509/x509_vfy.c",
|
||||
"crypto/x509/x509_trs.c",
|
||||
"crypto/x509/by_file.c",
|
||||
"crypto/x509/x509_obj.c",
|
||||
"crypto/x509/x509spki.c",
|
||||
"crypto/x509/x509_v3.c",
|
||||
"crypto/x509/x509_req.c",
|
||||
"crypto/x509/x509_att.c",
|
||||
"crypto/x509/x_all.c",
|
||||
"crypto/x509/x509_ext.c",
|
||||
"crypto/x509/x509type.c",
|
||||
"crypto/x509/x509_def.c",
|
||||
"crypto/x509/x509_err.c",
|
||||
"crypto/x509/x509name.c",
|
||||
"crypto/x509/x509_r2x.c",
|
||||
"crypto/x509/x509_cmp.c",
|
||||
"crypto/asn1/x_pkey.c",
|
||||
"crypto/asn1/a_gentm.c",
|
||||
"crypto/asn1/x_sig.c",
|
||||
"crypto/asn1/t_req.c",
|
||||
"crypto/asn1/t_pkey.c",
|
||||
"crypto/asn1/p8_pkey.c",
|
||||
"crypto/asn1/a_i2d_fp.c",
|
||||
"crypto/asn1/x_val.c",
|
||||
"crypto/asn1/f_string.c",
|
||||
"crypto/asn1/p5_pbe.c",
|
||||
"crypto/asn1/bio_ndef.c",
|
||||
"crypto/asn1/a_bool.c",
|
||||
"crypto/asn1/asn1_gen.c",
|
||||
"crypto/asn1/x_algor.c",
|
||||
"crypto/asn1/bio_asn1.c",
|
||||
"crypto/asn1/asn_mime.c",
|
||||
"crypto/asn1/t_x509.c",
|
||||
"crypto/asn1/a_strex.c",
|
||||
"crypto/asn1/x_nx509.c",
|
||||
"crypto/asn1/asn1_err.c",
|
||||
"crypto/asn1/x_crl.c",
|
||||
"crypto/asn1/a_print.c",
|
||||
"crypto/asn1/a_type.c",
|
||||
"crypto/asn1/tasn_new.c",
|
||||
"crypto/asn1/n_pkey.c",
|
||||
"crypto/asn1/x_bignum.c",
|
||||
"crypto/asn1/asn_pack.c",
|
||||
"crypto/asn1/evp_asn1.c",
|
||||
"crypto/asn1/t_bitst.c",
|
||||
"crypto/asn1/x_req.c",
|
||||
"crypto/asn1/a_time.c",
|
||||
"crypto/asn1/x_name.c",
|
||||
"crypto/asn1/x_pubkey.c",
|
||||
"crypto/asn1/tasn_typ.c",
|
||||
"crypto/asn1/asn_moid.c",
|
||||
"crypto/asn1/a_utctm.c",
|
||||
"crypto/asn1/asn1_lib.c",
|
||||
"crypto/asn1/x_x509a.c",
|
||||
"crypto/asn1/a_set.c",
|
||||
"crypto/asn1/t_crl.c",
|
||||
"crypto/asn1/p5_pbev2.c",
|
||||
"crypto/asn1/tasn_enc.c",
|
||||
"crypto/asn1/a_mbstr.c",
|
||||
"crypto/asn1/tasn_dec.c",
|
||||
"crypto/asn1/x_x509.c",
|
||||
"crypto/asn1/a_octet.c",
|
||||
"crypto/asn1/x_long.c",
|
||||
"crypto/asn1/a_bytes.c",
|
||||
"crypto/asn1/t_x509a.c",
|
||||
"crypto/asn1/a_enum.c",
|
||||
"crypto/asn1/a_int.c",
|
||||
"crypto/asn1/tasn_prn.c",
|
||||
"crypto/asn1/i2d_pr.c",
|
||||
"crypto/asn1/a_utf8.c",
|
||||
"crypto/asn1/t_spki.c",
|
||||
"crypto/asn1/a_digest.c",
|
||||
"crypto/asn1/a_dup.c",
|
||||
"crypto/asn1/i2d_pu.c",
|
||||
"crypto/asn1/a_verify.c",
|
||||
"crypto/asn1/f_enum.c",
|
||||
"crypto/asn1/a_sign.c",
|
||||
"crypto/asn1/d2i_pr.c",
|
||||
"crypto/asn1/asn1_par.c",
|
||||
"crypto/asn1/x_spki.c",
|
||||
"crypto/asn1/a_d2i_fp.c",
|
||||
"crypto/asn1/f_int.c",
|
||||
"crypto/asn1/x_exten.c",
|
||||
"crypto/asn1/tasn_utl.c",
|
||||
"crypto/asn1/nsseq.c",
|
||||
"crypto/asn1/a_bitstr.c",
|
||||
"crypto/asn1/x_info.c",
|
||||
"crypto/asn1/a_strnid.c",
|
||||
"crypto/asn1/a_object.c",
|
||||
"crypto/asn1/tasn_fre.c",
|
||||
"crypto/asn1/d2i_pu.c",
|
||||
"crypto/asn1/ameth_lib.c",
|
||||
"crypto/asn1/x_attrib.c",
|
||||
"crypto/evp/m_sha.c",
|
||||
"crypto/evp/e_camellia.c",
|
||||
"crypto/evp/e_aes.c",
|
||||
"crypto/evp/bio_b64.c",
|
||||
"crypto/evp/m_sigver.c",
|
||||
"crypto/evp/m_wp.c",
|
||||
"crypto/evp/m_sha1.c",
|
||||
"crypto/evp/p_seal.c",
|
||||
"crypto/evp/c_alld.c",
|
||||
"crypto/evp/p5_crpt.c",
|
||||
"crypto/evp/e_rc4.c",
|
||||
"crypto/evp/m_ecdsa.c",
|
||||
"crypto/evp/bio_enc.c",
|
||||
"crypto/evp/e_des3.c",
|
||||
"crypto/evp/m_null.c",
|
||||
"crypto/evp/bio_ok.c",
|
||||
"crypto/evp/pmeth_gn.c",
|
||||
"crypto/evp/e_rc5.c",
|
||||
"crypto/evp/e_rc2.c",
|
||||
"crypto/evp/p_dec.c",
|
||||
"crypto/evp/p_verify.c",
|
||||
"crypto/evp/e_rc4_hmac_md5.c",
|
||||
"crypto/evp/pmeth_lib.c",
|
||||
"crypto/evp/m_ripemd.c",
|
||||
"crypto/evp/m_md5.c",
|
||||
"crypto/evp/e_bf.c",
|
||||
"crypto/evp/p_enc.c",
|
||||
"crypto/evp/m_dss.c",
|
||||
"crypto/evp/bio_md.c",
|
||||
"crypto/evp/evp_pbe.c",
|
||||
"crypto/evp/e_seed.c",
|
||||
"crypto/evp/e_cast.c",
|
||||
"crypto/evp/p_open.c",
|
||||
"crypto/evp/p5_crpt2.c",
|
||||
"crypto/evp/m_dss1.c",
|
||||
"crypto/evp/names.c",
|
||||
"crypto/evp/evp_acnf.c",
|
||||
"crypto/evp/e_des.c",
|
||||
"crypto/evp/evp_cnf.c",
|
||||
"crypto/evp/evp_lib.c",
|
||||
"crypto/evp/digest.c",
|
||||
"crypto/evp/evp_err.c",
|
||||
"crypto/evp/evp_enc.c",
|
||||
"crypto/evp/e_old.c",
|
||||
"crypto/evp/c_all.c",
|
||||
"crypto/evp/m_md2.c",
|
||||
"crypto/evp/e_xcbc_d.c",
|
||||
"crypto/evp/pmeth_fn.c",
|
||||
"crypto/evp/p_lib.c",
|
||||
"crypto/evp/evp_key.c",
|
||||
"crypto/evp/encode.c",
|
||||
"crypto/evp/e_aes_cbc_hmac_sha1.c",
|
||||
"crypto/evp/e_aes_cbc_hmac_sha256.c",
|
||||
"crypto/evp/m_mdc2.c",
|
||||
"crypto/evp/e_null.c",
|
||||
"crypto/evp/p_sign.c",
|
||||
"crypto/evp/e_idea.c",
|
||||
"crypto/evp/c_allc.c",
|
||||
"crypto/evp/evp_pkey.c",
|
||||
"crypto/evp/m_md4.c",
|
||||
"crypto/ex_data.c",
|
||||
"crypto/pkcs12/p12_p8e.c",
|
||||
"crypto/pkcs12/p12_crt.c",
|
||||
"crypto/pkcs12/p12_utl.c",
|
||||
"crypto/pkcs12/p12_attr.c",
|
||||
"crypto/pkcs12/p12_npas.c",
|
||||
"crypto/pkcs12/p12_decr.c",
|
||||
"crypto/pkcs12/p12_init.c",
|
||||
"crypto/pkcs12/p12_kiss.c",
|
||||
"crypto/pkcs12/p12_add.c",
|
||||
"crypto/pkcs12/p12_p8d.c",
|
||||
"crypto/pkcs12/p12_mutl.c",
|
||||
"crypto/pkcs12/p12_crpt.c",
|
||||
"crypto/pkcs12/pk12err.c",
|
||||
"crypto/pkcs12/p12_asn.c",
|
||||
"crypto/pkcs12/p12_key.c",
|
||||
"crypto/ecdh/ech_key.c",
|
||||
"crypto/ecdh/ech_ossl.c",
|
||||
"crypto/ecdh/ech_lib.c",
|
||||
"crypto/ecdh/ech_err.c",
|
||||
"crypto/ecdh/ech_kdf.c",
|
||||
"crypto/o_str.c",
|
||||
"crypto/conf/conf_api.c",
|
||||
"crypto/conf/conf_err.c",
|
||||
"crypto/conf/conf_def.c",
|
||||
"crypto/conf/conf_lib.c",
|
||||
"crypto/conf/conf_mall.c",
|
||||
"crypto/conf/conf_sap.c",
|
||||
"crypto/conf/conf_mod.c",
|
||||
"crypto/ebcdic.c",
|
||||
"crypto/ecdsa/ecs_lib.c",
|
||||
"crypto/ecdsa/ecs_asn1.c",
|
||||
"crypto/ecdsa/ecs_ossl.c",
|
||||
"crypto/ecdsa/ecs_vrf.c",
|
||||
"crypto/ecdsa/ecs_sign.c",
|
||||
"crypto/ecdsa/ecs_err.c",
|
||||
"crypto/dso/dso_win32.c",
|
||||
"crypto/dso/dso_lib.c",
|
||||
"crypto/dso/dso_dlfcn.c",
|
||||
"crypto/dso/dso_dl.c",
|
||||
"crypto/dso/dso_beos.c",
|
||||
"crypto/dso/dso_null.c",
|
||||
"crypto/dso/dso_vms.c",
|
||||
"crypto/dso/dso_err.c",
|
||||
"crypto/dso/dso_openssl.c",
|
||||
"crypto/cryptlib.c",
|
||||
"crypto/md5/md5_one.c",
|
||||
"crypto/md5/md5_dgst.c",
|
||||
"crypto/pkcs7/pkcs7err.c",
|
||||
"crypto/pkcs7/pk7_smime.c",
|
||||
"crypto/pkcs7/bio_pk7.c",
|
||||
"crypto/pkcs7/pk7_mime.c",
|
||||
"crypto/pkcs7/pk7_lib.c",
|
||||
"crypto/pkcs7/pk7_asn1.c",
|
||||
"crypto/pkcs7/pk7_doit.c",
|
||||
"crypto/pkcs7/pk7_attr.c",
|
||||
"crypto/md4/md4_one.c",
|
||||
"crypto/md4/md4_dgst.c",
|
||||
"crypto/o_dir.c",
|
||||
"crypto/buffer/buf_err.c",
|
||||
"crypto/buffer/buf_str.c",
|
||||
"crypto/buffer/buffer.c",
|
||||
"crypto/cms/cms_lib.c",
|
||||
"crypto/cms/cms_io.c",
|
||||
"crypto/cms/cms_err.c",
|
||||
"crypto/cms/cms_dd.c",
|
||||
"crypto/cms/cms_smime.c",
|
||||
"crypto/cms/cms_att.c",
|
||||
"crypto/cms/cms_pwri.c",
|
||||
"crypto/cms/cms_cd.c",
|
||||
"crypto/cms/cms_sd.c",
|
||||
"crypto/cms/cms_asn1.c",
|
||||
"crypto/cms/cms_env.c",
|
||||
"crypto/cms/cms_enc.c",
|
||||
"crypto/cms/cms_ess.c",
|
||||
"crypto/cms/cms_kari.c",
|
||||
"crypto/mem_dbg.c",
|
||||
"crypto/uid.c",
|
||||
"crypto/stack/stack.c",
|
||||
"crypto/ec/ec_ameth.c",
|
||||
"crypto/ec/ec_err.c",
|
||||
"crypto/ec/ec_lib.c",
|
||||
"crypto/ec/ec_curve.c",
|
||||
"crypto/ec/ec_oct.c",
|
||||
"crypto/ec/ec_asn1.c",
|
||||
"crypto/ec/ecp_oct.c",
|
||||
"crypto/ec/ec_print.c",
|
||||
"crypto/ec/ec2_smpl.c",
|
||||
"crypto/ec/ecp_nistp224.c",
|
||||
"crypto/ec/ec2_oct.c",
|
||||
"crypto/ec/eck_prn.c",
|
||||
"crypto/ec/ec_key.c",
|
||||
"crypto/ec/ecp_nist.c",
|
||||
"crypto/ec/ec_check.c",
|
||||
"crypto/ec/ecp_smpl.c",
|
||||
"crypto/ec/ec2_mult.c",
|
||||
"crypto/ec/ecp_mont.c",
|
||||
"crypto/ec/ecp_nistp521.c",
|
||||
"crypto/ec/ec_mult.c",
|
||||
"crypto/ec/ecp_nistputil.c",
|
||||
"crypto/ec/ec_pmeth.c",
|
||||
"crypto/ec/ec_cvt.c",
|
||||
"crypto/ec/ecp_nistp256.c",
|
||||
"crypto/krb5/krb5_asn.c",
|
||||
"crypto/hmac/hmac.c",
|
||||
"crypto/hmac/hm_ameth.c",
|
||||
"crypto/hmac/hm_pmeth.c",
|
||||
"crypto/comp/c_rle.c",
|
||||
"crypto/comp/c_zlib.c",
|
||||
"crypto/comp/comp_lib.c",
|
||||
"crypto/comp/comp_err.c",
|
||||
"crypto/des/fcrypt.c",
|
||||
"crypto/des/str2key.c",
|
||||
"crypto/des/cbc_cksm.c",
|
||||
"crypto/des/des_enc.c",
|
||||
"crypto/des/ofb_enc.c",
|
||||
"crypto/des/read2pwd.c",
|
||||
"crypto/des/ecb3_enc.c",
|
||||
"crypto/des/rand_key.c",
|
||||
"crypto/des/cfb64ede.c",
|
||||
"crypto/des/rpc_enc.c",
|
||||
"crypto/des/ofb64ede.c",
|
||||
"crypto/des/qud_cksm.c",
|
||||
"crypto/des/enc_writ.c",
|
||||
"crypto/des/set_key.c",
|
||||
"crypto/des/xcbc_enc.c",
|
||||
"crypto/des/fcrypt_b.c",
|
||||
"crypto/des/ede_cbcm_enc.c",
|
||||
"crypto/des/des_old2.c",
|
||||
"crypto/des/cfb_enc.c",
|
||||
"crypto/des/ecb_enc.c",
|
||||
"crypto/des/enc_read.c",
|
||||
"crypto/des/des_old.c",
|
||||
"crypto/des/ofb64enc.c",
|
||||
"crypto/des/pcbc_enc.c",
|
||||
"crypto/des/cbc_enc.c",
|
||||
"crypto/des/cfb64enc.c",
|
||||
"crypto/lhash/lh_stats.c",
|
||||
"crypto/lhash/lhash.c",
|
||||
"crypto/x509v3/v3_genn.c",
|
||||
"crypto/x509v3/pcy_cache.c",
|
||||
"crypto/x509v3/v3_sxnet.c",
|
||||
"crypto/x509v3/v3_scts.c",
|
||||
"crypto/x509v3/v3err.c",
|
||||
"crypto/x509v3/v3_conf.c",
|
||||
"crypto/x509v3/v3_utl.c",
|
||||
"crypto/x509v3/v3_akeya.c",
|
||||
"crypto/x509v3/v3_lib.c",
|
||||
"crypto/x509v3/pcy_lib.c",
|
||||
"crypto/x509v3/v3_cpols.c",
|
||||
"crypto/x509v3/v3_ia5.c",
|
||||
"crypto/x509v3/v3_bitst.c",
|
||||
"crypto/x509v3/v3_skey.c",
|
||||
"crypto/x509v3/v3_info.c",
|
||||
"crypto/x509v3/v3_asid.c",
|
||||
"crypto/x509v3/pcy_tree.c",
|
||||
"crypto/x509v3/v3_pcons.c",
|
||||
"crypto/x509v3/v3_bcons.c",
|
||||
"crypto/x509v3/v3_pku.c",
|
||||
"crypto/x509v3/v3_ocsp.c",
|
||||
"crypto/x509v3/pcy_map.c",
|
||||
"crypto/x509v3/v3_ncons.c",
|
||||
"crypto/x509v3/v3_purp.c",
|
||||
"crypto/x509v3/v3_enum.c",
|
||||
"crypto/x509v3/v3_pmaps.c",
|
||||
"crypto/x509v3/pcy_node.c",
|
||||
"crypto/x509v3/v3_pcia.c",
|
||||
"crypto/x509v3/v3_crld.c",
|
||||
"crypto/x509v3/v3_pci.c",
|
||||
"crypto/x509v3/v3_akey.c",
|
||||
"crypto/x509v3/v3_addr.c",
|
||||
"crypto/x509v3/v3_int.c",
|
||||
"crypto/x509v3/v3_alt.c",
|
||||
"crypto/x509v3/v3_extku.c",
|
||||
"crypto/x509v3/v3_prn.c",
|
||||
"crypto/x509v3/pcy_data.c",
|
||||
"crypto/aes/aes_ofb.c",
|
||||
"crypto/aes/aes_ctr.c",
|
||||
"crypto/aes/aes_ecb.c",
|
||||
"crypto/aes/aes_cfb.c",
|
||||
"crypto/aes/aes_wrap.c",
|
||||
"crypto/aes/aes_ige.c",
|
||||
"crypto/aes/aes_misc.c",
|
||||
"crypto/pqueue/pqueue.c",
|
||||
"crypto/sha/sha_one.c",
|
||||
"crypto/sha/sha_dgst.c",
|
||||
"crypto/sha/sha512.c",
|
||||
"crypto/sha/sha1_one.c",
|
||||
"crypto/sha/sha1dgst.c",
|
||||
"crypto/sha/sha256.c",
|
||||
"crypto/whrlpool/wp_dgst.c",
|
||||
"crypto/objects/obj_xref.c",
|
||||
"crypto/objects/o_names.c",
|
||||
"crypto/objects/obj_err.c",
|
||||
"crypto/objects/obj_dat.c",
|
||||
"crypto/objects/obj_lib.c",
|
||||
"crypto/mem.c",
|
||||
"crypto/fips_ers.c",
|
||||
"crypto/o_fips.c",
|
||||
"crypto/engine/eng_rdrand.c",
|
||||
"crypto/engine/eng_err.c",
|
||||
"crypto/engine/tb_ecdsa.c",
|
||||
"crypto/engine/tb_rsa.c",
|
||||
"crypto/engine/tb_cipher.c",
|
||||
"crypto/engine/tb_dsa.c",
|
||||
"crypto/engine/eng_lib.c",
|
||||
"crypto/engine/tb_asnmth.c",
|
||||
"crypto/engine/tb_ecdh.c",
|
||||
"crypto/engine/tb_dh.c",
|
||||
"crypto/engine/tb_store.c",
|
||||
"crypto/engine/eng_init.c",
|
||||
"crypto/engine/eng_cnf.c",
|
||||
"crypto/engine/eng_all.c",
|
||||
"crypto/engine/tb_digest.c",
|
||||
"crypto/engine/tb_pkmeth.c",
|
||||
"crypto/engine/eng_table.c",
|
||||
"crypto/engine/eng_ctrl.c",
|
||||
"crypto/engine/eng_list.c",
|
||||
"crypto/engine/eng_cryptodev.c",
|
||||
"crypto/engine/eng_pkey.c",
|
||||
"crypto/engine/tb_rand.c",
|
||||
"crypto/engine/eng_openssl.c",
|
||||
"crypto/engine/eng_fat.c",
|
||||
"crypto/engine/eng_dyn.c",
|
||||
"crypto/ts/ts_rsp_verify.c",
|
||||
"crypto/ts/ts_req_print.c",
|
||||
"crypto/ts/ts_verify_ctx.c",
|
||||
"crypto/ts/ts_req_utils.c",
|
||||
"crypto/ts/ts_err.c",
|
||||
"crypto/ts/ts_rsp_print.c",
|
||||
"crypto/ts/ts_rsp_utils.c",
|
||||
"crypto/ts/ts_lib.c",
|
||||
"crypto/ts/ts_conf.c",
|
||||
"crypto/ts/ts_asn1.c",
|
||||
"crypto/ts/ts_rsp_sign.c",
|
||||
"crypto/ocsp/ocsp_ext.c",
|
||||
"crypto/ocsp/ocsp_cl.c",
|
||||
"crypto/ocsp/ocsp_ht.c",
|
||||
"crypto/ocsp/ocsp_lib.c",
|
||||
"crypto/ocsp/ocsp_srv.c",
|
||||
"crypto/ocsp/ocsp_vfy.c",
|
||||
"crypto/ocsp/ocsp_err.c",
|
||||
"crypto/ocsp/ocsp_prn.c",
|
||||
"crypto/ocsp/ocsp_asn.c",
|
||||
"crypto/bf/bf_cfb64.c",
|
||||
"crypto/bf/bf_ecb.c",
|
||||
"crypto/bf/bf_enc.c",
|
||||
"crypto/bf/bf_skey.c",
|
||||
"crypto/bf/bf_ofb64.c",
|
||||
"crypto/idea/i_skey.c",
|
||||
"crypto/idea/i_ofb64.c",
|
||||
"crypto/idea/i_cbc.c",
|
||||
"crypto/idea/i_ecb.c",
|
||||
"crypto/idea/i_cfb64.c",
|
||||
"crypto/cmac/cm_ameth.c",
|
||||
"crypto/cmac/cmac.c",
|
||||
"crypto/cmac/cm_pmeth.c",
|
||||
"crypto/dh/dh_lib.c",
|
||||
"crypto/dh/dh_key.c",
|
||||
"crypto/dh/dh_asn1.c",
|
||||
"crypto/dh/dh_depr.c",
|
||||
"crypto/dh/dh_pmeth.c",
|
||||
"crypto/dh/dh_prn.c",
|
||||
"crypto/dh/dh_gen.c",
|
||||
"crypto/dh/dh_ameth.c",
|
||||
"crypto/dh/dh_check.c",
|
||||
"crypto/dh/dh_err.c",
|
||||
"crypto/dh/dh_kdf.c",
|
||||
"crypto/dh/dh_rfc5114.c",
|
||||
"crypto/modes/ccm128.c",
|
||||
"crypto/modes/ofb128.c",
|
||||
"crypto/modes/cts128.c",
|
||||
"crypto/modes/ctr128.c",
|
||||
"crypto/modes/gcm128.c",
|
||||
"crypto/modes/cbc128.c",
|
||||
"crypto/modes/cfb128.c",
|
||||
"crypto/modes/xts128.c",
|
||||
"crypto/modes/wrap128.c",
|
||||
"crypto/camellia/cmll_cfb.c",
|
||||
"crypto/camellia/cmll_ecb.c",
|
||||
"crypto/camellia/cmll_utl.c",
|
||||
"crypto/camellia/cmll_misc.c",
|
||||
"crypto/camellia/cmll_ofb.c",
|
||||
"crypto/camellia/cmll_ctr.c",
|
||||
"crypto/seed/seed_ecb.c",
|
||||
"crypto/seed/seed_cbc.c",
|
||||
"crypto/seed/seed.c",
|
||||
"crypto/seed/seed_ofb.c",
|
||||
"crypto/seed/seed_cfb.c",
|
||||
"crypto/txt_db/txt_db.c",
|
||||
"crypto/cpt_err.c",
|
||||
"crypto/pem/pem_pk8.c",
|
||||
"crypto/pem/pem_lib.c",
|
||||
"crypto/pem/pem_sign.c",
|
||||
"crypto/pem/pem_all.c",
|
||||
"crypto/pem/pem_info.c",
|
||||
"crypto/pem/pem_pkey.c",
|
||||
"crypto/pem/pem_seal.c",
|
||||
"crypto/pem/pem_err.c",
|
||||
"crypto/pem/pem_xaux.c",
|
||||
"crypto/pem/pvkfmt.c",
|
||||
"crypto/pem/pem_x509.c",
|
||||
"crypto/pem/pem_oth.c",
|
||||
"crypto/rand/rand_lib.c",
|
||||
"crypto/rand/randfile.c",
|
||||
"crypto/rand/rand_os2.c",
|
||||
"crypto/rand/rand_unix.c",
|
||||
"crypto/rand/rand_nw.c",
|
||||
"crypto/rand/md_rand.c",
|
||||
"crypto/rand/rand_err.c",
|
||||
"crypto/rand/rand_win.c",
|
||||
"crypto/rand/rand_egd.c",
|
||||
"crypto/cversion.c",
|
||||
"crypto/cast/c_ecb.c",
|
||||
"crypto/cast/c_skey.c",
|
||||
"crypto/cast/c_ofb64.c",
|
||||
"crypto/cast/c_enc.c",
|
||||
"crypto/cast/c_cfb64.c",
|
||||
"crypto/o_time.c",
|
||||
"crypto/mdc2/mdc2dgst.c",
|
||||
"crypto/mdc2/mdc2_one.c",
|
||||
"crypto/rc4/rc4_utl.c",
|
||||
"crypto/ui/ui_compat.c",
|
||||
"crypto/ui/ui_util.c",
|
||||
"crypto/ui/ui_lib.c",
|
||||
"crypto/ui/ui_err.c",
|
||||
"crypto/ui/ui_openssl.c",
|
||||
"crypto/bio/bf_buff.c",
|
||||
"crypto/bio/bss_null.c",
|
||||
"crypto/bio/bss_acpt.c",
|
||||
"crypto/bio/bss_conn.c",
|
||||
"crypto/bio/bss_fd.c",
|
||||
"crypto/bio/bf_null.c",
|
||||
"crypto/bio/bio_err.c",
|
||||
"crypto/bio/bss_sock.c",
|
||||
"crypto/bio/bss_mem.c",
|
||||
"crypto/bio/b_dump.c",
|
||||
"crypto/bio/b_print.c",
|
||||
"crypto/bio/b_sock.c",
|
||||
"crypto/bio/bss_dgram.c",
|
||||
"crypto/bio/bf_nbio.c",
|
||||
"crypto/bio/bio_lib.c",
|
||||
"crypto/bio/bss_file.c",
|
||||
"crypto/bio/bss_bio.c",
|
||||
"crypto/bio/bss_log.c",
|
||||
"crypto/bio/bio_cb.c",
|
||||
"crypto/o_init.c",
|
||||
"crypto/rc2/rc2_skey.c",
|
||||
"crypto/rc2/rc2_cbc.c",
|
||||
"crypto/rc2/rc2cfb64.c",
|
||||
"crypto/rc2/rc2_ecb.c",
|
||||
"crypto/rc2/rc2ofb64.c",
|
||||
"crypto/bn/bn_x931p.c",
|
||||
"crypto/bn/bn_blind.c",
|
||||
"crypto/bn/bn_gf2m.c",
|
||||
"crypto/bn/bn_const.c",
|
||||
"crypto/bn/bn_sqr.c",
|
||||
"crypto/bn/bn_nist.c",
|
||||
"crypto/bn/bn_rand.c",
|
||||
"crypto/bn/bn_err.c",
|
||||
"crypto/bn/bn_div.c",
|
||||
"crypto/bn/bn_kron.c",
|
||||
"crypto/bn/bn_ctx.c",
|
||||
"crypto/bn/bn_shift.c",
|
||||
"crypto/bn/bn_mod.c",
|
||||
"crypto/bn/bn_exp2.c",
|
||||
"crypto/bn/bn_word.c",
|
||||
"crypto/bn/bn_add.c",
|
||||
"crypto/bn/bn_exp.c",
|
||||
"crypto/bn/bn_mont.c",
|
||||
"crypto/bn/bn_print.c",
|
||||
"crypto/bn/bn_mul.c",
|
||||
"crypto/bn/bn_prime.c",
|
||||
"crypto/bn/bn_depr.c",
|
||||
"crypto/bn/bn_gcd.c",
|
||||
"crypto/bn/bn_mpi.c",
|
||||
"crypto/bn/bn_sqrt.c",
|
||||
"crypto/bn/bn_recp.c",
|
||||
"crypto/bn/bn_lib.c",
|
||||
"crypto/ripemd/rmd_dgst.c",
|
||||
"crypto/ripemd/rmd_one.c",
|
||||
"crypto/rsa/rsa_x931.c",
|
||||
"crypto/rsa/rsa_depr.c",
|
||||
"crypto/rsa/rsa_saos.c",
|
||||
"crypto/rsa/rsa_crpt.c",
|
||||
"crypto/rsa/rsa_pss.c",
|
||||
"crypto/rsa/rsa_oaep.c",
|
||||
"crypto/rsa/rsa_null.c",
|
||||
"crypto/rsa/rsa_gen.c",
|
||||
"crypto/rsa/rsa_prn.c",
|
||||
"crypto/rsa/rsa_pmeth.c",
|
||||
"crypto/rsa/rsa_asn1.c",
|
||||
"crypto/rsa/rsa_ssl.c",
|
||||
"crypto/rsa/rsa_ameth.c",
|
||||
"crypto/rsa/rsa_pk1.c",
|
||||
"crypto/rsa/rsa_err.c",
|
||||
"crypto/rsa/rsa_lib.c",
|
||||
"crypto/rsa/rsa_none.c",
|
||||
"crypto/rsa/rsa_chk.c",
|
||||
"crypto/rsa/rsa_eay.c",
|
||||
"crypto/rsa/rsa_sign.c",
|
||||
"crypto/srp/srp_lib.c",
|
||||
"crypto/srp/srp_vfy.c",
|
||||
"crypto/err/err.c",
|
||||
"crypto/err/err_prn.c",
|
||||
"crypto/err/err_all.c",
|
||||
"crypto/mem_clr.c",
|
||||
"crypto/rc4/rc4_skey.c",
|
||||
"crypto/rc4/rc4_enc.c",
|
||||
"crypto/camellia/camellia.c",
|
||||
"crypto/camellia/cmll_cbc.c",
|
||||
#"crypto/aes/aes_x86core.c",
|
||||
"crypto/aes/aes_core.c",
|
||||
"crypto/aes/aes_cbc.c",
|
||||
"crypto/whrlpool/wp_block.c",
|
||||
"crypto/bn/bn_asm.c",
|
||||
]
|
||||
|
||||
#env.drivers_sources+=openssl_sources
|
||||
|
||||
env.Append(CPPPATH=["#drivers/builtin_openssl2"])
|
||||
env_drivers.Append(CPPPATH=["#drivers/builtin_openssl2/crypto"])
|
||||
env_drivers.Append(CPPPATH=["#drivers/builtin_openssl2/openssl"])
|
||||
env_drivers.Append(CPPPATH=["#drivers/builtin_openssl2/crypto/evp"])
|
||||
env_drivers.Append(CPPPATH=["#drivers/builtin_openssl2/crypto/asn1"])
|
||||
env_drivers.Append(CPPPATH=["#drivers/builtin_openssl2/crypto/modes"])
|
||||
#env_ssl.Append(CPPPATH=["#drivers/builtin_openssl2/crypto/store"])
|
||||
env_drivers.Append(CPPFLAGS=["-DOPENSSL_NO_ASM","-DOPENSSL_THREADS","-DL_ENDIAN"])
|
||||
|
||||
if "platform" in env and env["platform"] == "winrt":
|
||||
openssl_sources += ['winrt.cpp']
|
||||
|
||||
# Workaround for compilation error with GCC/Clang when -Werror is too greedy (GH-4517)
|
||||
import os
|
||||
import methods
|
||||
if not (os.name=="nt" and methods.msvc_is_detected() ): # not Windows and not MSVC
|
||||
env_drivers.Append(CFLAGS=["-Wno-error=implicit-function-declaration"])
|
||||
|
||||
env_drivers.add_source_files(env.drivers_sources,openssl_sources)
|
@ -1,22 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
zlib_sources = [
|
||||
|
||||
"builtin_zlib/zlib/adler32.c",
|
||||
"builtin_zlib/zlib/compress.c",
|
||||
"builtin_zlib/zlib/crc32.c",
|
||||
"builtin_zlib/zlib/deflate.c",
|
||||
"builtin_zlib/zlib/infback.c",
|
||||
"builtin_zlib/zlib/inffast.c",
|
||||
"builtin_zlib/zlib/inflate.c",
|
||||
"builtin_zlib/zlib/inftrees.c",
|
||||
"builtin_zlib/zlib/trees.c",
|
||||
"builtin_zlib/zlib/uncompr.c",
|
||||
"builtin_zlib/zlib/zutil.c",
|
||||
]
|
||||
|
||||
|
||||
env.drivers_sources+=zlib_sources
|
||||
|
||||
#env.add_source_files("core", png_sources)
|
||||
Export('env')
|
@ -1,5 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
|
||||
Export('env')
|
@ -1,4 +1,5 @@
|
||||
Import('env')
|
||||
Export('env');
|
||||
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
@ -1,10 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
|
||||
dds_sources = [
|
||||
"dds/texture_loader_dds.cpp"
|
||||
]
|
||||
|
||||
env.drivers_sources+=dds_sources
|
||||
|
||||
#env.add_source_files(env.drivers_sources, dds_sources)
|
@ -1,15 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
|
||||
etc_sources = [
|
||||
"etc1/image_etc.cpp",
|
||||
"etc1/rg_etc1.cpp",
|
||||
"etc1/texture_loader_pkm.cpp"
|
||||
]
|
||||
|
||||
if (env["etc1"] != "no"):
|
||||
env.drivers_sources+=etc_sources
|
||||
|
||||
#env.add_source_files(env.drivers_sources, etc_sources)
|
||||
|
||||
Export('env')
|
@ -1,73 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
ft_sources=[\
|
||||
"src/autofit/autofit.c",\
|
||||
"src/base/ftapi.c",\
|
||||
"src/base/ftbase.c",\
|
||||
"src/base/ftbbox.c",\
|
||||
"src/base/ftbdf.c",\
|
||||
"src/base/ftbitmap.c",\
|
||||
"src/base/ftcid.c",\
|
||||
"src/base/ftdebug.c",\
|
||||
"src/base/ftfntfmt.c",\
|
||||
"src/base/ftfstype.c",\
|
||||
"src/base/ftgasp.c",\
|
||||
"src/base/ftglyph.c",\
|
||||
"src/base/ftgxval.c",\
|
||||
"src/base/ftinit.c",\
|
||||
"src/base/ftlcdfil.c",\
|
||||
"src/base/ftmm.c",\
|
||||
"src/base/ftotval.c",\
|
||||
"src/base/ftpatent.c",\
|
||||
"src/base/ftpfr.c",\
|
||||
"src/base/ftpic.c",\
|
||||
"src/base/ftstroke.c",\
|
||||
"src/base/ftsynth.c",\
|
||||
"src/base/ftsystem.c",\
|
||||
"src/base/fttype1.c",\
|
||||
"src/base/ftwinfnt.c",\
|
||||
"src/bdf/bdf.c",\
|
||||
"src/cache/ftcache.c",\
|
||||
"src/cff/cff.c",\
|
||||
"src/cid/type1cid.c",\
|
||||
"src/gxvalid/gxvalid.c",\
|
||||
"src/otvalid/otvalid.c",\
|
||||
"src/pcf/pcf.c",\
|
||||
"src/pfr/pfr.c",\
|
||||
"src/psaux/psaux.c",\
|
||||
"src/pshinter/pshinter.c",\
|
||||
"src/psnames/psnames.c",\
|
||||
"src/raster/raster.c",\
|
||||
"src/sfnt/sfnt.c",\
|
||||
"src/smooth/smooth.c",\
|
||||
"src/truetype/truetype.c",\
|
||||
"src/type1/type1.c",\
|
||||
"src/type42/type42.c",\
|
||||
"src/winfonts/winfnt.c",\
|
||||
]
|
||||
|
||||
|
||||
if (env["freetype"]=="builtin"):
|
||||
|
||||
# Include header for WinRT to fix build issues
|
||||
if "platform" in env and env["platform"] == "winrt":
|
||||
env.Append(CCFLAGS=['/FI', '"drivers/freetype/winrtdef.h"'])
|
||||
|
||||
# fix for Windows' shell miserably failing on long lines, split in two libraries
|
||||
half1=[]
|
||||
half2=[]
|
||||
for x in ft_sources:
|
||||
if (x.find("src/base")==0 or x.find("src/sfnt")==0):
|
||||
half2.append(x)
|
||||
else:
|
||||
half1.append(x)
|
||||
|
||||
lib = env.Library("freetype_builtin1",half2)
|
||||
env.Append(LIBS=[lib])
|
||||
lib = env.Library("freetype_builtin2",half1)
|
||||
env.Append(LIBS=[lib])
|
||||
|
||||
env.Append(CPPPATH=["#drivers/freetype/include"])
|
||||
|
||||
|
||||
Export('env')
|
@ -1,19 +0,0 @@
|
||||
# FreeType 2 src Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) ;
|
||||
|
||||
for xx in $(FT2_COMPONENTS)
|
||||
{
|
||||
SubInclude FT2_TOP $(FT2_SRC_DIR) $(xx) ;
|
||||
}
|
||||
|
||||
# end of src Jamfile
|
@ -1,53 +0,0 @@
|
||||
# FreeType 2 src/autofit Jamfile
|
||||
#
|
||||
# Copyright 2003-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP src autofit ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
# define FT2_AUTOFIT2 to enable experimental latin hinter replacement
|
||||
if $(FT2_AUTOFIT2)
|
||||
{
|
||||
CCFLAGS += FT_OPTION_AUTOFIT2 ;
|
||||
}
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = afangles
|
||||
afblue
|
||||
afcjk
|
||||
afdummy
|
||||
afglobal
|
||||
afhints
|
||||
afindic
|
||||
aflatin
|
||||
afloader
|
||||
afmodule
|
||||
afpic
|
||||
afranges
|
||||
afshaper
|
||||
afwarp
|
||||
;
|
||||
|
||||
if $(FT2_AUTOFIT2)
|
||||
{
|
||||
_sources += aflatin2 ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = autofit ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/autofit Jamfile
|
@ -1,88 +0,0 @@
|
||||
# FreeType 2 src/base Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) base ;
|
||||
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = basepic
|
||||
ftadvanc
|
||||
ftcalc
|
||||
ftdbgmem
|
||||
ftgloadr
|
||||
fthash
|
||||
ftobjs
|
||||
ftoutln
|
||||
ftpic
|
||||
ftrfork
|
||||
ftsnames
|
||||
ftstream
|
||||
fttrigon
|
||||
ftutil
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = ftbase ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# Add the optional/replaceable files.
|
||||
#
|
||||
{
|
||||
local _sources = ftapi
|
||||
ftbbox
|
||||
ftbdf
|
||||
ftbitmap
|
||||
ftcid
|
||||
ftdebug
|
||||
ftfntfmt
|
||||
ftfstype
|
||||
ftgasp
|
||||
ftglyph
|
||||
ftgxval
|
||||
ftinit
|
||||
ftlcdfil
|
||||
ftmm
|
||||
ftotval
|
||||
ftpatent
|
||||
ftpfr
|
||||
ftstroke
|
||||
ftsynth
|
||||
ftsystem
|
||||
fttype1
|
||||
ftwinfnt
|
||||
;
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# Add Macintosh-specific file to the library when necessary.
|
||||
#
|
||||
if $(MAC)
|
||||
{
|
||||
Library $(FT2_LIB) : ftmac.c ;
|
||||
}
|
||||
else if $(OS) = MACOSX
|
||||
{
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
Library $(FT2_LIB) : ftmac.c ;
|
||||
}
|
||||
}
|
||||
|
||||
# end of src/base Jamfile
|
@ -1,31 +0,0 @@
|
||||
# FreeType 2 src/bdf Jamfile
|
||||
#
|
||||
# Copyright 2002-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) bdf ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = bdfdrivr
|
||||
bdflib
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = bdf ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/bdf Jamfile
|
37
drivers/freetype/src/cache/Jamfile
vendored
37
drivers/freetype/src/cache/Jamfile
vendored
@ -1,37 +0,0 @@
|
||||
# FreeType 2 src/cache Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) cache ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = ftcbasic
|
||||
ftccache
|
||||
ftcglyph
|
||||
ftcimage
|
||||
ftcmanag
|
||||
ftccmap
|
||||
ftcmru
|
||||
ftcsbits
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = ftcache ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/cache Jamfile
|
@ -1,45 +0,0 @@
|
||||
# FreeType 2 src/cff Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) cff ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = cffcmap
|
||||
cffdrivr
|
||||
cffgload
|
||||
cffload
|
||||
cffobjs
|
||||
cffparse
|
||||
cffpic
|
||||
cf2arrst
|
||||
cf2blues
|
||||
cf2error
|
||||
cf2font
|
||||
cf2ft
|
||||
cf2hints
|
||||
cf2intrp
|
||||
cf2read
|
||||
cf2stack
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = cff ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/cff Jamfile
|
@ -1,34 +0,0 @@
|
||||
# FreeType 2 src/cid Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) cid ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = cidgload
|
||||
cidload
|
||||
cidobjs
|
||||
cidparse
|
||||
cidriver
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = type1cid ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/cid Jamfile
|
@ -1,52 +0,0 @@
|
||||
# FreeType 2 src/gxvalid Jamfile
|
||||
#
|
||||
# Copyright 2005-2016 by
|
||||
# suzuki toshiya, Masatake YAMATO and Red Hat K.K.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) gxvalid ;
|
||||
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = gxvbsln
|
||||
gxvcommn
|
||||
gxvfeat
|
||||
gxvjust
|
||||
gxvkern
|
||||
gxvlcar
|
||||
gxvmod
|
||||
gxvmort
|
||||
gxvmort0
|
||||
gxvmort1
|
||||
gxvmort2
|
||||
gxvmort4
|
||||
gxvmort5
|
||||
gxvmorx
|
||||
gxvmorx0
|
||||
gxvmorx1
|
||||
gxvmorx2
|
||||
gxvmorx4
|
||||
gxvmorx5
|
||||
gxvopbd
|
||||
gxvprop
|
||||
gxvtrak
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = gxvalid ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/gxvalid Jamfile
|
@ -1,37 +0,0 @@
|
||||
# FreeType 2 src/otvalid Jamfile
|
||||
#
|
||||
# Copyright 2004-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) otvalid ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = otvbase
|
||||
otvcommn
|
||||
otvgdef
|
||||
otvgpos
|
||||
otvgsub
|
||||
otvjstf
|
||||
otvmath
|
||||
otvmod
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = otvalid ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/otvalid Jamfile
|
@ -1,32 +0,0 @@
|
||||
# FreeType 2 src/pcf Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) pcf ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = pcfdrivr
|
||||
pcfread
|
||||
pcfutil
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = pcf ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/pcf Jamfile
|
@ -1,35 +0,0 @@
|
||||
# FreeType 2 src/pfr Jamfile
|
||||
#
|
||||
# Copyright 2002-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) pfr ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = pfrcmap
|
||||
pfrdrivr
|
||||
pfrgload
|
||||
pfrload
|
||||
pfrobjs
|
||||
pfrsbit
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = pfr ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/pfr Jamfile
|
@ -1,35 +0,0 @@
|
||||
# FreeType 2 src/psaux Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) psaux ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = afmparse
|
||||
psauxmod
|
||||
psconv
|
||||
psobjs
|
||||
t1cmap
|
||||
t1decode
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = psaux ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/psaux Jamfile
|
@ -1,34 +0,0 @@
|
||||
# FreeType 2 src/pshinter Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) pshinter ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = pshalgo
|
||||
pshglob
|
||||
pshmod
|
||||
pshpic
|
||||
pshrec
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = pshinter ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/pshinter Jamfile
|
@ -1,31 +0,0 @@
|
||||
# FreeType 2 src/psnames Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) psnames ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = psmodule
|
||||
pspic
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = psnames ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/psnames Jamfile
|
@ -1,32 +0,0 @@
|
||||
# FreeType 2 src/raster Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) raster ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = ftraster
|
||||
ftrend1
|
||||
rastpic
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = raster ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/raster Jamfile
|
@ -1,40 +0,0 @@
|
||||
# FreeType 2 src/sfnt Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = pngshim
|
||||
sfdriver
|
||||
sfntpic
|
||||
sfobjs
|
||||
ttbdf
|
||||
ttcmap
|
||||
ttkern
|
||||
ttload
|
||||
ttmtx
|
||||
ttpost
|
||||
ttsbit
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = sfnt ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/sfnt Jamfile
|
@ -1,32 +0,0 @@
|
||||
# FreeType 2 src/smooth Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) smooth ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = ftgrays
|
||||
ftsmooth
|
||||
ftspic
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = smooth ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/smooth Jamfile
|
@ -1,37 +0,0 @@
|
||||
# FreeType 2 src/truetype Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) truetype ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = ttdriver
|
||||
ttgload
|
||||
ttgxvar
|
||||
ttinterp
|
||||
ttobjs
|
||||
ttpic
|
||||
ttpload
|
||||
ttsubpix
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = truetype ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/truetype Jamfile
|
@ -1,35 +0,0 @@
|
||||
# FreeType 2 src/type1 Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) type1 ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = t1afm
|
||||
t1driver
|
||||
t1gload
|
||||
t1load
|
||||
t1objs
|
||||
t1parse
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = type1 ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/type1 Jamfile
|
@ -1,32 +0,0 @@
|
||||
# FreeType 2 src/type42 Jamfile
|
||||
#
|
||||
# Copyright 2002-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) type42 ;
|
||||
|
||||
{
|
||||
local _sources ;
|
||||
|
||||
if $(FT2_MULTI)
|
||||
{
|
||||
_sources = t42drivr
|
||||
t42objs
|
||||
t42parse
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
_sources = type42 ;
|
||||
}
|
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ;
|
||||
}
|
||||
|
||||
# end of src/type42 Jamfile
|
@ -1,16 +0,0 @@
|
||||
# FreeType 2 src/winfonts Jamfile
|
||||
#
|
||||
# Copyright 2001-2016 by
|
||||
# David Turner, Robert Wilhelm, and Werner Lemberg.
|
||||
#
|
||||
# This file is part of the FreeType project, and may only be used, modified,
|
||||
# and distributed under the terms of the FreeType project license,
|
||||
# LICENSE.TXT. By continuing to use, modify, or distribute this file you
|
||||
# indicate that you have read the license and understand and accept it
|
||||
# fully.
|
||||
|
||||
SubDir FT2_TOP $(FT2_SRC_DIR) winfonts ;
|
||||
|
||||
Library $(FT2_LIB) : winfnt.c ;
|
||||
|
||||
# end of src/winfonts Jamfile
|
@ -1,11 +1,21 @@
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
if (env["platform"] in ["haiku","osx","windows","x11"]):
|
||||
# Thirdparty source files
|
||||
if (env["glew"] != "system"): # builtin
|
||||
thirdparty_dir = "#thirdparty/glew/"
|
||||
thirdparty_sources = [
|
||||
"glew.c",
|
||||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env.add_source_files(env.drivers_sources, thirdparty_sources)
|
||||
env.Append(CPPFLAGS = ['-DGLEW_STATIC'])
|
||||
env.Append(CPPPATH = [thirdparty_dir])
|
||||
|
||||
if (env.get('glew') == 'yes'):
|
||||
env.add_source_files(env.drivers_sources,"glew.c")
|
||||
env.Append(CPPFLAGS = ['-DGLEW_ENABLED'])
|
||||
env.Append(CPPFLAGS = ['-DGLEW_STATIC'])
|
||||
env.Append(CPPPATH = ['.'])
|
||||
|
||||
# Godot source files
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
@ -1,5 +1,7 @@
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
SConscript("shaders/SCsub")
|
||||
|
||||
Export('env')
|
||||
|
@ -6,3 +6,5 @@ if env['BUILDERS'].has_key('GLSL120GLES'):
|
||||
env.GLSL120GLES('canvas_shadow.glsl');
|
||||
env.GLSL120GLES('blur.glsl');
|
||||
env.GLSL120GLES('copy.glsl');
|
||||
|
||||
Export('env')
|
||||
|
@ -1,11 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
|
||||
jpg_sources = [
|
||||
"jpegd/jpgd.cpp",
|
||||
"jpegd/image_loader_jpegd.cpp"
|
||||
]
|
||||
|
||||
env.drivers_sources+=jpg_sources
|
||||
|
||||
#env.add_source_files(env.drivers_sources, jpg_sources)
|
@ -1,143 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* image_loader_jpegd.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "image_loader_jpegd.h"
|
||||
|
||||
#include "print_string.h"
|
||||
#include "os/os.h"
|
||||
#include "jpgd.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
Error jpeg_load_image_from_buffer(Image *p_image,const uint8_t* p_buffer, int p_buffer_len) {
|
||||
|
||||
jpgd::jpeg_decoder_mem_stream mem_stream(p_buffer,p_buffer_len);
|
||||
|
||||
jpgd::jpeg_decoder decoder(&mem_stream);
|
||||
|
||||
if (decoder.get_error_code() != jpgd::JPGD_SUCCESS) {
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
const int image_width = decoder.get_width();
|
||||
const int image_height = decoder.get_height();
|
||||
int comps = decoder.get_num_components();
|
||||
if (comps==3)
|
||||
comps=4; //weird
|
||||
|
||||
if (decoder.begin_decoding() != jpgd::JPGD_SUCCESS)
|
||||
return ERR_FILE_CORRUPT;
|
||||
|
||||
const int dst_bpl = image_width * comps;
|
||||
|
||||
DVector<uint8_t> data;
|
||||
|
||||
data.resize(dst_bpl * image_height);
|
||||
|
||||
DVector<uint8_t>::Write dw = data.write();
|
||||
|
||||
jpgd::uint8 *pImage_data = (jpgd::uint8*)dw.ptr();
|
||||
|
||||
for (int y = 0; y < image_height; y++)
|
||||
{
|
||||
const jpgd::uint8* pScan_line;
|
||||
jpgd::uint scan_line_len;
|
||||
if (decoder.decode((const void**)&pScan_line, &scan_line_len) != jpgd::JPGD_SUCCESS)
|
||||
{
|
||||
return ERR_FILE_CORRUPT;
|
||||
}
|
||||
|
||||
jpgd::uint8 *pDst = pImage_data + y * dst_bpl;
|
||||
memcpy(pDst, pScan_line, dst_bpl);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//all good
|
||||
|
||||
Image::Format fmt;
|
||||
if (comps==1)
|
||||
fmt=Image::FORMAT_GRAYSCALE;
|
||||
else
|
||||
fmt=Image::FORMAT_RGBA;
|
||||
|
||||
dw = DVector<uint8_t>::Write();
|
||||
p_image->create(image_width,image_height,0,fmt,data);
|
||||
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Error ImageLoaderJPG::load_image(Image *p_image,FileAccess *f) {
|
||||
|
||||
|
||||
DVector<uint8_t> src_image;
|
||||
int src_image_len = f->get_len();
|
||||
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
|
||||
src_image.resize(src_image_len);
|
||||
|
||||
DVector<uint8_t>::Write w = src_image.write();
|
||||
|
||||
f->get_buffer(&w[0],src_image_len);
|
||||
|
||||
f->close();
|
||||
|
||||
|
||||
Error err = jpeg_load_image_from_buffer(p_image,w.ptr(),src_image_len);
|
||||
|
||||
w = DVector<uint8_t>::Write();
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
void ImageLoaderJPG::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("jpg");
|
||||
p_extensions->push_back("jpeg");
|
||||
}
|
||||
|
||||
|
||||
static Image _jpegd_mem_loader_func(const uint8_t* p_png,int p_size) {
|
||||
|
||||
Image img;
|
||||
Error err = jpeg_load_image_from_buffer(&img,p_png,p_size);
|
||||
if (err)
|
||||
ERR_PRINT("Couldn't initialize ImageLoaderJPG with the given resource.");
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
ImageLoaderJPG::ImageLoaderJPG() {
|
||||
|
||||
Image::_jpg_mem_loader_func=_jpegd_mem_loader_func;
|
||||
}
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
|
||||
mpc_sources = [
|
||||
"mpc/huffman.c",
|
||||
"mpc/mpc_bits_reader.c",
|
||||
"mpc/mpc_decoder.c",
|
||||
"mpc/mpc_demux.c",
|
||||
"mpc/mpc_reader.c",
|
||||
"mpc/requant.c",
|
||||
"mpc/streaminfo.c",
|
||||
"mpc/synth_filter.c",
|
||||
]
|
||||
|
||||
env.drivers_sources+=mpc_sources
|
||||
|
||||
env.add_source_files(env.drivers_sources,"*.cpp")
|
||||
|
||||
#env.add_source_files(env.drivers_sources, mpc_sources)
|
||||
|
||||
Export('env')
|
@ -1,147 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* audio_stream_mpc.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef AUDIO_STREAM_MPC_H
|
||||
#define AUDIO_STREAM_MPC_H
|
||||
|
||||
#include "scene/resources/audio_stream.h"
|
||||
#include "os/file_access.h"
|
||||
#include "mpc/mpcdec.h"
|
||||
#include "os/thread_safe.h"
|
||||
#include "io/resource_loader.h"
|
||||
//#include "../libmpcdec/decoder.h"
|
||||
//#include "../libmpcdec/internal.h"
|
||||
|
||||
class AudioStreamPlaybackMPC : public AudioStreamPlayback {
|
||||
|
||||
OBJ_TYPE( AudioStreamPlaybackMPC, AudioStreamPlayback );
|
||||
|
||||
bool preload;
|
||||
FileAccess *f;
|
||||
String file;
|
||||
DVector<uint8_t> data;
|
||||
int data_ofs;
|
||||
int streamlen;
|
||||
|
||||
|
||||
bool active;
|
||||
bool paused;
|
||||
bool loop;
|
||||
int loops;
|
||||
|
||||
// mpc
|
||||
mpc_reader reader;
|
||||
mpc_demux* demux;
|
||||
mpc_streaminfo si;
|
||||
MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];
|
||||
|
||||
static mpc_int32_t _mpc_read(mpc_reader *p_reader,void *p_dst, mpc_int32_t p_bytes);
|
||||
static mpc_bool_t _mpc_seek(mpc_reader *p_reader,mpc_int32_t p_offset);
|
||||
static mpc_int32_t _mpc_tell(mpc_reader *p_reader);
|
||||
static mpc_int32_t _mpc_get_size(mpc_reader *p_reader);
|
||||
static mpc_bool_t _mpc_canseek(mpc_reader *p_reader);
|
||||
|
||||
int stream_min_size;
|
||||
int stream_rate;
|
||||
int stream_channels;
|
||||
|
||||
protected:
|
||||
Error _open_file();
|
||||
void _close_file();
|
||||
int _read_file(void *p_dst,int p_bytes);
|
||||
bool _seek_file(int p_pos);
|
||||
int _tell_file() const;
|
||||
int _sizeof_file() const;
|
||||
bool _canseek_file() const;
|
||||
|
||||
|
||||
Error _reload();
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_file(const String& p_file);
|
||||
String get_file() const;
|
||||
|
||||
virtual void play(float p_offset=0);
|
||||
virtual void stop();
|
||||
virtual bool is_playing() const;
|
||||
|
||||
|
||||
virtual void set_loop(bool p_enable);
|
||||
virtual bool has_loop() const;
|
||||
|
||||
virtual float get_length() const;
|
||||
|
||||
virtual String get_stream_name() const;
|
||||
|
||||
virtual int get_loop_count() const;
|
||||
|
||||
virtual float get_pos() const;
|
||||
virtual void seek_pos(float p_time);
|
||||
|
||||
virtual int get_channels() const { return stream_channels; }
|
||||
virtual int get_mix_rate() const { return stream_rate; }
|
||||
|
||||
virtual int get_minimum_buffer_size() const { return stream_min_size; }
|
||||
virtual int mix(int16_t* p_bufer,int p_frames);
|
||||
|
||||
virtual void set_loop_restart_time(float p_time) { }
|
||||
|
||||
AudioStreamPlaybackMPC();
|
||||
~AudioStreamPlaybackMPC();
|
||||
};
|
||||
|
||||
class AudioStreamMPC : public AudioStream {
|
||||
|
||||
OBJ_TYPE( AudioStreamMPC, AudioStream );
|
||||
|
||||
String file;
|
||||
public:
|
||||
|
||||
Ref<AudioStreamPlayback> instance_playback() {
|
||||
Ref<AudioStreamPlaybackMPC> pb = memnew( AudioStreamPlaybackMPC );
|
||||
pb->set_file(file);
|
||||
return pb;
|
||||
}
|
||||
|
||||
void set_file(const String& p_file) { file=p_file; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
class ResourceFormatLoaderAudioStreamMPC : public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // AUDIO_STREAM_MPC_H
|
@ -1,7 +1,5 @@
|
||||
Import('env')
|
||||
|
||||
sources = [
|
||||
'nrex.cpp',
|
||||
'regex.cpp',
|
||||
]
|
||||
env.add_source_files(env.drivers_sources, sources)
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
@ -1,9 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
ogg_sources = [
|
||||
|
||||
"ogg/bitwise.c",
|
||||
"ogg/framing.c",
|
||||
]
|
||||
|
||||
env.drivers_sources+=ogg_sources
|
@ -1,6 +0,0 @@
|
||||
Import('env_drivers')
|
||||
Import('env')
|
||||
|
||||
env_drivers.add_source_files(env.drivers_sources,"*.cpp")
|
||||
env_drivers.add_source_files(env.drivers_sources,"*.c")
|
||||
|
@ -1,221 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* This file is an amalgamation of hostcheck.c and most of rawstr.c
|
||||
from cURL. The contents of the COPYING file mentioned above are:
|
||||
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2013, Daniel Stenberg, <daniel@haxx.se>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright
|
||||
notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of a copyright holder shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization of the copyright holder.
|
||||
*/
|
||||
|
||||
#ifdef OPENSSL_ENABLED
|
||||
|
||||
#include "curl_hostcheck.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
|
||||
its behavior is altered by the current locale. */
|
||||
static char Curl_raw_toupper(char in)
|
||||
{
|
||||
switch (in) {
|
||||
case 'a':
|
||||
return 'A';
|
||||
case 'b':
|
||||
return 'B';
|
||||
case 'c':
|
||||
return 'C';
|
||||
case 'd':
|
||||
return 'D';
|
||||
case 'e':
|
||||
return 'E';
|
||||
case 'f':
|
||||
return 'F';
|
||||
case 'g':
|
||||
return 'G';
|
||||
case 'h':
|
||||
return 'H';
|
||||
case 'i':
|
||||
return 'I';
|
||||
case 'j':
|
||||
return 'J';
|
||||
case 'k':
|
||||
return 'K';
|
||||
case 'l':
|
||||
return 'L';
|
||||
case 'm':
|
||||
return 'M';
|
||||
case 'n':
|
||||
return 'N';
|
||||
case 'o':
|
||||
return 'O';
|
||||
case 'p':
|
||||
return 'P';
|
||||
case 'q':
|
||||
return 'Q';
|
||||
case 'r':
|
||||
return 'R';
|
||||
case 's':
|
||||
return 'S';
|
||||
case 't':
|
||||
return 'T';
|
||||
case 'u':
|
||||
return 'U';
|
||||
case 'v':
|
||||
return 'V';
|
||||
case 'w':
|
||||
return 'W';
|
||||
case 'x':
|
||||
return 'X';
|
||||
case 'y':
|
||||
return 'Y';
|
||||
case 'z':
|
||||
return 'Z';
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
|
||||
* to be locale independent and only compare strings we know are safe for
|
||||
* this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
|
||||
* some further explanation to why this function is necessary.
|
||||
*
|
||||
* The function is capable of comparing a-z case insensitively even for
|
||||
* non-ascii.
|
||||
*/
|
||||
|
||||
static int Curl_raw_equal(const char *first, const char *second)
|
||||
{
|
||||
while(*first && *second) {
|
||||
if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
|
||||
/* get out of the loop as soon as they don't match */
|
||||
break;
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
/* we do the comparison here (possibly again), just to make sure that if the
|
||||
loop above is skipped because one of the strings reached zero, we must not
|
||||
return this as a successful match */
|
||||
return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
|
||||
}
|
||||
|
||||
static int Curl_raw_nequal(const char *first, const char *second, size_t max)
|
||||
{
|
||||
while(*first && *second && max) {
|
||||
if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
|
||||
break;
|
||||
}
|
||||
max--;
|
||||
first++;
|
||||
second++;
|
||||
}
|
||||
if(0 == max)
|
||||
return 1; /* they are equal this far */
|
||||
|
||||
return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
|
||||
}
|
||||
|
||||
/*
|
||||
* Match a hostname against a wildcard pattern.
|
||||
* E.g.
|
||||
* "foo.host.com" matches "*.host.com".
|
||||
*
|
||||
* We use the matching rule described in RFC6125, section 6.4.3.
|
||||
* http://tools.ietf.org/html/rfc6125#section-6.4.3
|
||||
*/
|
||||
|
||||
static int hostmatch(const char *hostname, const char *pattern)
|
||||
{
|
||||
const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
|
||||
int wildcard_enabled;
|
||||
size_t prefixlen, suffixlen;
|
||||
pattern_wildcard = strchr(pattern, '*');
|
||||
if(pattern_wildcard == NULL)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
/* We require at least 2 dots in pattern to avoid too wide wildcard
|
||||
match. */
|
||||
wildcard_enabled = 1;
|
||||
pattern_label_end = strchr(pattern, '.');
|
||||
if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
|
||||
pattern_wildcard > pattern_label_end ||
|
||||
Curl_raw_nequal(pattern, "xn--", 4)) {
|
||||
wildcard_enabled = 0;
|
||||
}
|
||||
if(!wildcard_enabled)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
hostname_label_end = strchr(hostname, '.');
|
||||
if(hostname_label_end == NULL ||
|
||||
!Curl_raw_equal(pattern_label_end, hostname_label_end))
|
||||
return CURL_HOST_NOMATCH;
|
||||
|
||||
/* The wildcard must match at least one character, so the left-most
|
||||
label of the hostname is at least as large as the left-most label
|
||||
of the pattern. */
|
||||
if(hostname_label_end - hostname < pattern_label_end - pattern)
|
||||
return CURL_HOST_NOMATCH;
|
||||
|
||||
prefixlen = pattern_wildcard - pattern;
|
||||
suffixlen = pattern_label_end - (pattern_wildcard+1);
|
||||
return Curl_raw_nequal(pattern, hostname, prefixlen) &&
|
||||
Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
suffixlen) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
}
|
||||
|
||||
int Tool_Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
{
|
||||
if(!match_pattern || !*match_pattern ||
|
||||
!hostname || !*hostname) /* sanity check */
|
||||
return 0;
|
||||
|
||||
if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
|
||||
return 1;
|
||||
|
||||
if(hostmatch(hostname,match_pattern) == CURL_HOST_MATCH)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,43 +0,0 @@
|
||||
#ifndef HEADER_TOOL_CURL_HOSTCHECK_H
|
||||
#define HEADER_TOOL_CURL_HOSTCHECK_H
|
||||
|
||||
#ifdef OPENSSL_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#define CURL_HOST_NOMATCH 0
|
||||
#define CURL_HOST_MATCH 1
|
||||
int Tool_Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HOSTCHECK_H */
|
||||
|
@ -1,47 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* register_openssl.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "register_openssl.h"
|
||||
|
||||
#include "stream_peer_openssl.h"
|
||||
#ifdef OPENSSL_ENABLED
|
||||
|
||||
void register_openssl() {
|
||||
|
||||
ObjectTypeDB::register_type<StreamPeerOpenSSL>();
|
||||
StreamPeerOpenSSL::initialize_ssl();
|
||||
|
||||
}
|
||||
|
||||
void unregister_openssl() {
|
||||
|
||||
StreamPeerOpenSSL::finalize_ssl();
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* register_openssl.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef REGISTER_OPENSSL_H
|
||||
#define REGISTER_OPENSSL_H
|
||||
|
||||
#ifdef OPENSSL_ENABLED
|
||||
|
||||
void register_openssl();
|
||||
void unregister_openssl();
|
||||
|
||||
#endif
|
||||
|
||||
#endif // REGISTER_OPENSSL_H
|
@ -1,649 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* stream_peer_openssl.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifdef OPENSSL_ENABLED
|
||||
#include "stream_peer_openssl.h"
|
||||
//hostname matching code from curl
|
||||
|
||||
|
||||
//#include <openssl/applink.c> // To prevent crashing (see the OpenSSL FAQ)
|
||||
|
||||
bool StreamPeerOpenSSL::_match_host_name(const char *name, const char *hostname) {
|
||||
|
||||
return Tool_Curl_cert_hostcheck(name,hostname)==CURL_HOST_MATCH;
|
||||
// print_line("MATCH: "+String(name)+" vs "+String(hostname));
|
||||
// return true;
|
||||
}
|
||||
|
||||
Error StreamPeerOpenSSL::_match_common_name(const char *hostname, const X509 *server_cert) {
|
||||
|
||||
int common_name_loc = -1;
|
||||
X509_NAME_ENTRY *common_name_entry = NULL;
|
||||
ASN1_STRING *common_name_asn1 = NULL;
|
||||
char *common_name_str = NULL;
|
||||
|
||||
// Find the position of the CN field in the Subject field of the certificate
|
||||
common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name((X509 *) server_cert), NID_commonName, -1);
|
||||
|
||||
ERR_FAIL_COND_V(common_name_loc < 0, ERR_INVALID_PARAMETER );
|
||||
|
||||
// Extract the CN field
|
||||
common_name_entry = X509_NAME_get_entry(X509_get_subject_name((X509 *) server_cert), common_name_loc);
|
||||
|
||||
ERR_FAIL_COND_V(common_name_entry == NULL, ERR_INVALID_PARAMETER );
|
||||
|
||||
// Convert the CN field to a C string
|
||||
common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
|
||||
|
||||
ERR_FAIL_COND_V(common_name_asn1 == NULL, ERR_INVALID_PARAMETER );
|
||||
|
||||
common_name_str = (char *) ASN1_STRING_data(common_name_asn1);
|
||||
|
||||
// Make sure there isn't an embedded NUL character in the CN
|
||||
bool malformed_certificate = (size_t)ASN1_STRING_length(common_name_asn1) != strlen(common_name_str);
|
||||
|
||||
ERR_FAIL_COND_V(malformed_certificate, ERR_INVALID_PARAMETER );
|
||||
|
||||
|
||||
// Compare expected hostname with the CN
|
||||
|
||||
|
||||
return _match_host_name(common_name_str,hostname)?OK:FAILED;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tries to find a match for hostname in the certificate's Subject Alternative Name extension.
|
||||
*
|
||||
*/
|
||||
|
||||
Error StreamPeerOpenSSL::_match_subject_alternative_name(const char *hostname, const X509 *server_cert) {
|
||||
|
||||
Error result = FAILED;
|
||||
int i;
|
||||
int san_names_nb = -1;
|
||||
STACK_OF(GENERAL_NAME) *san_names = NULL;
|
||||
|
||||
// Try to extract the names within the SAN extension from the certificate
|
||||
san_names = (STACK_OF(GENERAL_NAME) *)X509_get_ext_d2i((X509 *) server_cert, NID_subject_alt_name, NULL, NULL);
|
||||
if (san_names == NULL) {
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
san_names_nb = sk_GENERAL_NAME_num(san_names);
|
||||
|
||||
// Check each name within the extension
|
||||
for (i=0; i<san_names_nb; i++) {
|
||||
const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i);
|
||||
|
||||
if (current_name->type == GEN_DNS) {
|
||||
// Current name is a DNS name, let's check it
|
||||
char *dns_name = (char *) ASN1_STRING_data(current_name->d.dNSName);
|
||||
|
||||
// Make sure there isn't an embedded NUL character in the DNS name
|
||||
if ((size_t)ASN1_STRING_length(current_name->d.dNSName) != strlen(dns_name)) {
|
||||
result = ERR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
else { // Compare expected hostname with the DNS name
|
||||
if (_match_host_name(dns_name, hostname)) {
|
||||
result = OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* See http://archives.seul.org/libevent/users/Jan-2013/msg00039.html */
|
||||
int StreamPeerOpenSSL::_cert_verify_callback(X509_STORE_CTX *x509_ctx, void *arg) {
|
||||
|
||||
/* This is the function that OpenSSL would call if we hadn't called
|
||||
* SSL_CTX_set_cert_verify_callback(). Therefore, we are "wrapping"
|
||||
* the default functionality, rather than replacing it. */
|
||||
|
||||
bool base_cert_valid = X509_verify_cert(x509_ctx);
|
||||
if (!base_cert_valid) {
|
||||
print_line("Cause: "+String(X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509_ctx))));
|
||||
ERR_print_errors_fp(stdout);
|
||||
}
|
||||
X509 *server_cert = X509_STORE_CTX_get_current_cert(x509_ctx);
|
||||
|
||||
ERR_FAIL_COND_V(!server_cert,0);
|
||||
|
||||
char cert_str[256];
|
||||
X509_NAME_oneline(X509_get_subject_name (server_cert),
|
||||
cert_str, sizeof (cert_str));
|
||||
|
||||
print_line("CERT STR: "+String(cert_str));
|
||||
print_line("VALID: "+itos(base_cert_valid));
|
||||
|
||||
if (!base_cert_valid)
|
||||
return 0;
|
||||
|
||||
StreamPeerOpenSSL *ssl = (StreamPeerOpenSSL *)arg;
|
||||
|
||||
if (ssl->validate_hostname) {
|
||||
|
||||
Error err = _match_subject_alternative_name(ssl->hostname.utf8().get_data(),server_cert);
|
||||
|
||||
if (err==ERR_FILE_NOT_FOUND) {
|
||||
|
||||
err = _match_common_name(ssl->hostname.utf8().get_data(),server_cert);
|
||||
}
|
||||
|
||||
if (err!=OK) {
|
||||
|
||||
ssl->status=STATUS_ERROR_HOSTNAME_MISMATCH;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int StreamPeerOpenSSL::_bio_create( BIO *b ) {
|
||||
b->init = 1;
|
||||
b->num = 0;
|
||||
b->ptr = NULL;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int StreamPeerOpenSSL::_bio_destroy( BIO *b )
|
||||
{
|
||||
if ( b == NULL )
|
||||
return 0;
|
||||
|
||||
b->ptr = NULL; /* sb_tls_remove() will free it */
|
||||
b->init = 0;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int StreamPeerOpenSSL::_bio_read( BIO *b, char *buf, int len ) {
|
||||
|
||||
|
||||
if ( buf == NULL || len <= 0 ) return 0;
|
||||
|
||||
StreamPeerOpenSSL *sp = (StreamPeerOpenSSL *)b->ptr;
|
||||
|
||||
ERR_FAIL_COND_V( sp == NULL, 0);
|
||||
|
||||
BIO_clear_retry_flags( b );
|
||||
if (sp->use_blocking) {
|
||||
|
||||
Error err = sp->base->get_data((uint8_t*)buf,len);
|
||||
if (err!=OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
} else {
|
||||
|
||||
int got;
|
||||
Error err = sp->base->get_partial_data((uint8_t*)buf,len,got);
|
||||
if (err!=OK) {
|
||||
return -1;
|
||||
}
|
||||
if (got==0) {
|
||||
BIO_set_retry_read( b );
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
//unreachable
|
||||
return 0;
|
||||
}
|
||||
|
||||
int StreamPeerOpenSSL::_bio_write( BIO *b, const char *buf, int len ) {
|
||||
|
||||
if ( buf == NULL || len <= 0 ) return 0;
|
||||
|
||||
StreamPeerOpenSSL *sp = (StreamPeerOpenSSL *)b->ptr;
|
||||
|
||||
ERR_FAIL_COND_V( sp == NULL, 0);
|
||||
|
||||
BIO_clear_retry_flags( b );
|
||||
if (sp->use_blocking) {
|
||||
|
||||
Error err = sp->base->put_data((const uint8_t*)buf,len);
|
||||
if (err!=OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
} else {
|
||||
|
||||
int sent;
|
||||
Error err = sp->base->put_partial_data((const uint8_t*)buf,len,sent);
|
||||
if (err!=OK) {
|
||||
return -1;
|
||||
}
|
||||
if (sent==0) {
|
||||
BIO_set_retry_write( b );
|
||||
}
|
||||
return sent;
|
||||
|
||||
}
|
||||
|
||||
//unreachable
|
||||
return 0;
|
||||
}
|
||||
|
||||
long StreamPeerOpenSSL::_bio_ctrl( BIO *b, int cmd, long num, void *ptr )
|
||||
{
|
||||
if ( cmd == BIO_CTRL_FLUSH ) {
|
||||
/* The OpenSSL library needs this */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int StreamPeerOpenSSL::_bio_gets( BIO *b, char *buf, int len )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StreamPeerOpenSSL::_bio_puts( BIO *b, const char *str )
|
||||
{
|
||||
return _bio_write( b, str, strlen( str ) );
|
||||
}
|
||||
|
||||
BIO_METHOD StreamPeerOpenSSL::_bio_method = {
|
||||
/* it's a source/sink BIO */
|
||||
( 100 | 0x400 ),
|
||||
"streampeer glue",
|
||||
_bio_write,
|
||||
_bio_read,
|
||||
_bio_puts,
|
||||
_bio_gets,
|
||||
_bio_ctrl,
|
||||
_bio_create,
|
||||
_bio_destroy
|
||||
};
|
||||
|
||||
Error StreamPeerOpenSSL::connect(Ref<StreamPeer> p_base, bool p_validate_certs, const String& p_for_hostname) {
|
||||
|
||||
if (connected)
|
||||
disconnect();
|
||||
|
||||
|
||||
hostname=p_for_hostname;
|
||||
status=STATUS_DISCONNECTED;
|
||||
|
||||
// Set up a SSL_CTX object, which will tell our BIO object how to do its work
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
base=p_base;
|
||||
validate_certs=p_validate_certs;
|
||||
validate_hostname=p_for_hostname!="";
|
||||
|
||||
|
||||
|
||||
|
||||
if (p_validate_certs) {
|
||||
|
||||
|
||||
if (certs.size()) {
|
||||
//yay for undocumented OpenSSL functions
|
||||
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(ctx);
|
||||
for(int i=0;i<certs.size();i++) {
|
||||
|
||||
X509_STORE_add_cert(store,certs[i]);
|
||||
|
||||
}
|
||||
#if 0
|
||||
const unsigned char *in=(const unsigned char *)certs.ptr();
|
||||
X509 *Cert = d2i_X509(NULL, &in, certs.size()-1);
|
||||
if (!Cert) {
|
||||
print_line(String(ERR_error_string(ERR_get_error(),NULL)));
|
||||
}
|
||||
ERR_FAIL_COND_V(!Cert,ERR_PARSE_ERROR);
|
||||
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(ctx);
|
||||
X509_STORE_add_cert(store,Cert);
|
||||
|
||||
//char *str = X509_NAME_oneline(X509_get_subject_name(Cert),0,0);
|
||||
//printf ("subject: %s\n", str); /* [1] */
|
||||
#endif
|
||||
}
|
||||
|
||||
//used for testing
|
||||
//int res = SSL_CTX_load_verify_locations(ctx,"/etc/ssl/certs/ca-certificates.crt",NULL);
|
||||
//print_line("verify locations res: "+itos(res));
|
||||
|
||||
|
||||
/* Ask OpenSSL to verify the server certificate. Note that this
|
||||
* does NOT include verifying that the hostname is correct.
|
||||
* So, by itself, this means anyone with any legitimate
|
||||
* CA-issued certificate for any website, can impersonate any
|
||||
* other website in the world. This is not good. See "The
|
||||
* Most Dangerous Code in the World" article at
|
||||
* https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html
|
||||
*/
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
/* This is how we solve the problem mentioned in the previous
|
||||
* comment. We "wrap" OpenSSL's validation routine in our
|
||||
* own routine, which also validates the hostname by calling
|
||||
* the code provided by iSECPartners. Note that even though
|
||||
* the "Everything You've Always Wanted to Know About
|
||||
* Certificate Validation With OpenSSL (But Were Afraid to
|
||||
* Ask)" paper from iSECPartners says very explicitly not to
|
||||
* call SSL_CTX_set_cert_verify_callback (at the bottom of
|
||||
* page 2), what we're doing here is safe because our
|
||||
* cert_verify_callback() calls X509_verify_cert(), which is
|
||||
* OpenSSL's built-in routine which would have been called if
|
||||
* we hadn't set the callback. Therefore, we're just
|
||||
* "wrapping" OpenSSL's routine, not replacing it. */
|
||||
SSL_CTX_set_cert_verify_callback (ctx, _cert_verify_callback,this);
|
||||
|
||||
//Let the verify_callback catch the verify_depth error so that we get an appropriate error in the logfile. (??)
|
||||
SSL_CTX_set_verify_depth(ctx,max_cert_chain_depth + 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ssl = SSL_new( ctx );
|
||||
bio = BIO_new( &_bio_method );
|
||||
bio->ptr = this;
|
||||
SSL_set_bio( ssl, bio, bio );
|
||||
|
||||
if (p_for_hostname!=String()) {
|
||||
SSL_set_tlsext_host_name(ssl,p_for_hostname.utf8().get_data());
|
||||
}
|
||||
|
||||
use_blocking=true; // let handshake use blocking
|
||||
// Set the SSL to automatically retry on failure.
|
||||
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
|
||||
// Same as before, try to connect.
|
||||
int result = SSL_connect( ssl );
|
||||
|
||||
print_line("CONNECTION RESULT: "+itos(result));
|
||||
if (result<1) {
|
||||
ERR_print_errors_fp(stdout);
|
||||
_print_error(result);
|
||||
}
|
||||
|
||||
X509 * peer = SSL_get_peer_certificate(ssl);
|
||||
|
||||
if (peer) {
|
||||
bool cert_ok = SSL_get_verify_result(ssl) == X509_V_OK;
|
||||
print_line("cert_ok: "+itos(cert_ok));
|
||||
|
||||
} else if (validate_certs){
|
||||
status=STATUS_ERROR_NO_CERTIFICATE;
|
||||
}
|
||||
|
||||
connected=true;
|
||||
status=STATUS_CONNECTED;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error StreamPeerOpenSSL::accept(Ref<StreamPeer> p_base) {
|
||||
|
||||
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
void StreamPeerOpenSSL::_print_error(int err) {
|
||||
|
||||
err = SSL_get_error(ssl,err);
|
||||
switch(err) {
|
||||
case SSL_ERROR_NONE: ERR_PRINT("NO ERROR: The TLS/SSL I/O operation completed"); break;
|
||||
case SSL_ERROR_ZERO_RETURN: ERR_PRINT("The TLS/SSL connection has been closed.");
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
ERR_PRINT("The operation did not complete."); break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
ERR_PRINT("The connect/accept operation did not complete"); break;
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
ERR_PRINT("The operation did not complete because an application callback set by SSL_CTX_set_client_cert_cb() has asked to be called again."); break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
ERR_PRINT("Some I/O error occurred. The OpenSSL error queue may contain more information on the error."); break;
|
||||
case SSL_ERROR_SSL:
|
||||
ERR_PRINT("A failure in the SSL library occurred, usually a protocol error."); break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Error StreamPeerOpenSSL::put_data(const uint8_t* p_data,int p_bytes) {
|
||||
|
||||
ERR_FAIL_COND_V(!connected,ERR_UNCONFIGURED);
|
||||
|
||||
while(p_bytes>0) {
|
||||
int ret = SSL_write(ssl,p_data,p_bytes);
|
||||
if (ret<=0) {
|
||||
_print_error(ret);
|
||||
disconnect();
|
||||
return ERR_CONNECTION_ERROR;
|
||||
}
|
||||
p_data+=ret;
|
||||
p_bytes-=ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
Error StreamPeerOpenSSL::put_partial_data(const uint8_t* p_data,int p_bytes, int &r_sent){
|
||||
|
||||
ERR_FAIL_COND_V(!connected,ERR_UNCONFIGURED);
|
||||
if (p_bytes==0)
|
||||
return OK;
|
||||
|
||||
Error err = put_data(p_data,p_bytes);
|
||||
if (err!=OK)
|
||||
return err;
|
||||
|
||||
r_sent=p_bytes;
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
Error StreamPeerOpenSSL::get_data(uint8_t* p_buffer, int p_bytes){
|
||||
|
||||
ERR_FAIL_COND_V(!connected,ERR_UNCONFIGURED);
|
||||
|
||||
while(p_bytes>0) {
|
||||
|
||||
int ret = SSL_read(ssl,p_buffer,p_bytes);
|
||||
if (ret<=0) {
|
||||
_print_error(ret);
|
||||
disconnect();
|
||||
return ERR_CONNECTION_ERROR;
|
||||
}
|
||||
p_buffer+=ret;
|
||||
p_bytes-=ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error StreamPeerOpenSSL::get_partial_data(uint8_t* p_buffer, int p_bytes,int &r_received){
|
||||
|
||||
ERR_FAIL_COND_V(!connected,ERR_UNCONFIGURED);
|
||||
if (p_bytes==0) {
|
||||
r_received=0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error err = get_data(p_buffer,p_bytes);
|
||||
if (err!=OK)
|
||||
return err;
|
||||
r_received=p_bytes;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int StreamPeerOpenSSL::get_available_bytes() const {
|
||||
|
||||
ERR_FAIL_COND_V(!connected,0);
|
||||
|
||||
return SSL_pending(ssl);
|
||||
|
||||
}
|
||||
StreamPeerOpenSSL::StreamPeerOpenSSL() {
|
||||
|
||||
ctx=NULL;
|
||||
ssl=NULL;
|
||||
bio=NULL;
|
||||
connected=false;
|
||||
use_blocking=true; //might be improved int the future, but for now it always blocks
|
||||
max_cert_chain_depth=9;
|
||||
flags=0;
|
||||
}
|
||||
|
||||
void StreamPeerOpenSSL::disconnect() {
|
||||
|
||||
if (!connected)
|
||||
return;
|
||||
SSL_shutdown( ssl );
|
||||
SSL_free( ssl );
|
||||
SSL_CTX_free(ctx);
|
||||
base=Ref<StreamPeer>();
|
||||
connected=false;
|
||||
validate_certs=false;
|
||||
validate_hostname=false;
|
||||
status=STATUS_DISCONNECTED;
|
||||
|
||||
|
||||
}
|
||||
|
||||
StreamPeerOpenSSL::Status StreamPeerOpenSSL::get_status() const {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
StreamPeerOpenSSL::~StreamPeerOpenSSL() {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
StreamPeerSSL* StreamPeerOpenSSL::_create_func() {
|
||||
|
||||
return memnew( StreamPeerOpenSSL );
|
||||
}
|
||||
|
||||
|
||||
Vector<X509*> StreamPeerOpenSSL::certs;
|
||||
|
||||
|
||||
void StreamPeerOpenSSL::_load_certs(const ByteArray& p_array) {
|
||||
|
||||
ByteArray::Read r = p_array.read();
|
||||
BIO* mem = BIO_new(BIO_s_mem());
|
||||
BIO_puts(mem,(const char*)r.ptr());
|
||||
while(true) {
|
||||
X509*cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
|
||||
if (!cert)
|
||||
break;
|
||||
certs.push_back(cert);
|
||||
}
|
||||
BIO_free(mem);
|
||||
}
|
||||
|
||||
void StreamPeerOpenSSL::initialize_ssl() {
|
||||
|
||||
available=true;
|
||||
|
||||
load_certs_func=_load_certs;
|
||||
|
||||
_create=_create_func;
|
||||
CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use
|
||||
SSL_library_init(); // Initialize OpenSSL's SSL libraries
|
||||
SSL_load_error_strings(); // Load SSL error strings
|
||||
ERR_load_BIO_strings(); // Load BIO error strings
|
||||
OpenSSL_add_all_algorithms(); // Load all available encryption algorithms
|
||||
String certs_path =GLOBAL_DEF("ssl/certificates","");
|
||||
Globals::get_singleton()->set_custom_property_info("ssl/certificates",PropertyInfo(Variant::STRING,"ssl/certificates",PROPERTY_HINT_FILE,"*.crt"));
|
||||
if (certs_path!="") {
|
||||
|
||||
|
||||
|
||||
FileAccess *f=FileAccess::open(certs_path,FileAccess::READ);
|
||||
if (f) {
|
||||
ByteArray arr;
|
||||
int flen = f->get_len();
|
||||
arr.resize(flen+1);
|
||||
{
|
||||
ByteArray::Write w = arr.write();
|
||||
f->get_buffer(w.ptr(),flen);
|
||||
w[flen]=0; //end f string
|
||||
}
|
||||
|
||||
memdelete(f);
|
||||
|
||||
_load_certs(arr);
|
||||
print_line("Loaded certs from '"+certs_path+"': "+itos(certs.size()));
|
||||
}
|
||||
}
|
||||
String config_path =GLOBAL_DEF("ssl/config","");
|
||||
Globals::get_singleton()->set_custom_property_info("ssl/config",PropertyInfo(Variant::STRING,"ssl/config",PROPERTY_HINT_FILE,"*.cnf"));
|
||||
if (config_path!="") {
|
||||
|
||||
Vector<uint8_t> data = FileAccess::get_file_as_array(config_path);
|
||||
if (data.size()) {
|
||||
data.push_back(0);
|
||||
BIO* mem = BIO_new(BIO_s_mem());
|
||||
BIO_puts(mem,(const char*) data.ptr());
|
||||
|
||||
while(true) {
|
||||
X509*cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
|
||||
if (!cert)
|
||||
break;
|
||||
certs.push_back(cert);
|
||||
}
|
||||
BIO_free(mem);
|
||||
}
|
||||
print_line("Loaded certs from '"+certs_path+"': "+itos(certs.size()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void StreamPeerOpenSSL::finalize_ssl(){
|
||||
|
||||
for(int i=0;i<certs.size();i++) {
|
||||
X509_free(certs[i]);
|
||||
}
|
||||
certs.clear();
|
||||
}
|
||||
|
||||
#endif
|
@ -1,113 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* stream_peer_openssl.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef STREAM_PEER_OPEN_SSL_H
|
||||
#define STREAM_PEER_OPEN_SSL_H
|
||||
|
||||
#ifdef OPENSSL_ENABLED
|
||||
|
||||
|
||||
#include <stdio.h> // If you don't know what this is for stop reading now.
|
||||
#include "io/stream_peer_ssl.h"
|
||||
#include "globals.h"
|
||||
#include "os/file_access.h"
|
||||
#include "curl_hostcheck.h"
|
||||
|
||||
#include <openssl/bio.h> // BIO objects for I/O
|
||||
#include <openssl/ssl.h> // SSL and SSL_CTX for SSL connections
|
||||
#include <openssl/err.h> // Error reporting
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
class StreamPeerOpenSSL : public StreamPeerSSL {
|
||||
private:
|
||||
static int _bio_create( BIO *b );
|
||||
static int _bio_destroy( BIO *b );
|
||||
static int _bio_read( BIO *b, char *buf, int len );
|
||||
static int _bio_write( BIO *b, const char *buf, int len );
|
||||
static long _bio_ctrl( BIO *b, int cmd, long num, void *ptr );
|
||||
static int _bio_gets( BIO *b, char *buf, int len );
|
||||
static int _bio_puts( BIO *b, const char *str );
|
||||
|
||||
static BIO_METHOD _bio_method;
|
||||
|
||||
static bool _match_host_name(const char *name, const char *hostname);
|
||||
static Error _match_common_name(const char *hostname, const X509 *server_cert);
|
||||
static Error _match_subject_alternative_name(const char *hostname, const X509 *server_cert);
|
||||
|
||||
|
||||
static int _cert_verify_callback(X509_STORE_CTX *x509_ctx, void *arg);
|
||||
|
||||
|
||||
Status status;
|
||||
String hostname;
|
||||
int max_cert_chain_depth;
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
BIO* bio;
|
||||
bool connected;
|
||||
int flags;
|
||||
bool use_blocking;
|
||||
bool validate_certs;
|
||||
bool validate_hostname;
|
||||
|
||||
Ref<StreamPeer> base;
|
||||
|
||||
static StreamPeerSSL* _create_func();
|
||||
void _print_error(int err);
|
||||
|
||||
static Vector<X509*> certs;
|
||||
|
||||
static void _load_certs(const ByteArray& p_array);
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
|
||||
virtual Error accept(Ref<StreamPeer> p_base);
|
||||
virtual Error connect(Ref<StreamPeer> p_base,bool p_validate_certs=false,const String& p_for_hostname=String());
|
||||
virtual Status get_status() const;
|
||||
|
||||
virtual void disconnect();
|
||||
|
||||
virtual Error put_data(const uint8_t* p_data,int p_bytes);
|
||||
virtual Error put_partial_data(const uint8_t* p_data,int p_bytes, int &r_sent);
|
||||
|
||||
virtual Error get_data(uint8_t* p_buffer, int p_bytes);
|
||||
virtual Error get_partial_data(uint8_t* p_buffer, int p_bytes,int &r_received);
|
||||
|
||||
virtual int get_available_bytes() const;
|
||||
|
||||
static void initialize_ssl();
|
||||
static void finalize_ssl();
|
||||
|
||||
StreamPeerOpenSSL();
|
||||
~StreamPeerOpenSSL();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // STREAM_PEER_SSL_H
|
@ -1,196 +0,0 @@
|
||||
Import('env')
|
||||
|
||||
opus_sources = [
|
||||
"opus/audio_stream_opus.cpp",
|
||||
]
|
||||
|
||||
opus_sources_silk=[]
|
||||
|
||||
opus_sources_lib = [
|
||||
"opus/silk/tables_other.c",
|
||||
"opus/silk/sum_sqr_shift.c",
|
||||
"opus/silk/PLC.c",
|
||||
"opus/silk/dec_API.c",
|
||||
"opus/silk/decode_pulses.c",
|
||||
"opus/silk/inner_prod_aligned.c",
|
||||
"opus/silk/init_encoder.c",
|
||||
"opus/silk/interpolate.c",
|
||||
"opus/silk/stereo_encode_pred.c",
|
||||
"opus/silk/decode_frame.c",
|
||||
"opus/silk/NLSF_del_dec_quant.c",
|
||||
"opus/silk/VAD.c",
|
||||
"opus/silk/resampler_private_AR2.c",
|
||||
"opus/silk/NLSF_unpack.c",
|
||||
"opus/silk/resampler_down2.c",
|
||||
"opus/silk/sort.c",
|
||||
"opus/silk/resampler_private_IIR_FIR.c",
|
||||
"opus/silk/resampler_down2_3.c",
|
||||
"opus/silk/resampler_private_up2_HQ.c",
|
||||
"opus/silk/tables_gain.c",
|
||||
"opus/silk/stereo_find_predictor.c",
|
||||
"opus/silk/stereo_quant_pred.c",
|
||||
"opus/silk/NLSF_stabilize.c",
|
||||
"opus/silk/ana_filt_bank_1.c",
|
||||
"opus/silk/check_control_input.c",
|
||||
"opus/silk/bwexpander.c",
|
||||
"opus/silk/A2NLSF.c",
|
||||
"opus/silk/LPC_inv_pred_gain.c",
|
||||
"opus/silk/log2lin.c",
|
||||
"opus/silk/process_NLSFs.c",
|
||||
"opus/silk/sigm_Q15.c",
|
||||
"opus/silk/VQ_WMat_EC.c",
|
||||
"opus/silk/quant_LTP_gains.c",
|
||||
"opus/silk/resampler_private_down_FIR.c",
|
||||
"opus/silk/NLSF_decode.c",
|
||||
"opus/silk/control_codec.c",
|
||||
"opus/silk/NLSF_VQ_weights_laroia.c",
|
||||
"opus/silk/decode_pitch.c",
|
||||
"opus/silk/stereo_decode_pred.c",
|
||||
"opus/silk/tables_pulses_per_block.c",
|
||||
"opus/silk/init_decoder.c",
|
||||
"opus/silk/table_LSF_cos.c",
|
||||
"opus/silk/decode_core.c",
|
||||
"opus/silk/code_signs.c",
|
||||
"opus/silk/enc_API.c",
|
||||
"opus/silk/tables_LTP.c",
|
||||
"opus/silk/pitch_est_tables.c",
|
||||
"opus/silk/biquad_alt.c",
|
||||
"opus/silk/encode_indices.c",
|
||||
"opus/silk/tables_NLSF_CB_WB.c",
|
||||
"opus/silk/debug.c",
|
||||
"opus/silk/decode_parameters.c",
|
||||
"opus/silk/tables_pitch_lag.c",
|
||||
"opus/silk/NLSF2A.c",
|
||||
"opus/silk/resampler.c",
|
||||
"opus/silk/decode_indices.c",
|
||||
"opus/silk/NLSF_VQ.c",
|
||||
"opus/silk/bwexpander_32.c",
|
||||
"opus/silk/tables_NLSF_CB_NB_MB.c",
|
||||
"opus/silk/encode_pulses.c",
|
||||
"opus/silk/NSQ_del_dec.c",
|
||||
"opus/silk/control_SNR.c",
|
||||
"opus/silk/shell_coder.c",
|
||||
"opus/silk/NLSF_encode.c",
|
||||
"opus/silk/stereo_MS_to_LR.c",
|
||||
"opus/silk/stereo_LR_to_MS.c",
|
||||
"opus/silk/HP_variable_cutoff.c",
|
||||
"opus/silk/LPC_analysis_filter.c",
|
||||
"opus/silk/CNG.c",
|
||||
"opus/silk/decoder_set_fs.c",
|
||||
"opus/silk/resampler_rom.c",
|
||||
"opus/silk/control_audio_bandwidth.c",
|
||||
"opus/silk/lin2log.c",
|
||||
"opus/silk/LP_variable_cutoff.c",
|
||||
"opus/silk/NSQ.c",
|
||||
"opus/silk/gain_quant.c",
|
||||
"opus/celt/laplace.c",
|
||||
"opus/celt/vq.c",
|
||||
"opus/celt/quant_bands.c",
|
||||
"opus/celt/kiss_fft.c",
|
||||
"opus/celt/entcode.c",
|
||||
"opus/celt/entenc.c",
|
||||
"opus/celt/celt_lpc.c",
|
||||
"opus/celt/pitch.c",
|
||||
"opus/celt/rate.c",
|
||||
"opus/celt/mathops.c",
|
||||
#"opus/celt/arm/armcpu.c",
|
||||
#"opus/celt/arm/celt_neon_intr.c",
|
||||
#"opus/celt/arm/celt_ne10_mdct.c",
|
||||
#"opus/celt/arm/celt_ne10_fft.c",
|
||||
#"opus/celt/arm/arm_celt_map.c",
|
||||
"opus/celt/celt_encoder.c",
|
||||
"opus/celt/celt.c",
|
||||
"opus/celt/bands.c",
|
||||
"opus/celt/cwrs.c",
|
||||
"opus/celt/entdec.c",
|
||||
"opus/celt/celt_decoder.c",
|
||||
"opus/celt/mdct.c",
|
||||
"opus/celt/modes.c",
|
||||
"opus/repacketizer.c",
|
||||
"opus/mlp_data.c",
|
||||
"opus/opus_multistream.c",
|
||||
"opus/opusfile.c",
|
||||
"opus/opus_encoder.c",
|
||||
"opus/analysis.c",
|
||||
"opus/mlp.c",
|
||||
"opus/info.c",
|
||||
"opus/stream.c",
|
||||
"opus/opus_decoder.c",
|
||||
"opus/internal.c",
|
||||
"opus/wincerts.c",
|
||||
"opus/opus.c",
|
||||
"opus/opus_multistream_encoder.c",
|
||||
"opus/http.c",
|
||||
"opus/opus_multistream_decoder.c"
|
||||
]
|
||||
|
||||
if("opus_fixed_point" in env and env.opus_fixed_point=="yes"):
|
||||
env.Append(CFLAGS=["-DOPUS_FIXED_POINT"])
|
||||
opus_sources_silk = [
|
||||
"opus/silk/fixed/schur64_FIX.c",
|
||||
"opus/silk/fixed/residual_energy16_FIX.c",
|
||||
"opus/silk/fixed/encode_frame_FIX.c",
|
||||
"opus/silk/fixed/regularize_correlations_FIX.c",
|
||||
"opus/silk/fixed/apply_sine_window_FIX.c",
|
||||
"opus/silk/fixed/solve_LS_FIX.c",
|
||||
"opus/silk/fixed/schur_FIX.c",
|
||||
"opus/silk/fixed/pitch_analysis_core_FIX.c",
|
||||
"opus/silk/fixed/noise_shape_analysis_FIX.c",
|
||||
"opus/silk/fixed/find_LTP_FIX.c",
|
||||
"opus/silk/fixed/vector_ops_FIX.c",
|
||||
"opus/silk/fixed/autocorr_FIX.c",
|
||||
"opus/silk/fixed/warped_autocorrelation_FIX.c",
|
||||
"opus/silk/fixed/find_pitch_lags_FIX.c",
|
||||
"opus/silk/fixed/k2a_Q16_FIX.c",
|
||||
"opus/silk/fixed/LTP_scale_ctrl_FIX.c",
|
||||
"opus/silk/fixed/corrMatrix_FIX.c",
|
||||
"opus/silk/fixed/prefilter_FIX.c",
|
||||
"opus/silk/fixed/find_LPC_FIX.c",
|
||||
"opus/silk/fixed/residual_energy_FIX.c",
|
||||
"opus/silk/fixed/process_gains_FIX.c",
|
||||
"opus/silk/fixed/LTP_analysis_filter_FIX.c",
|
||||
"opus/silk/fixed/k2a_FIX.c",
|
||||
"opus/silk/fixed/burg_modified_FIX.c",
|
||||
"opus/silk/fixed/find_pred_coefs_FIX.c"
|
||||
]
|
||||
else:
|
||||
opus_sources_silk = [
|
||||
"opus/silk/float/LTP_scale_ctrl_FLP.c",
|
||||
"opus/silk/float/regularize_correlations_FLP.c",
|
||||
"opus/silk/float/corrMatrix_FLP.c",
|
||||
"opus/silk/float/LPC_analysis_filter_FLP.c",
|
||||
"opus/silk/float/levinsondurbin_FLP.c",
|
||||
"opus/silk/float/schur_FLP.c",
|
||||
"opus/silk/float/scale_vector_FLP.c",
|
||||
"opus/silk/float/apply_sine_window_FLP.c",
|
||||
"opus/silk/float/pitch_analysis_core_FLP.c",
|
||||
"opus/silk/float/wrappers_FLP.c",
|
||||
"opus/silk/float/bwexpander_FLP.c",
|
||||
"opus/silk/float/warped_autocorrelation_FLP.c",
|
||||
"opus/silk/float/solve_LS_FLP.c",
|
||||
"opus/silk/float/find_LPC_FLP.c",
|
||||
"opus/silk/float/autocorrelation_FLP.c",
|
||||
"opus/silk/float/find_pred_coefs_FLP.c",
|
||||
"opus/silk/float/find_pitch_lags_FLP.c",
|
||||
"opus/silk/float/burg_modified_FLP.c",
|
||||
"opus/silk/float/find_LTP_FLP.c",
|
||||
"opus/silk/float/energy_FLP.c",
|
||||
"opus/silk/float/sort_FLP.c",
|
||||
"opus/silk/float/LPC_inv_pred_gain_FLP.c",
|
||||
"opus/silk/float/k2a_FLP.c",
|
||||
"opus/silk/float/noise_shape_analysis_FLP.c",
|
||||
"opus/silk/float/inner_product_FLP.c",
|
||||
"opus/silk/float/process_gains_FLP.c",
|
||||
"opus/silk/float/encode_frame_FLP.c",
|
||||
"opus/silk/float/scale_copy_vector_FLP.c",
|
||||
"opus/silk/float/residual_energy_FLP.c",
|
||||
"opus/silk/float/LTP_analysis_filter_FLP.c",
|
||||
"opus/silk/float/prefilter_FLP.c"
|
||||
]
|
||||
|
||||
|
||||
env.drivers_sources+=opus_sources_silk
|
||||
env.drivers_sources+=opus_sources_lib
|
||||
env.drivers_sources+=opus_sources
|
||||
|
||||
Export('env')
|
@ -1,672 +0,0 @@
|
||||
/* Copyright (c) 2011 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/celt.h"
|
||||
#include "opus/celt/modes.h"
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/quant_bands.h"
|
||||
#include <stdio.h>
|
||||
#include "opus/analysis.h"
|
||||
#include "opus/mlp.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141592653
|
||||
#endif
|
||||
|
||||
static const float dct_table[128] = {
|
||||
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
|
||||
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
|
||||
0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f,
|
||||
-0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f,
|
||||
0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f,
|
||||
-0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f,
|
||||
0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f,
|
||||
0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f,
|
||||
0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
|
||||
0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
|
||||
0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f,
|
||||
-0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f,
|
||||
0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f,
|
||||
-0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f,
|
||||
0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f,
|
||||
0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f,
|
||||
};
|
||||
|
||||
static const float analysis_window[240] = {
|
||||
0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f,
|
||||
0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f,
|
||||
0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f,
|
||||
0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f,
|
||||
0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f,
|
||||
0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f,
|
||||
0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f,
|
||||
0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f,
|
||||
0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f,
|
||||
0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f,
|
||||
0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f,
|
||||
0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f,
|
||||
0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f,
|
||||
0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f,
|
||||
0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f,
|
||||
0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f,
|
||||
0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f,
|
||||
0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f,
|
||||
0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f,
|
||||
0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f,
|
||||
0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f,
|
||||
0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f,
|
||||
0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f,
|
||||
0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f,
|
||||
0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f,
|
||||
0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f,
|
||||
0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f,
|
||||
0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f,
|
||||
0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f,
|
||||
0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f,
|
||||
};
|
||||
|
||||
static const int tbands[NB_TBANDS+1] = {
|
||||
2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120
|
||||
};
|
||||
|
||||
static const int extra_bands[NB_TOT_BANDS+1] = {
|
||||
1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200
|
||||
};
|
||||
|
||||
/*static const float tweight[NB_TBANDS+1] = {
|
||||
.3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5
|
||||
};*/
|
||||
|
||||
#define NB_TONAL_SKIP_BANDS 9
|
||||
|
||||
#define cA 0.43157974f
|
||||
#define cB 0.67848403f
|
||||
#define cC 0.08595542f
|
||||
#define cE ((float)M_PI/2)
|
||||
static OPUS_INLINE float fast_atan2f(float y, float x) {
|
||||
float x2, y2;
|
||||
/* Should avoid underflow on the values we'll get */
|
||||
if (ABS16(x)+ABS16(y)<1e-9f)
|
||||
{
|
||||
x*=1e12f;
|
||||
y*=1e12f;
|
||||
}
|
||||
x2 = x*x;
|
||||
y2 = y*y;
|
||||
if(x2<y2){
|
||||
float den = (y2 + cB*x2) * (y2 + cC*x2);
|
||||
if (den!=0)
|
||||
return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
|
||||
else
|
||||
return (y<0 ? -cE : cE);
|
||||
}else{
|
||||
float den = (x2 + cB*y2) * (x2 + cC*y2);
|
||||
if (den!=0)
|
||||
return x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
|
||||
else
|
||||
return (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
|
||||
}
|
||||
}
|
||||
|
||||
void tonality_analysis_init(TonalityAnalysisState *tonal)
|
||||
{
|
||||
/* Initialize reusable fields. */
|
||||
tonal->arch = opus_select_arch();
|
||||
/* Clear remaining fields. */
|
||||
tonality_analysis_reset(tonal);
|
||||
}
|
||||
|
||||
void tonality_analysis_reset(TonalityAnalysisState *tonal)
|
||||
{
|
||||
/* Clear non-reusable fields. */
|
||||
char *start = (char*)&tonal->TONALITY_ANALYSIS_RESET_START;
|
||||
OPUS_CLEAR(start, sizeof(TonalityAnalysisState) - (start - (char*)tonal));
|
||||
}
|
||||
|
||||
void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len)
|
||||
{
|
||||
int pos;
|
||||
int curr_lookahead;
|
||||
float psum;
|
||||
int i;
|
||||
|
||||
pos = tonal->read_pos;
|
||||
curr_lookahead = tonal->write_pos-tonal->read_pos;
|
||||
if (curr_lookahead<0)
|
||||
curr_lookahead += DETECT_SIZE;
|
||||
|
||||
if (len > 480 && pos != tonal->write_pos)
|
||||
{
|
||||
pos++;
|
||||
if (pos==DETECT_SIZE)
|
||||
pos=0;
|
||||
}
|
||||
if (pos == tonal->write_pos)
|
||||
pos--;
|
||||
if (pos<0)
|
||||
pos = DETECT_SIZE-1;
|
||||
OPUS_COPY(info_out, &tonal->info[pos], 1);
|
||||
tonal->read_subframe += len/120;
|
||||
while (tonal->read_subframe>=4)
|
||||
{
|
||||
tonal->read_subframe -= 4;
|
||||
tonal->read_pos++;
|
||||
}
|
||||
if (tonal->read_pos>=DETECT_SIZE)
|
||||
tonal->read_pos-=DETECT_SIZE;
|
||||
|
||||
/* Compensate for the delay in the features themselves.
|
||||
FIXME: Need a better estimate the 10 I just made up */
|
||||
curr_lookahead = IMAX(curr_lookahead-10, 0);
|
||||
|
||||
psum=0;
|
||||
/* Summing the probability of transition patterns that involve music at
|
||||
time (DETECT_SIZE-curr_lookahead-1) */
|
||||
for (i=0;i<DETECT_SIZE-curr_lookahead;i++)
|
||||
psum += tonal->pmusic[i];
|
||||
for (;i<DETECT_SIZE;i++)
|
||||
psum += tonal->pspeech[i];
|
||||
psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence;
|
||||
/*printf("%f %f %f\n", psum, info_out->music_prob, info_out->tonality);*/
|
||||
|
||||
info_out->music_prob = psum;
|
||||
}
|
||||
|
||||
static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)
|
||||
{
|
||||
int i, b;
|
||||
const kiss_fft_state *kfft;
|
||||
VARDECL(kiss_fft_cpx, in);
|
||||
VARDECL(kiss_fft_cpx, out);
|
||||
int N = 480, N2=240;
|
||||
float * OPUS_RESTRICT A = tonal->angle;
|
||||
float * OPUS_RESTRICT dA = tonal->d_angle;
|
||||
float * OPUS_RESTRICT d2A = tonal->d2_angle;
|
||||
VARDECL(float, tonality);
|
||||
VARDECL(float, noisiness);
|
||||
float band_tonality[NB_TBANDS];
|
||||
float logE[NB_TBANDS];
|
||||
float BFCC[8];
|
||||
float features[25];
|
||||
float frame_tonality;
|
||||
float max_frame_tonality;
|
||||
/*float tw_sum=0;*/
|
||||
float frame_noisiness;
|
||||
const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI);
|
||||
float slope=0;
|
||||
float frame_stationarity;
|
||||
float relativeE;
|
||||
float frame_probs[2];
|
||||
float alpha, alphaE, alphaE2;
|
||||
float frame_loudness;
|
||||
float bandwidth_mask;
|
||||
int bandwidth=0;
|
||||
float maxE = 0;
|
||||
float noise_floor;
|
||||
int remaining;
|
||||
AnalysisInfo *info;
|
||||
SAVE_STACK;
|
||||
|
||||
tonal->last_transition++;
|
||||
alpha = 1.f/IMIN(20, 1+tonal->count);
|
||||
alphaE = 1.f/IMIN(50, 1+tonal->count);
|
||||
alphaE2 = 1.f/IMIN(1000, 1+tonal->count);
|
||||
|
||||
if (tonal->count<4)
|
||||
tonal->music_prob = .5;
|
||||
kfft = celt_mode->mdct.kfft[0];
|
||||
if (tonal->count==0)
|
||||
tonal->mem_fill = 240;
|
||||
downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C);
|
||||
if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)
|
||||
{
|
||||
tonal->mem_fill += len;
|
||||
/* Don't have enough to update the analysis */
|
||||
RESTORE_STACK;
|
||||
return;
|
||||
}
|
||||
info = &tonal->info[tonal->write_pos++];
|
||||
if (tonal->write_pos>=DETECT_SIZE)
|
||||
tonal->write_pos-=DETECT_SIZE;
|
||||
|
||||
ALLOC(in, 480, kiss_fft_cpx);
|
||||
ALLOC(out, 480, kiss_fft_cpx);
|
||||
ALLOC(tonality, 240, float);
|
||||
ALLOC(noisiness, 240, float);
|
||||
for (i=0;i<N2;i++)
|
||||
{
|
||||
float w = analysis_window[i];
|
||||
in[i].r = (kiss_fft_scalar)(w*tonal->inmem[i]);
|
||||
in[i].i = (kiss_fft_scalar)(w*tonal->inmem[N2+i]);
|
||||
in[N-i-1].r = (kiss_fft_scalar)(w*tonal->inmem[N-i-1]);
|
||||
in[N-i-1].i = (kiss_fft_scalar)(w*tonal->inmem[N+N2-i-1]);
|
||||
}
|
||||
OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
|
||||
remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
|
||||
downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C);
|
||||
tonal->mem_fill = 240 + remaining;
|
||||
opus_fft(kfft, in, out, tonal->arch);
|
||||
#ifndef OPUS_FIXED_POINT
|
||||
/* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */
|
||||
if (celt_isnan(out[0].r))
|
||||
{
|
||||
info->valid = 0;
|
||||
RESTORE_STACK;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i=1;i<N2;i++)
|
||||
{
|
||||
float X1r, X2r, X1i, X2i;
|
||||
float angle, d_angle, d2_angle;
|
||||
float angle2, d_angle2, d2_angle2;
|
||||
float mod1, mod2, avg_mod;
|
||||
X1r = (float)out[i].r+out[N-i].r;
|
||||
X1i = (float)out[i].i-out[N-i].i;
|
||||
X2r = (float)out[i].i+out[N-i].i;
|
||||
X2i = (float)out[N-i].r-out[i].r;
|
||||
|
||||
angle = (float)(.5f/M_PI)*fast_atan2f(X1i, X1r);
|
||||
d_angle = angle - A[i];
|
||||
d2_angle = d_angle - dA[i];
|
||||
|
||||
angle2 = (float)(.5f/M_PI)*fast_atan2f(X2i, X2r);
|
||||
d_angle2 = angle2 - angle;
|
||||
d2_angle2 = d_angle2 - d_angle;
|
||||
|
||||
mod1 = d2_angle - (float)floor(.5+d2_angle);
|
||||
noisiness[i] = ABS16(mod1);
|
||||
mod1 *= mod1;
|
||||
mod1 *= mod1;
|
||||
|
||||
mod2 = d2_angle2 - (float)floor(.5+d2_angle2);
|
||||
noisiness[i] += ABS16(mod2);
|
||||
mod2 *= mod2;
|
||||
mod2 *= mod2;
|
||||
|
||||
avg_mod = .25f*(d2A[i]+2.f*mod1+mod2);
|
||||
tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;
|
||||
|
||||
A[i] = angle2;
|
||||
dA[i] = d_angle2;
|
||||
d2A[i] = mod2;
|
||||
}
|
||||
|
||||
frame_tonality = 0;
|
||||
max_frame_tonality = 0;
|
||||
/*tw_sum = 0;*/
|
||||
info->activity = 0;
|
||||
frame_noisiness = 0;
|
||||
frame_stationarity = 0;
|
||||
if (!tonal->count)
|
||||
{
|
||||
for (b=0;b<NB_TBANDS;b++)
|
||||
{
|
||||
tonal->lowE[b] = 1e10;
|
||||
tonal->highE[b] = -1e10;
|
||||
}
|
||||
}
|
||||
relativeE = 0;
|
||||
frame_loudness = 0;
|
||||
for (b=0;b<NB_TBANDS;b++)
|
||||
{
|
||||
float E=0, tE=0, nE=0;
|
||||
float L1, L2;
|
||||
float stationarity;
|
||||
for (i=tbands[b];i<tbands[b+1];i++)
|
||||
{
|
||||
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
|
||||
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
/* FIXME: It's probably best to change the BFCC filter initial state instead */
|
||||
binE *= 5.55e-17f;
|
||||
#endif
|
||||
E += binE;
|
||||
tE += binE*tonality[i];
|
||||
nE += binE*2.f*(.5f-noisiness[i]);
|
||||
}
|
||||
#ifndef OPUS_FIXED_POINT
|
||||
/* Check for extreme band energies that could cause NaNs later. */
|
||||
if (!(E<1e9f) || celt_isnan(E))
|
||||
{
|
||||
info->valid = 0;
|
||||
RESTORE_STACK;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
tonal->E[tonal->E_count][b] = E;
|
||||
frame_noisiness += nE/(1e-15f+E);
|
||||
|
||||
frame_loudness += (float)sqrt(E+1e-10f);
|
||||
logE[b] = (float)log(E+1e-10f);
|
||||
tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);
|
||||
tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);
|
||||
if (tonal->highE[b] < tonal->lowE[b]+1.f)
|
||||
{
|
||||
tonal->highE[b]+=.5f;
|
||||
tonal->lowE[b]-=.5f;
|
||||
}
|
||||
relativeE += (logE[b]-tonal->lowE[b])/(1e-15f+tonal->highE[b]-tonal->lowE[b]);
|
||||
|
||||
L1=L2=0;
|
||||
for (i=0;i<NB_FRAMES;i++)
|
||||
{
|
||||
L1 += (float)sqrt(tonal->E[i][b]);
|
||||
L2 += tonal->E[i][b];
|
||||
}
|
||||
|
||||
stationarity = MIN16(0.99f,L1/(float)sqrt(1e-15+NB_FRAMES*L2));
|
||||
stationarity *= stationarity;
|
||||
stationarity *= stationarity;
|
||||
frame_stationarity += stationarity;
|
||||
/*band_tonality[b] = tE/(1e-15+E)*/;
|
||||
band_tonality[b] = MAX16(tE/(1e-15f+E), stationarity*tonal->prev_band_tonality[b]);
|
||||
#if 0
|
||||
if (b>=NB_TONAL_SKIP_BANDS)
|
||||
{
|
||||
frame_tonality += tweight[b]*band_tonality[b];
|
||||
tw_sum += tweight[b];
|
||||
}
|
||||
#else
|
||||
frame_tonality += band_tonality[b];
|
||||
if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS)
|
||||
frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS];
|
||||
#endif
|
||||
max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality);
|
||||
slope += band_tonality[b]*(b-8);
|
||||
/*printf("%f %f ", band_tonality[b], stationarity);*/
|
||||
tonal->prev_band_tonality[b] = band_tonality[b];
|
||||
}
|
||||
|
||||
bandwidth_mask = 0;
|
||||
bandwidth = 0;
|
||||
maxE = 0;
|
||||
noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
noise_floor *= 1<<(15+SIG_SHIFT);
|
||||
#endif
|
||||
noise_floor *= noise_floor;
|
||||
for (b=0;b<NB_TOT_BANDS;b++)
|
||||
{
|
||||
float E=0;
|
||||
int band_start, band_end;
|
||||
/* Keep a margin of 300 Hz for aliasing */
|
||||
band_start = extra_bands[b];
|
||||
band_end = extra_bands[b+1];
|
||||
for (i=band_start;i<band_end;i++)
|
||||
{
|
||||
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
|
||||
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
|
||||
E += binE;
|
||||
}
|
||||
maxE = MAX32(maxE, E);
|
||||
tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
|
||||
E = MAX32(E, tonal->meanE[b]);
|
||||
/* Use a simple follower with 13 dB/Bark slope for spreading function */
|
||||
bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
|
||||
/* Consider the band "active" only if all these conditions are met:
|
||||
1) less than 10 dB below the simple follower
|
||||
2) less than 90 dB below the peak band (maximal masking possible considering
|
||||
both the ATH and the loudness-dependent slope of the spreading function)
|
||||
3) above the PCM quantization noise floor
|
||||
*/
|
||||
if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start))
|
||||
bandwidth = b;
|
||||
}
|
||||
if (tonal->count<=2)
|
||||
bandwidth = 20;
|
||||
frame_loudness = 20*(float)log10(frame_loudness);
|
||||
tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness);
|
||||
tonal->lowECount *= (1-alphaE);
|
||||
if (frame_loudness < tonal->Etracker-30)
|
||||
tonal->lowECount += alphaE;
|
||||
|
||||
for (i=0;i<8;i++)
|
||||
{
|
||||
float sum=0;
|
||||
for (b=0;b<16;b++)
|
||||
sum += dct_table[i*16+b]*logE[b];
|
||||
BFCC[i] = sum;
|
||||
}
|
||||
|
||||
frame_stationarity /= NB_TBANDS;
|
||||
relativeE /= NB_TBANDS;
|
||||
if (tonal->count<10)
|
||||
relativeE = .5;
|
||||
frame_noisiness /= NB_TBANDS;
|
||||
#if 1
|
||||
info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;
|
||||
#else
|
||||
info->activity = .5*(1+frame_noisiness-frame_stationarity);
|
||||
#endif
|
||||
frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS));
|
||||
frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f);
|
||||
tonal->prev_tonality = frame_tonality;
|
||||
|
||||
slope /= 8*8;
|
||||
info->tonality_slope = slope;
|
||||
|
||||
tonal->E_count = (tonal->E_count+1)%NB_FRAMES;
|
||||
tonal->count++;
|
||||
info->tonality = frame_tonality;
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
features[i] = -0.12299f*(BFCC[i]+tonal->mem[i+24]) + 0.49195f*(tonal->mem[i]+tonal->mem[i+16]) + 0.69693f*tonal->mem[i+8] - 1.4349f*tonal->cmean[i];
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i];
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]);
|
||||
for (i=0;i<3;i++)
|
||||
features[8+i] = 0.53452f*(BFCC[i]+tonal->mem[i+24]) - 0.26726f*(tonal->mem[i]+tonal->mem[i+16]) -0.53452f*tonal->mem[i+8];
|
||||
|
||||
if (tonal->count > 5)
|
||||
{
|
||||
for (i=0;i<9;i++)
|
||||
tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];
|
||||
}
|
||||
|
||||
for (i=0;i<8;i++)
|
||||
{
|
||||
tonal->mem[i+24] = tonal->mem[i+16];
|
||||
tonal->mem[i+16] = tonal->mem[i+8];
|
||||
tonal->mem[i+8] = tonal->mem[i];
|
||||
tonal->mem[i] = BFCC[i];
|
||||
}
|
||||
for (i=0;i<9;i++)
|
||||
features[11+i] = (float)sqrt(tonal->std[i]);
|
||||
features[20] = info->tonality;
|
||||
features[21] = info->activity;
|
||||
features[22] = frame_stationarity;
|
||||
features[23] = info->tonality_slope;
|
||||
features[24] = tonal->lowECount;
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
mlp_process(&net, features, frame_probs);
|
||||
frame_probs[0] = .5f*(frame_probs[0]+1);
|
||||
/* Curve fitting between the MLP probability and the actual probability */
|
||||
frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);
|
||||
/* Probability of active audio (as opposed to silence) */
|
||||
frame_probs[1] = .5f*frame_probs[1]+.5f;
|
||||
/* Consider that silence has a 50-50 probability. */
|
||||
frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f;
|
||||
|
||||
/*printf("%f %f ", frame_probs[0], frame_probs[1]);*/
|
||||
{
|
||||
/* Probability of state transition */
|
||||
float tau;
|
||||
/* Represents independence of the MLP probabilities, where
|
||||
beta=1 means fully independent. */
|
||||
float beta;
|
||||
/* Denormalized probability of speech (p0) and music (p1) after update */
|
||||
float p0, p1;
|
||||
/* Probabilities for "all speech" and "all music" */
|
||||
float s0, m0;
|
||||
/* Probability sum for renormalisation */
|
||||
float psum;
|
||||
/* Instantaneous probability of speech and music, with beta pre-applied. */
|
||||
float speech0;
|
||||
float music0;
|
||||
|
||||
/* One transition every 3 minutes of active audio */
|
||||
tau = .00005f*frame_probs[1];
|
||||
beta = .05f;
|
||||
if (1) {
|
||||
/* Adapt beta based on how "unexpected" the new prob is */
|
||||
float p, q;
|
||||
p = MAX16(.05f,MIN16(.95f,frame_probs[0]));
|
||||
q = MAX16(.05f,MIN16(.95f,tonal->music_prob));
|
||||
beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
|
||||
}
|
||||
/* p0 and p1 are the probabilities of speech and music at this frame
|
||||
using only information from previous frame and applying the
|
||||
state transition model */
|
||||
p0 = (1-tonal->music_prob)*(1-tau) + tonal->music_prob *tau;
|
||||
p1 = tonal->music_prob *(1-tau) + (1-tonal->music_prob)*tau;
|
||||
/* We apply the current probability with exponent beta to work around
|
||||
the fact that the probability estimates aren't independent. */
|
||||
p0 *= (float)pow(1-frame_probs[0], beta);
|
||||
p1 *= (float)pow(frame_probs[0], beta);
|
||||
/* Normalise the probabilities to get the Marokv probability of music. */
|
||||
tonal->music_prob = p1/(p0+p1);
|
||||
info->music_prob = tonal->music_prob;
|
||||
|
||||
/* This chunk of code deals with delayed decision. */
|
||||
psum=1e-20f;
|
||||
/* Instantaneous probability of speech and music, with beta pre-applied. */
|
||||
speech0 = (float)pow(1-frame_probs[0], beta);
|
||||
music0 = (float)pow(frame_probs[0], beta);
|
||||
if (tonal->count==1)
|
||||
{
|
||||
tonal->pspeech[0]=.5;
|
||||
tonal->pmusic [0]=.5;
|
||||
}
|
||||
/* Updated probability of having only speech (s0) or only music (m0),
|
||||
before considering the new observation. */
|
||||
s0 = tonal->pspeech[0] + tonal->pspeech[1];
|
||||
m0 = tonal->pmusic [0] + tonal->pmusic [1];
|
||||
/* Updates s0 and m0 with instantaneous probability. */
|
||||
tonal->pspeech[0] = s0*(1-tau)*speech0;
|
||||
tonal->pmusic [0] = m0*(1-tau)*music0;
|
||||
/* Propagate the transition probabilities */
|
||||
for (i=1;i<DETECT_SIZE-1;i++)
|
||||
{
|
||||
tonal->pspeech[i] = tonal->pspeech[i+1]*speech0;
|
||||
tonal->pmusic [i] = tonal->pmusic [i+1]*music0;
|
||||
}
|
||||
/* Probability that the latest frame is speech, when all the previous ones were music. */
|
||||
tonal->pspeech[DETECT_SIZE-1] = m0*tau*speech0;
|
||||
/* Probability that the latest frame is music, when all the previous ones were speech. */
|
||||
tonal->pmusic [DETECT_SIZE-1] = s0*tau*music0;
|
||||
|
||||
/* Renormalise probabilities to 1 */
|
||||
for (i=0;i<DETECT_SIZE;i++)
|
||||
psum += tonal->pspeech[i] + tonal->pmusic[i];
|
||||
psum = 1.f/psum;
|
||||
for (i=0;i<DETECT_SIZE;i++)
|
||||
{
|
||||
tonal->pspeech[i] *= psum;
|
||||
tonal->pmusic [i] *= psum;
|
||||
}
|
||||
psum = tonal->pmusic[0];
|
||||
for (i=1;i<DETECT_SIZE;i++)
|
||||
psum += tonal->pspeech[i];
|
||||
|
||||
/* Estimate our confidence in the speech/music decisions */
|
||||
if (frame_probs[1]>.75)
|
||||
{
|
||||
if (tonal->music_prob>.9)
|
||||
{
|
||||
float adapt;
|
||||
adapt = 1.f/(++tonal->music_confidence_count);
|
||||
tonal->music_confidence_count = IMIN(tonal->music_confidence_count, 500);
|
||||
tonal->music_confidence += adapt*MAX16(-.2f,frame_probs[0]-tonal->music_confidence);
|
||||
}
|
||||
if (tonal->music_prob<.1)
|
||||
{
|
||||
float adapt;
|
||||
adapt = 1.f/(++tonal->speech_confidence_count);
|
||||
tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500);
|
||||
tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence);
|
||||
}
|
||||
} else {
|
||||
if (tonal->music_confidence_count==0)
|
||||
tonal->music_confidence = .9f;
|
||||
if (tonal->speech_confidence_count==0)
|
||||
tonal->speech_confidence = .1f;
|
||||
}
|
||||
}
|
||||
if (tonal->last_music != (tonal->music_prob>.5f))
|
||||
tonal->last_transition=0;
|
||||
tonal->last_music = tonal->music_prob>.5f;
|
||||
#else
|
||||
info->music_prob = 0;
|
||||
#endif
|
||||
/*for (i=0;i<25;i++)
|
||||
printf("%f ", features[i]);
|
||||
printf("\n");*/
|
||||
|
||||
info->bandwidth = bandwidth;
|
||||
/*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
|
||||
info->noisiness = frame_noisiness;
|
||||
info->valid = 1;
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
|
||||
int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
|
||||
int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info)
|
||||
{
|
||||
int offset;
|
||||
int pcm_len;
|
||||
|
||||
if (analysis_pcm != NULL)
|
||||
{
|
||||
/* Avoid overflow/wrap-around of the analysis buffer */
|
||||
analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/100, analysis_frame_size);
|
||||
|
||||
pcm_len = analysis_frame_size - analysis->analysis_offset;
|
||||
offset = analysis->analysis_offset;
|
||||
do {
|
||||
tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
|
||||
offset += 480;
|
||||
pcm_len -= 480;
|
||||
} while (pcm_len>0);
|
||||
analysis->analysis_offset = analysis_frame_size;
|
||||
|
||||
analysis->analysis_offset -= frame_size;
|
||||
}
|
||||
|
||||
analysis_info->valid = 0;
|
||||
tonality_get_info(analysis, analysis_info, frame_size);
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/* Copyright (c) 2011 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ANALYSIS_H
|
||||
#define ANALYSIS_H
|
||||
|
||||
#include "opus/celt/celt.h"
|
||||
#include "opus/opus_private.h"
|
||||
|
||||
#define NB_FRAMES 8
|
||||
#define NB_TBANDS 18
|
||||
#define NB_TOT_BANDS 21
|
||||
#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */
|
||||
|
||||
#define DETECT_SIZE 200
|
||||
|
||||
typedef struct {
|
||||
int arch;
|
||||
#define TONALITY_ANALYSIS_RESET_START angle
|
||||
float angle[240];
|
||||
float d_angle[240];
|
||||
float d2_angle[240];
|
||||
opus_val32 inmem[ANALYSIS_BUF_SIZE];
|
||||
int mem_fill; /* number of usable samples in the buffer */
|
||||
float prev_band_tonality[NB_TBANDS];
|
||||
float prev_tonality;
|
||||
float E[NB_FRAMES][NB_TBANDS];
|
||||
float lowE[NB_TBANDS];
|
||||
float highE[NB_TBANDS];
|
||||
float meanE[NB_TOT_BANDS];
|
||||
float mem[32];
|
||||
float cmean[8];
|
||||
float std[9];
|
||||
float music_prob;
|
||||
float Etracker;
|
||||
float lowECount;
|
||||
int E_count;
|
||||
int last_music;
|
||||
int last_transition;
|
||||
int count;
|
||||
float subframe_mem[3];
|
||||
int analysis_offset;
|
||||
/** Probability of having speech for time i to DETECT_SIZE-1 (and music before).
|
||||
pspeech[0] is the probability that all frames in the window are speech. */
|
||||
float pspeech[DETECT_SIZE];
|
||||
/** Probability of having music for time i to DETECT_SIZE-1 (and speech before).
|
||||
pmusic[0] is the probability that all frames in the window are music. */
|
||||
float pmusic[DETECT_SIZE];
|
||||
float speech_confidence;
|
||||
float music_confidence;
|
||||
int speech_confidence_count;
|
||||
int music_confidence_count;
|
||||
int write_pos;
|
||||
int read_pos;
|
||||
int read_subframe;
|
||||
AnalysisInfo info[DETECT_SIZE];
|
||||
} TonalityAnalysisState;
|
||||
|
||||
/** Initialize a TonalityAnalysisState struct.
|
||||
*
|
||||
* This performs some possibly slow initialization steps which should
|
||||
* not be repeated every analysis step. No allocated memory is retained
|
||||
* by the state struct, so no cleanup call is required.
|
||||
*/
|
||||
void tonality_analysis_init(TonalityAnalysisState *analysis);
|
||||
|
||||
/** Reset a TonalityAnalysisState stuct.
|
||||
*
|
||||
* Call this when there's a discontinuity in the data.
|
||||
*/
|
||||
void tonality_analysis_reset(TonalityAnalysisState *analysis);
|
||||
|
||||
void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len);
|
||||
|
||||
void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
|
||||
int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
|
||||
int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info);
|
||||
|
||||
#endif
|
@ -1,141 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* audio_stream_opus.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Author: George Marques <george@gmarqu.es> */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef AUDIO_STREAM_OPUS_H
|
||||
#define AUDIO_STREAM_OPUS_H
|
||||
|
||||
#include "scene/resources/audio_stream.h"
|
||||
#include "opus/opusfile.h"
|
||||
#include "opus/internal.h"
|
||||
#include "os/file_access.h"
|
||||
#include "io/resource_loader.h"
|
||||
|
||||
class AudioStreamPlaybackOpus : public AudioStreamPlayback {
|
||||
|
||||
OBJ_TYPE(AudioStreamPlaybackOpus,AudioStreamPlayback)
|
||||
|
||||
enum {
|
||||
MIN_MIX=1024
|
||||
};
|
||||
|
||||
FileAccess *f;
|
||||
|
||||
OpusFileCallbacks _op_callbacks;
|
||||
float length;
|
||||
static int _op_read_func(void *_stream, unsigned char *_ptr, int _nbytes);
|
||||
static int _op_seek_func(void *_stream, opus_int64 _offset, int _whence);
|
||||
static int _op_close_func(void *_stream);
|
||||
static opus_int64 _op_tell_func(void *_stream);
|
||||
static const float osrate;
|
||||
|
||||
String file;
|
||||
int64_t frames_mixed;
|
||||
|
||||
bool stream_loaded;
|
||||
volatile bool playing;
|
||||
OggOpusFile *opus_file;
|
||||
int stream_channels;
|
||||
int current_section;
|
||||
int pre_skip;
|
||||
|
||||
bool paused;
|
||||
bool loops;
|
||||
int repeats;
|
||||
|
||||
Error _load_stream();
|
||||
void _clear_stream();
|
||||
void _close_file();
|
||||
|
||||
bool stream_valid;
|
||||
float loop_restart_time;
|
||||
|
||||
public:
|
||||
Error set_file(const String& p_file);
|
||||
|
||||
virtual void play(float p_from=0);
|
||||
virtual void stop();
|
||||
virtual bool is_playing() const { return playing; }
|
||||
|
||||
virtual void set_loop_restart_time(float p_time) { loop_restart_time=p_time; }
|
||||
|
||||
virtual void set_paused(bool p_paused) { paused=p_paused; }
|
||||
virtual bool is_paused() const { return paused; }
|
||||
|
||||
virtual void set_loop(bool p_enable) { loops=p_enable; }
|
||||
virtual bool has_loop() const {return loops; }
|
||||
|
||||
virtual float get_length() const;
|
||||
|
||||
virtual String get_stream_name() const { return ""; }
|
||||
|
||||
virtual int get_loop_count() const { return repeats; }
|
||||
|
||||
virtual float get_pos() const;
|
||||
virtual void seek_pos(float p_time);
|
||||
|
||||
virtual int get_channels() const { return stream_channels; }
|
||||
virtual int get_mix_rate() const { return osrate; }
|
||||
|
||||
virtual int get_minimum_buffer_size() const;
|
||||
|
||||
virtual int mix(int16_t* p_bufer,int p_frames);
|
||||
|
||||
AudioStreamPlaybackOpus();
|
||||
~AudioStreamPlaybackOpus();
|
||||
};
|
||||
|
||||
|
||||
class AudioStreamOpus: public AudioStream {
|
||||
|
||||
OBJ_TYPE(AudioStreamOpus,AudioStream)
|
||||
|
||||
String file;
|
||||
public:
|
||||
|
||||
Ref<AudioStreamPlayback> instance_playback() {
|
||||
Ref<AudioStreamPlaybackOpus> pb = memnew( AudioStreamPlaybackOpus );
|
||||
pb->set_file(file);
|
||||
return pb;
|
||||
}
|
||||
|
||||
void set_file(const String& p_file) { file=p_file; }
|
||||
|
||||
};
|
||||
|
||||
class ResourceFormatLoaderAudioStreamOpus: public ResourceFormatLoader {
|
||||
public:
|
||||
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
||||
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
||||
virtual bool handles_type(const String& p_type) const;
|
||||
virtual String get_resource_type(const String &p_path) const;
|
||||
};
|
||||
|
||||
#endif // AUDIO_STREAM_OPUS_H
|
@ -1,182 +0,0 @@
|
||||
/*Copyright (c) 2003-2004, Mark Borgerding
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.*/
|
||||
|
||||
#ifndef KISS_FFT_GUTS_H
|
||||
#define KISS_FFT_GUTS_H
|
||||
|
||||
#define MIN(a,b) ((a)<(b) ? (a):(b))
|
||||
#define MAX(a,b) ((a)>(b) ? (a):(b))
|
||||
|
||||
/* kiss_fft.h
|
||||
defines kiss_fft_scalar as either short or a float type
|
||||
and defines
|
||||
typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
|
||||
/*
|
||||
Explanation of macros dealing with complex math:
|
||||
|
||||
C_MUL(m,a,b) : m = a*b
|
||||
C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
|
||||
C_SUB( res, a,b) : res = a - b
|
||||
C_SUBFROM( res , a) : res -= a
|
||||
C_ADDTO( res , a) : res += a
|
||||
* */
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
|
||||
#define SAMP_MAX 2147483647
|
||||
#define TWID_MAX 32767
|
||||
#define TRIG_UPSCALE 1
|
||||
|
||||
#define SAMP_MIN -SAMP_MAX
|
||||
|
||||
|
||||
# define S_MUL(a,b) MULT16_32_Q15(b, a)
|
||||
|
||||
# define C_MUL(m,a,b) \
|
||||
do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
|
||||
(m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
|
||||
|
||||
# define C_MULC(m,a,b) \
|
||||
do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
|
||||
(m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
|
||||
|
||||
# define C_MULBYSCALAR( c, s ) \
|
||||
do{ (c).r = S_MUL( (c).r , s ) ;\
|
||||
(c).i = S_MUL( (c).i , s ) ; }while(0)
|
||||
|
||||
# define DIVSCALAR(x,k) \
|
||||
(x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 )
|
||||
|
||||
# define C_FIXDIV(c,div) \
|
||||
do { DIVSCALAR( (c).r , div); \
|
||||
DIVSCALAR( (c).i , div); }while (0)
|
||||
|
||||
#define C_ADD( res, a,b)\
|
||||
do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \
|
||||
}while(0)
|
||||
#define C_SUB( res, a,b)\
|
||||
do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \
|
||||
}while(0)
|
||||
#define C_ADDTO( res , a)\
|
||||
do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\
|
||||
}while(0)
|
||||
|
||||
#define C_SUBFROM( res , a)\
|
||||
do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \
|
||||
}while(0)
|
||||
|
||||
#if defined(OPUS_ARM_INLINE_ASM)
|
||||
#include "opus/celt/arm/kiss_fft_armv4.h"
|
||||
#endif
|
||||
|
||||
#if defined(OPUS_ARM_INLINE_EDSP)
|
||||
#include "opus/celt/arm/kiss_fft_armv5e.h"
|
||||
#endif
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "opus/celt/mips/kiss_fft_mipsr1.h"
|
||||
#endif
|
||||
|
||||
#else /* not FIXED_POINT*/
|
||||
|
||||
# define S_MUL(a,b) ( (a)*(b) )
|
||||
#define C_MUL(m,a,b) \
|
||||
do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
|
||||
(m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
|
||||
#define C_MULC(m,a,b) \
|
||||
do{ (m).r = (a).r*(b).r + (a).i*(b).i;\
|
||||
(m).i = (a).i*(b).r - (a).r*(b).i; }while(0)
|
||||
|
||||
#define C_MUL4(m,a,b) C_MUL(m,a,b)
|
||||
|
||||
# define C_FIXDIV(c,div) /* NOOP */
|
||||
# define C_MULBYSCALAR( c, s ) \
|
||||
do{ (c).r *= (s);\
|
||||
(c).i *= (s); }while(0)
|
||||
#endif
|
||||
|
||||
#ifndef CHECK_OVERFLOW_OP
|
||||
# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
|
||||
#endif
|
||||
|
||||
#ifndef C_ADD
|
||||
#define C_ADD( res, a,b)\
|
||||
do { \
|
||||
CHECK_OVERFLOW_OP((a).r,+,(b).r)\
|
||||
CHECK_OVERFLOW_OP((a).i,+,(b).i)\
|
||||
(res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
|
||||
}while(0)
|
||||
#define C_SUB( res, a,b)\
|
||||
do { \
|
||||
CHECK_OVERFLOW_OP((a).r,-,(b).r)\
|
||||
CHECK_OVERFLOW_OP((a).i,-,(b).i)\
|
||||
(res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
|
||||
}while(0)
|
||||
#define C_ADDTO( res , a)\
|
||||
do { \
|
||||
CHECK_OVERFLOW_OP((res).r,+,(a).r)\
|
||||
CHECK_OVERFLOW_OP((res).i,+,(a).i)\
|
||||
(res).r += (a).r; (res).i += (a).i;\
|
||||
}while(0)
|
||||
|
||||
#define C_SUBFROM( res , a)\
|
||||
do {\
|
||||
CHECK_OVERFLOW_OP((res).r,-,(a).r)\
|
||||
CHECK_OVERFLOW_OP((res).i,-,(a).i)\
|
||||
(res).r -= (a).r; (res).i -= (a).i; \
|
||||
}while(0)
|
||||
#endif /* C_ADD defined */
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
/*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase))))
|
||||
# define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/
|
||||
# define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase))
|
||||
# define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase))
|
||||
# define HALF_OF(x) ((x)>>1)
|
||||
#elif defined(USE_SIMD)
|
||||
# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) )
|
||||
# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) )
|
||||
# define HALF_OF(x) ((x)*_mm_set1_ps(.5f))
|
||||
#else
|
||||
# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase)
|
||||
# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase)
|
||||
# define HALF_OF(x) ((x)*.5f)
|
||||
#endif
|
||||
|
||||
#define kf_cexp(x,phase) \
|
||||
do{ \
|
||||
(x)->r = KISS_FFT_COS(phase);\
|
||||
(x)->i = KISS_FFT_SIN(phase);\
|
||||
}while(0)
|
||||
|
||||
#define kf_cexp2(x,phase) \
|
||||
do{ \
|
||||
(x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\
|
||||
(x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\
|
||||
}while(0)
|
||||
|
||||
#endif /* KISS_FFT_GUTS_H */
|
@ -1,241 +0,0 @@
|
||||
/* Copyright (c) 2003-2008 Jean-Marc Valin
|
||||
Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/**
|
||||
@file arch.h
|
||||
@brief Various architecture definitions for CELT
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ARCH_H
|
||||
#define ARCH_H
|
||||
|
||||
#include "opus/opus_types.h"
|
||||
#include "opus/opus_defines.h"
|
||||
|
||||
# if !defined(__GNUC_PREREQ)
|
||||
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
|
||||
# define __GNUC_PREREQ(_maj,_min) \
|
||||
((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min))
|
||||
# else
|
||||
# define __GNUC_PREREQ(_maj,_min) 0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#define CELT_SIG_SCALE 32768.f
|
||||
|
||||
#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
|
||||
#ifdef ENABLE_ASSERTIONS
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __GNUC__
|
||||
__attribute__((noreturn))
|
||||
#endif
|
||||
static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)
|
||||
{
|
||||
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
|
||||
abort();
|
||||
}
|
||||
#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}}
|
||||
#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}}
|
||||
#else
|
||||
#define celt_assert(cond)
|
||||
#define celt_assert2(cond, message)
|
||||
#endif
|
||||
|
||||
#define IMUL32(a,b) ((a)*(b))
|
||||
|
||||
#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */
|
||||
#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
|
||||
#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */
|
||||
#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */
|
||||
#define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */
|
||||
#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */
|
||||
#define UADD32(a,b) ((a)+(b))
|
||||
#define USUB32(a,b) ((a)-(b))
|
||||
|
||||
#define PRINT_MIPS(file)
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
|
||||
typedef opus_int16 opus_val16;
|
||||
typedef opus_int32 opus_val32;
|
||||
|
||||
typedef opus_val32 celt_sig;
|
||||
typedef opus_val16 celt_norm;
|
||||
typedef opus_val32 celt_ener;
|
||||
|
||||
#define Q15ONE 32767
|
||||
|
||||
#define SIG_SHIFT 12
|
||||
|
||||
#define NORM_SCALING 16384
|
||||
|
||||
#define DB_SHIFT 10
|
||||
|
||||
#define EPSILON 1
|
||||
#define VERY_SMALL 0
|
||||
#define VERY_LARGE16 ((opus_val16)32767)
|
||||
#define Q15_ONE ((opus_val16)32767)
|
||||
|
||||
#define SCALEIN(a) (a)
|
||||
#define SCALEOUT(a) (a)
|
||||
|
||||
#define ABS16(x) ((x) < 0 ? (-(x)) : (x))
|
||||
#define ABS32(x) ((x) < 0 ? (-(x)) : (x))
|
||||
|
||||
static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
|
||||
return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;
|
||||
}
|
||||
|
||||
#ifdef FIXED_DEBUG
|
||||
#include "opus/celt/fixed_debug.h"
|
||||
#else
|
||||
|
||||
#include "opus/celt/fixed_generic.h"
|
||||
|
||||
#ifdef OPUS_ARM_INLINE_EDSP
|
||||
#include "opus/celt/arm/fixed_armv5e.h"
|
||||
#elif defined (OPUS_ARM_INLINE_ASM)
|
||||
#include "opus/celt/arm/fixed_armv4.h"
|
||||
#elif defined (BFIN_ASM)
|
||||
#include "fixed_bfin.h"
|
||||
#elif defined (TI_C5X_ASM)
|
||||
#include "fixed_c5x.h"
|
||||
#elif defined (TI_C6X_ASM)
|
||||
#include "fixed_c6x.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#else /* FIXED_POINT */
|
||||
|
||||
typedef float opus_val16;
|
||||
typedef float opus_val32;
|
||||
|
||||
typedef float celt_sig;
|
||||
typedef float celt_norm;
|
||||
typedef float celt_ener;
|
||||
|
||||
#ifdef FLOAT_APPROX
|
||||
/* This code should reliably detect NaN/inf even when -ffast-math is used.
|
||||
Assumes IEEE 754 format. */
|
||||
static OPUS_INLINE int celt_isnan(float x)
|
||||
{
|
||||
union {float f; opus_uint32 i;} in;
|
||||
in.f = x;
|
||||
return ((in.i>>23)&0xFF)==0xFF && (in.i&0x007FFFFF)!=0;
|
||||
}
|
||||
#else
|
||||
#ifdef __FAST_MATH__
|
||||
#error Cannot build libopus with -ffast-math unless FLOAT_APPROX is defined. This could result in crashes on extreme (e.g. NaN) input
|
||||
#endif
|
||||
#define celt_isnan(x) ((x)!=(x))
|
||||
#endif
|
||||
|
||||
#define Q15ONE 1.0f
|
||||
|
||||
#define NORM_SCALING 1.f
|
||||
|
||||
#define EPSILON 1e-15f
|
||||
#define VERY_SMALL 1e-30f
|
||||
#define VERY_LARGE16 1e15f
|
||||
#define Q15_ONE ((opus_val16)1.f)
|
||||
|
||||
/* This appears to be the same speed as C99's fabsf() but it's more portable. */
|
||||
#define ABS16(x) ((float)fabs(x))
|
||||
#define ABS32(x) ((float)fabs(x))
|
||||
|
||||
#define QCONST16(x,bits) (x)
|
||||
#define QCONST32(x,bits) (x)
|
||||
|
||||
#define NEG16(x) (-(x))
|
||||
#define NEG32(x) (-(x))
|
||||
#define EXTRACT16(x) (x)
|
||||
#define EXTEND32(x) (x)
|
||||
#define SHR16(a,shift) (a)
|
||||
#define SHL16(a,shift) (a)
|
||||
#define SHR32(a,shift) (a)
|
||||
#define SHL32(a,shift) (a)
|
||||
#define PSHR32(a,shift) (a)
|
||||
#define VSHR32(a,shift) (a)
|
||||
|
||||
#define PSHR(a,shift) (a)
|
||||
#define SHR(a,shift) (a)
|
||||
#define SHL(a,shift) (a)
|
||||
#define SATURATE(x,a) (x)
|
||||
#define SATURATE16(x) (x)
|
||||
|
||||
#define ROUND16(a,shift) (a)
|
||||
#define HALF16(x) (.5f*(x))
|
||||
#define HALF32(x) (.5f*(x))
|
||||
|
||||
#define ADD16(a,b) ((a)+(b))
|
||||
#define SUB16(a,b) ((a)-(b))
|
||||
#define ADD32(a,b) ((a)+(b))
|
||||
#define SUB32(a,b) ((a)-(b))
|
||||
#define MULT16_16_16(a,b) ((a)*(b))
|
||||
#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b))
|
||||
#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b))
|
||||
|
||||
#define MULT16_32_Q15(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q16(a,b) ((a)*(b))
|
||||
|
||||
#define MULT32_32_Q31(a,b) ((a)*(b))
|
||||
|
||||
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_32_Q16(c,a,b) ((c)+(a)*(b))
|
||||
|
||||
#define MULT16_16_Q11_32(a,b) ((a)*(b))
|
||||
#define MULT16_16_Q11(a,b) ((a)*(b))
|
||||
#define MULT16_16_Q13(a,b) ((a)*(b))
|
||||
#define MULT16_16_Q14(a,b) ((a)*(b))
|
||||
#define MULT16_16_Q15(a,b) ((a)*(b))
|
||||
#define MULT16_16_P15(a,b) ((a)*(b))
|
||||
#define MULT16_16_P13(a,b) ((a)*(b))
|
||||
#define MULT16_16_P14(a,b) ((a)*(b))
|
||||
#define MULT16_32_P16(a,b) ((a)*(b))
|
||||
|
||||
#define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b))
|
||||
#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b))
|
||||
|
||||
#define SCALEIN(a) ((a)*CELT_SIG_SCALE)
|
||||
#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE))
|
||||
|
||||
#define SIG2WORD16(x) (x)
|
||||
|
||||
#endif /* !FIXED_POINT */
|
||||
|
||||
#ifndef GLOBAL_STACK_SIZE
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
#define GLOBAL_STACK_SIZE 100000
|
||||
#else
|
||||
#define GLOBAL_STACK_SIZE 100000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* ARCH_H */
|
@ -1,118 +0,0 @@
|
||||
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||
* Copyright (c) 2013 Parrot */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/pitch.h"
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/mdct.h"
|
||||
|
||||
#if defined(OPUS_HAVE_RTCD)
|
||||
|
||||
# if defined(FIXED_POINT)
|
||||
opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
|
||||
const opus_val16 *, opus_val32 *, int , int) = {
|
||||
celt_pitch_xcorr_c, /* ARMv4 */
|
||||
MAY_HAVE_EDSP(celt_pitch_xcorr), /* EDSP */
|
||||
MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */
|
||||
MAY_HAVE_NEON(celt_pitch_xcorr) /* NEON */
|
||||
};
|
||||
# else /* !FIXED_POINT */
|
||||
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
|
||||
void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
|
||||
const opus_val16 *, opus_val32 *, int, int) = {
|
||||
celt_pitch_xcorr_c, /* ARMv4 */
|
||||
celt_pitch_xcorr_c, /* EDSP */
|
||||
celt_pitch_xcorr_c, /* Media */
|
||||
celt_pitch_xcorr_float_neon /* Neon */
|
||||
};
|
||||
# endif
|
||||
# endif /* FIXED_POINT */
|
||||
|
||||
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
|
||||
# if defined(HAVE_ARM_NE10)
|
||||
# if defined(CUSTOM_MODES)
|
||||
int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {
|
||||
opus_fft_alloc_arch_c, /* ARMv4 */
|
||||
opus_fft_alloc_arch_c, /* EDSP */
|
||||
opus_fft_alloc_arch_c, /* Media */
|
||||
opus_fft_alloc_arm_neon /* Neon with NE10 library support */
|
||||
};
|
||||
|
||||
void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {
|
||||
opus_fft_free_arch_c, /* ARMv4 */
|
||||
opus_fft_free_arch_c, /* EDSP */
|
||||
opus_fft_free_arch_c, /* Media */
|
||||
opus_fft_free_arm_neon /* Neon with NE10 */
|
||||
};
|
||||
# endif /* CUSTOM_MODES */
|
||||
|
||||
void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
|
||||
const kiss_fft_cpx *fin,
|
||||
kiss_fft_cpx *fout) = {
|
||||
opus_fft_c, /* ARMv4 */
|
||||
opus_fft_c, /* EDSP */
|
||||
opus_fft_c, /* Media */
|
||||
opus_fft_neon /* Neon with NE10 */
|
||||
};
|
||||
|
||||
void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
|
||||
const kiss_fft_cpx *fin,
|
||||
kiss_fft_cpx *fout) = {
|
||||
opus_ifft_c, /* ARMv4 */
|
||||
opus_ifft_c, /* EDSP */
|
||||
opus_ifft_c, /* Media */
|
||||
opus_ifft_neon /* Neon with NE10 */
|
||||
};
|
||||
|
||||
void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,
|
||||
kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window,
|
||||
int overlap, int shift,
|
||||
int stride, int arch) = {
|
||||
clt_mdct_forward_c, /* ARMv4 */
|
||||
clt_mdct_forward_c, /* EDSP */
|
||||
clt_mdct_forward_c, /* Media */
|
||||
clt_mdct_forward_neon /* Neon with NE10 */
|
||||
};
|
||||
|
||||
void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,
|
||||
kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window,
|
||||
int overlap, int shift,
|
||||
int stride, int arch) = {
|
||||
clt_mdct_backward_c, /* ARMv4 */
|
||||
clt_mdct_backward_c, /* EDSP */
|
||||
clt_mdct_backward_c, /* Media */
|
||||
clt_mdct_backward_neon /* Neon with NE10 */
|
||||
};
|
||||
|
||||
# endif /* HAVE_ARM_NE10 */
|
||||
# endif /* OPUS_ARM_MAY_HAVE_NEON_INTR */
|
||||
|
||||
#endif /* OPUS_HAVE_RTCD */
|
@ -1,171 +0,0 @@
|
||||
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||
* Copyright (c) 2013 Parrot */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Original code from libtheora modified to suit to Opus */
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#ifdef OPUS_HAVE_RTCD
|
||||
|
||||
#include "opus/celt/arm/armcpu.h"
|
||||
#include "opus/celt/cpu_support.h"
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/opus_types.h"
|
||||
|
||||
#define OPUS_CPU_ARM_V4 (1)
|
||||
#define OPUS_CPU_ARM_EDSP (1<<1)
|
||||
#define OPUS_CPU_ARM_MEDIA (1<<2)
|
||||
#define OPUS_CPU_ARM_NEON (1<<3)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_EXTRA_LEAN
|
||||
# include <windows.h>
|
||||
|
||||
static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){
|
||||
opus_uint32 flags;
|
||||
flags=0;
|
||||
/* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit
|
||||
* instructions via their assembled hex code.
|
||||
* All of these instructions should be essentially nops. */
|
||||
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
|
||||
__try{
|
||||
/*PLD [r13]*/
|
||||
__emit(0xF5DDF000);
|
||||
flags|=OPUS_CPU_ARM_EDSP;
|
||||
}
|
||||
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||
/*Ignore exception.*/
|
||||
}
|
||||
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
|
||||
__try{
|
||||
/*SHADD8 r3,r3,r3*/
|
||||
__emit(0xE6333F93);
|
||||
flags|=OPUS_CPU_ARM_MEDIA;
|
||||
}
|
||||
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||
/*Ignore exception.*/
|
||||
}
|
||||
# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
|
||||
__try{
|
||||
/*VORR q0,q0,q0*/
|
||||
__emit(0xF2200150);
|
||||
flags|=OPUS_CPU_ARM_NEON;
|
||||
}
|
||||
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||
/*Ignore exception.*/
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
/* Linux based */
|
||||
opus_uint32 opus_cpu_capabilities(void)
|
||||
{
|
||||
opus_uint32 flags = 0;
|
||||
FILE *cpuinfo;
|
||||
|
||||
/* Reading /proc/self/auxv would be easier, but that doesn't work reliably on
|
||||
* Android */
|
||||
cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
|
||||
if(cpuinfo != NULL)
|
||||
{
|
||||
/* 512 should be enough for anybody (it's even enough for all the flags that
|
||||
* x86 has accumulated... so far). */
|
||||
char buf[512];
|
||||
|
||||
while(fgets(buf, 512, cpuinfo) != NULL)
|
||||
{
|
||||
# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
|
||||
/* Search for edsp and neon flag */
|
||||
if(memcmp(buf, "Features", 8) == 0)
|
||||
{
|
||||
char *p;
|
||||
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
|
||||
p = strstr(buf, " edsp");
|
||||
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
|
||||
flags |= OPUS_CPU_ARM_EDSP;
|
||||
# endif
|
||||
|
||||
# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
|
||||
p = strstr(buf, " neon");
|
||||
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
|
||||
flags |= OPUS_CPU_ARM_NEON;
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
|
||||
/* Search for media capabilities (>= ARMv6) */
|
||||
if(memcmp(buf, "CPU architecture:", 17) == 0)
|
||||
{
|
||||
int version;
|
||||
version = atoi(buf+17);
|
||||
|
||||
if(version >= 6)
|
||||
flags |= OPUS_CPU_ARM_MEDIA;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
fclose(cpuinfo);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
#else
|
||||
/* The feature registers which can tell us what the processor supports are
|
||||
* accessible in priveleged modes only, so we can't have a general user-space
|
||||
* detection method like on x86.*/
|
||||
# error "Configured to use ARM asm but no CPU detection method available for " \
|
||||
"your platform. Reconfigure with --disable-rtcd (or send patches)."
|
||||
#endif
|
||||
|
||||
int opus_select_arch(void)
|
||||
{
|
||||
opus_uint32 flags = opus_cpu_capabilities();
|
||||
int arch = 0;
|
||||
|
||||
if(!(flags & OPUS_CPU_ARM_EDSP))
|
||||
return arch;
|
||||
arch++;
|
||||
|
||||
if(!(flags & OPUS_CPU_ARM_MEDIA))
|
||||
return arch;
|
||||
arch++;
|
||||
|
||||
if(!(flags & OPUS_CPU_ARM_NEON))
|
||||
return arch;
|
||||
arch++;
|
||||
|
||||
return arch;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,172 +0,0 @@
|
||||
/* Copyright (c) 2015 Xiph.Org Foundation
|
||||
Written by Viswanath Puttagunta */
|
||||
/**
|
||||
@file celt_ne10_fft.c
|
||||
@brief ARM Neon optimizations for fft using NE10 library
|
||||
*/
|
||||
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SKIP_CONFIG_H
|
||||
#include "opus/opus_config.h"
|
||||
#endif
|
||||
|
||||
#include <NE10_init.h>
|
||||
#include <NE10_dsp.h>
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
|
||||
#if !defined(FIXED_POINT)
|
||||
# define NE10_FFT_ALLOC_C2C_TYPE_NEON ne10_fft_alloc_c2c_float32_neon
|
||||
# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t
|
||||
# define NE10_FFT_STATE_TYPE_T ne10_fft_state_float32_t
|
||||
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_float32
|
||||
# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_float32_t
|
||||
# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_float32_neon
|
||||
#else
|
||||
# define NE10_FFT_ALLOC_C2C_TYPE_NEON(nfft) ne10_fft_alloc_c2c_int32_neon(nfft)
|
||||
# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t
|
||||
# define NE10_FFT_STATE_TYPE_T ne10_fft_state_int32_t
|
||||
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
|
||||
# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
|
||||
# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_int32_t
|
||||
# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_int32_neon
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM_MODES)
|
||||
|
||||
/* nfft lengths in NE10 that support scaled fft */
|
||||
# define NE10_FFTSCALED_SUPPORT_MAX 4
|
||||
static const int ne10_fft_scaled_support[NE10_FFTSCALED_SUPPORT_MAX] = {
|
||||
480, 240, 120, 60
|
||||
};
|
||||
|
||||
int opus_fft_alloc_arm_neon(kiss_fft_state *st)
|
||||
{
|
||||
int i;
|
||||
size_t memneeded = sizeof(struct arch_fft_state);
|
||||
|
||||
st->arch_fft = (arch_fft_state *)opus_alloc(memneeded);
|
||||
if (!st->arch_fft)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < NE10_FFTSCALED_SUPPORT_MAX; i++) {
|
||||
if(st->nfft == ne10_fft_scaled_support[i])
|
||||
break;
|
||||
}
|
||||
if (i == NE10_FFTSCALED_SUPPORT_MAX) {
|
||||
/* This nfft length (scaled fft) is not supported in NE10 */
|
||||
st->arch_fft->is_supported = 0;
|
||||
st->arch_fft->priv = NULL;
|
||||
}
|
||||
else {
|
||||
st->arch_fft->is_supported = 1;
|
||||
st->arch_fft->priv = (void *)NE10_FFT_ALLOC_C2C_TYPE_NEON(st->nfft);
|
||||
if (st->arch_fft->priv == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void opus_fft_free_arm_neon(kiss_fft_state *st)
|
||||
{
|
||||
NE10_FFT_CFG_TYPE_T cfg;
|
||||
|
||||
if (!st->arch_fft)
|
||||
return;
|
||||
|
||||
cfg = (NE10_FFT_CFG_TYPE_T)st->arch_fft->priv;
|
||||
if (cfg)
|
||||
NE10_FFT_DESTROY_C2C_TYPE(cfg);
|
||||
opus_free(st->arch_fft);
|
||||
}
|
||||
#endif
|
||||
|
||||
void opus_fft_neon(const kiss_fft_state *st,
|
||||
const kiss_fft_cpx *fin,
|
||||
kiss_fft_cpx *fout)
|
||||
{
|
||||
NE10_FFT_STATE_TYPE_T state;
|
||||
NE10_FFT_CFG_TYPE_T cfg = &state;
|
||||
VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
|
||||
SAVE_STACK;
|
||||
ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
|
||||
|
||||
if (!st->arch_fft->is_supported) {
|
||||
/* This nfft length (scaled fft) not supported in NE10 */
|
||||
opus_fft_c(st, fin, fout);
|
||||
}
|
||||
else {
|
||||
memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
|
||||
state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
|
||||
#if !defined(FIXED_POINT)
|
||||
state.is_forward_scaled = 1;
|
||||
|
||||
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
||||
(NE10_FFT_CPX_TYPE_T *)fin,
|
||||
cfg, 0);
|
||||
#else
|
||||
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
||||
(NE10_FFT_CPX_TYPE_T *)fin,
|
||||
cfg, 0, 1);
|
||||
#endif
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
void opus_ifft_neon(const kiss_fft_state *st,
|
||||
const kiss_fft_cpx *fin,
|
||||
kiss_fft_cpx *fout)
|
||||
{
|
||||
NE10_FFT_STATE_TYPE_T state;
|
||||
NE10_FFT_CFG_TYPE_T cfg = &state;
|
||||
VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
|
||||
SAVE_STACK;
|
||||
ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
|
||||
|
||||
if (!st->arch_fft->is_supported) {
|
||||
/* This nfft length (scaled fft) not supported in NE10 */
|
||||
opus_ifft_c(st, fin, fout);
|
||||
}
|
||||
else {
|
||||
memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
|
||||
state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
|
||||
#if !defined(FIXED_POINT)
|
||||
state.is_backward_scaled = 0;
|
||||
|
||||
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
||||
(NE10_FFT_CPX_TYPE_T *)fin,
|
||||
cfg, 1);
|
||||
#else
|
||||
NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
|
||||
(NE10_FFT_CPX_TYPE_T *)fin,
|
||||
cfg, 1, 0);
|
||||
#endif
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
@ -1,256 +0,0 @@
|
||||
/* Copyright (c) 2015 Xiph.Org Foundation
|
||||
Written by Viswanath Puttagunta */
|
||||
/**
|
||||
@file celt_ne10_mdct.c
|
||||
@brief ARM Neon optimizations for mdct using NE10 library
|
||||
*/
|
||||
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SKIP_CONFIG_H
|
||||
#include "opus/opus_config.h"
|
||||
#endif
|
||||
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/_kiss_fft_guts.h"
|
||||
#include "opus/celt/mdct.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
|
||||
void clt_mdct_forward_neon(const mdct_lookup *l,
|
||||
kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window,
|
||||
int overlap, int shift, int stride, int arch)
|
||||
{
|
||||
int i;
|
||||
int N, N2, N4;
|
||||
VARDECL(kiss_fft_scalar, f);
|
||||
VARDECL(kiss_fft_cpx, f2);
|
||||
const kiss_fft_state *st = l->kfft[shift];
|
||||
const kiss_twiddle_scalar *trig;
|
||||
|
||||
SAVE_STACK;
|
||||
|
||||
N = l->n;
|
||||
trig = l->trig;
|
||||
for (i=0;i<shift;i++)
|
||||
{
|
||||
N >>= 1;
|
||||
trig += N;
|
||||
}
|
||||
N2 = N>>1;
|
||||
N4 = N>>2;
|
||||
|
||||
ALLOC(f, N2, kiss_fft_scalar);
|
||||
ALLOC(f2, N4, kiss_fft_cpx);
|
||||
|
||||
/* Consider the input to be composed of four blocks: [a, b, c, d] */
|
||||
/* Window, shuffle, fold */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
|
||||
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
|
||||
for(i=0;i<((overlap+3)>>2);i++)
|
||||
{
|
||||
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
|
||||
*yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
|
||||
*yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]);
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
wp1+=2;
|
||||
wp2-=2;
|
||||
}
|
||||
wp1 = window;
|
||||
wp2 = window+overlap-1;
|
||||
for(;i<N4-((overlap+3)>>2);i++)
|
||||
{
|
||||
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
||||
*yp++ = *xp2;
|
||||
*yp++ = *xp1;
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
}
|
||||
for(;i<N4;i++)
|
||||
{
|
||||
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
||||
*yp++ = -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);
|
||||
*yp++ = MULT16_32_Q15(*wp2, *xp1) + MULT16_32_Q15(*wp1, xp2[N2]);
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
wp1+=2;
|
||||
wp2-=2;
|
||||
}
|
||||
}
|
||||
/* Pre-rotation */
|
||||
{
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
kiss_fft_cpx yc;
|
||||
kiss_twiddle_scalar t0, t1;
|
||||
kiss_fft_scalar re, im, yr, yi;
|
||||
t0 = t[i];
|
||||
t1 = t[N4+i];
|
||||
re = *yp++;
|
||||
im = *yp++;
|
||||
yr = S_MUL(re,t0) - S_MUL(im,t1);
|
||||
yi = S_MUL(im,t0) + S_MUL(re,t1);
|
||||
yc.r = yr;
|
||||
yc.i = yi;
|
||||
f2[i] = yc;
|
||||
}
|
||||
}
|
||||
|
||||
opus_fft(st, f2, (kiss_fft_cpx *)f, arch);
|
||||
|
||||
/* Post-rotate */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_cpx * OPUS_RESTRICT fp = (kiss_fft_cpx *)f;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
kiss_fft_scalar yr, yi;
|
||||
yr = S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]);
|
||||
yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]);
|
||||
*yp1 = yr;
|
||||
*yp2 = yi;
|
||||
fp++;
|
||||
yp1 += 2*stride;
|
||||
yp2 -= 2*stride;
|
||||
}
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
void clt_mdct_backward_neon(const mdct_lookup *l,
|
||||
kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 * OPUS_RESTRICT window,
|
||||
int overlap, int shift, int stride, int arch)
|
||||
{
|
||||
int i;
|
||||
int N, N2, N4;
|
||||
VARDECL(kiss_fft_scalar, f);
|
||||
const kiss_twiddle_scalar *trig;
|
||||
const kiss_fft_state *st = l->kfft[shift];
|
||||
|
||||
N = l->n;
|
||||
trig = l->trig;
|
||||
for (i=0;i<shift;i++)
|
||||
{
|
||||
N >>= 1;
|
||||
trig += N;
|
||||
}
|
||||
N2 = N>>1;
|
||||
N4 = N>>2;
|
||||
|
||||
ALLOC(f, N2, kiss_fft_scalar);
|
||||
|
||||
/* Pre-rotate */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||
const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
kiss_fft_scalar yr, yi;
|
||||
yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);
|
||||
yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);
|
||||
yp[2*i] = yr;
|
||||
yp[2*i+1] = yi;
|
||||
xp1+=2*stride;
|
||||
xp2-=2*stride;
|
||||
}
|
||||
}
|
||||
|
||||
opus_ifft(st, (kiss_fft_cpx *)f, (kiss_fft_cpx*)(out+(overlap>>1)), arch);
|
||||
|
||||
/* Post-rotate and de-shuffle from both ends of the buffer at once to make
|
||||
it in-place. */
|
||||
{
|
||||
kiss_fft_scalar * yp0 = out+(overlap>>1);
|
||||
kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
/* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
|
||||
middle pair will be computed twice. */
|
||||
for(i=0;i<(N4+1)>>1;i++)
|
||||
{
|
||||
kiss_fft_scalar re, im, yr, yi;
|
||||
kiss_twiddle_scalar t0, t1;
|
||||
re = yp0[0];
|
||||
im = yp0[1];
|
||||
t0 = t[i];
|
||||
t1 = t[N4+i];
|
||||
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||
yr = S_MUL(re,t0) + S_MUL(im,t1);
|
||||
yi = S_MUL(re,t1) - S_MUL(im,t0);
|
||||
re = yp1[0];
|
||||
im = yp1[1];
|
||||
yp0[0] = yr;
|
||||
yp1[1] = yi;
|
||||
|
||||
t0 = t[(N4-i-1)];
|
||||
t1 = t[(N2-i-1)];
|
||||
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||
yr = S_MUL(re,t0) + S_MUL(im,t1);
|
||||
yi = S_MUL(re,t1) - S_MUL(im,t0);
|
||||
yp1[0] = yr;
|
||||
yp0[1] = yi;
|
||||
yp0 += 2;
|
||||
yp1 -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mirror on both sides for TDAC */
|
||||
{
|
||||
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||
const opus_val16 * OPUS_RESTRICT wp1 = window;
|
||||
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
|
||||
|
||||
for(i = 0; i < overlap/2; i++)
|
||||
{
|
||||
kiss_fft_scalar x1, x2;
|
||||
x1 = *xp1;
|
||||
x2 = *yp1;
|
||||
*yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
|
||||
*xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
|
||||
wp1++;
|
||||
wp2--;
|
||||
}
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/* Copyright (c) 2014-2015 Xiph.Org Foundation
|
||||
Written by Viswanath Puttagunta */
|
||||
/**
|
||||
@file celt_neon_intr.c
|
||||
@brief ARM Neon Intrinsic optimizations for celt
|
||||
*/
|
||||
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include "opus/celt/pitch.h"
|
||||
|
||||
#if !defined(FIXED_POINT)
|
||||
/*
|
||||
* Function: xcorr_kernel_neon_float
|
||||
* ---------------------------------
|
||||
* Computes 4 correlation values and stores them in sum[4]
|
||||
*/
|
||||
static void xcorr_kernel_neon_float(const float32_t *x, const float32_t *y,
|
||||
float32_t sum[4], int len) {
|
||||
float32x4_t YY[3];
|
||||
float32x4_t YEXT[3];
|
||||
float32x4_t XX[2];
|
||||
float32x2_t XX_2;
|
||||
float32x4_t SUMM;
|
||||
const float32_t *xi = x;
|
||||
const float32_t *yi = y;
|
||||
|
||||
celt_assert(len>0);
|
||||
|
||||
YY[0] = vld1q_f32(yi);
|
||||
SUMM = vdupq_n_f32(0);
|
||||
|
||||
/* Consume 8 elements in x vector and 12 elements in y
|
||||
* vector. However, the 12'th element never really gets
|
||||
* touched in this loop. So, if len == 8, then we only
|
||||
* must access y[0] to y[10]. y[11] must not be accessed
|
||||
* hence make sure len > 8 and not len >= 8
|
||||
*/
|
||||
while (len > 8) {
|
||||
yi += 4;
|
||||
YY[1] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
YY[2] = vld1q_f32(yi);
|
||||
|
||||
XX[0] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
XX[1] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
|
||||
SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);
|
||||
YEXT[0] = vextq_f32(YY[0], YY[1], 1);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);
|
||||
YEXT[1] = vextq_f32(YY[0], YY[1], 2);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);
|
||||
YEXT[2] = vextq_f32(YY[0], YY[1], 3);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);
|
||||
|
||||
SUMM = vmlaq_lane_f32(SUMM, YY[1], vget_low_f32(XX[1]), 0);
|
||||
YEXT[0] = vextq_f32(YY[1], YY[2], 1);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[1]), 1);
|
||||
YEXT[1] = vextq_f32(YY[1], YY[2], 2);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[1]), 0);
|
||||
YEXT[2] = vextq_f32(YY[1], YY[2], 3);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[1]), 1);
|
||||
|
||||
YY[0] = YY[2];
|
||||
len -= 8;
|
||||
}
|
||||
|
||||
/* Consume 4 elements in x vector and 8 elements in y
|
||||
* vector. However, the 8'th element in y never really gets
|
||||
* touched in this loop. So, if len == 4, then we only
|
||||
* must access y[0] to y[6]. y[7] must not be accessed
|
||||
* hence make sure len>4 and not len>=4
|
||||
*/
|
||||
if (len > 4) {
|
||||
yi += 4;
|
||||
YY[1] = vld1q_f32(yi);
|
||||
|
||||
XX[0] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
|
||||
SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);
|
||||
YEXT[0] = vextq_f32(YY[0], YY[1], 1);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);
|
||||
YEXT[1] = vextq_f32(YY[0], YY[1], 2);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);
|
||||
YEXT[2] = vextq_f32(YY[0], YY[1], 3);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);
|
||||
|
||||
YY[0] = YY[1];
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
while (--len > 0) {
|
||||
XX_2 = vld1_dup_f32(xi++);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);
|
||||
YY[0]= vld1q_f32(++yi);
|
||||
}
|
||||
|
||||
XX_2 = vld1_dup_f32(xi);
|
||||
SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);
|
||||
|
||||
vst1q_f32(sum, SUMM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: xcorr_kernel_neon_float_process1
|
||||
* ---------------------------------
|
||||
* Computes single correlation values and stores in *sum
|
||||
*/
|
||||
static void xcorr_kernel_neon_float_process1(const float32_t *x,
|
||||
const float32_t *y, float32_t *sum, int len) {
|
||||
float32x4_t XX[4];
|
||||
float32x4_t YY[4];
|
||||
float32x2_t XX_2;
|
||||
float32x2_t YY_2;
|
||||
float32x4_t SUMM;
|
||||
float32x2_t SUMM_2[2];
|
||||
const float32_t *xi = x;
|
||||
const float32_t *yi = y;
|
||||
|
||||
SUMM = vdupq_n_f32(0);
|
||||
|
||||
/* Work on 16 values per iteration */
|
||||
while (len >= 16) {
|
||||
XX[0] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
XX[1] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
XX[2] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
XX[3] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
|
||||
YY[0] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
YY[1] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
YY[2] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
YY[3] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
|
||||
SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
|
||||
SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);
|
||||
SUMM = vmlaq_f32(SUMM, YY[2], XX[2]);
|
||||
SUMM = vmlaq_f32(SUMM, YY[3], XX[3]);
|
||||
len -= 16;
|
||||
}
|
||||
|
||||
/* Work on 8 values */
|
||||
if (len >= 8) {
|
||||
XX[0] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
XX[1] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
|
||||
YY[0] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
YY[1] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
|
||||
SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
|
||||
SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);
|
||||
len -= 8;
|
||||
}
|
||||
|
||||
/* Work on 4 values */
|
||||
if (len >= 4) {
|
||||
XX[0] = vld1q_f32(xi);
|
||||
xi += 4;
|
||||
YY[0] = vld1q_f32(yi);
|
||||
yi += 4;
|
||||
SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
/* Start accumulating results */
|
||||
SUMM_2[0] = vget_low_f32(SUMM);
|
||||
if (len >= 2) {
|
||||
/* While at it, consume 2 more values if available */
|
||||
XX_2 = vld1_f32(xi);
|
||||
xi += 2;
|
||||
YY_2 = vld1_f32(yi);
|
||||
yi += 2;
|
||||
SUMM_2[0] = vmla_f32(SUMM_2[0], YY_2, XX_2);
|
||||
len -= 2;
|
||||
}
|
||||
SUMM_2[1] = vget_high_f32(SUMM);
|
||||
SUMM_2[0] = vadd_f32(SUMM_2[0], SUMM_2[1]);
|
||||
SUMM_2[0] = vpadd_f32(SUMM_2[0], SUMM_2[0]);
|
||||
/* Ok, now we have result accumulated in SUMM_2[0].0 */
|
||||
|
||||
if (len > 0) {
|
||||
/* Case when you have one value left */
|
||||
XX_2 = vld1_dup_f32(xi);
|
||||
YY_2 = vld1_dup_f32(yi);
|
||||
SUMM_2[0] = vmla_f32(SUMM_2[0], XX_2, YY_2);
|
||||
}
|
||||
|
||||
vst1_lane_f32(sum, SUMM_2[0], 0);
|
||||
}
|
||||
|
||||
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
|
||||
opus_val32 *xcorr, int len, int max_pitch) {
|
||||
int i;
|
||||
celt_assert(max_pitch > 0);
|
||||
celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
|
||||
|
||||
for (i = 0; i < (max_pitch-3); i += 4) {
|
||||
xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i,
|
||||
(float32_t *)xcorr+i, len);
|
||||
}
|
||||
|
||||
/* In case max_pitch isn't multiple of 4
|
||||
* compute single correlation value per iteration
|
||||
*/
|
||||
for (; i < max_pitch; i++) {
|
||||
xcorr_kernel_neon_float_process1((const float32_t *)_x,
|
||||
(const float32_t *)_y+i, (float32_t *)xcorr+i, len);
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,72 +0,0 @@
|
||||
/* Copyright (c) 2015 Xiph.Org Foundation
|
||||
Written by Viswanath Puttagunta */
|
||||
/**
|
||||
@file fft_arm.h
|
||||
@brief ARM Neon Intrinsic optimizations for fft using NE10 library
|
||||
*/
|
||||
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(FFT_ARM_H)
|
||||
#define FFT_ARM_H
|
||||
|
||||
#include "opus/opus_config.h"
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
|
||||
#if defined(HAVE_ARM_NE10)
|
||||
|
||||
int opus_fft_alloc_arm_neon(kiss_fft_state *st);
|
||||
void opus_fft_free_arm_neon(kiss_fft_state *st);
|
||||
|
||||
void opus_fft_neon(const kiss_fft_state *st,
|
||||
const kiss_fft_cpx *fin,
|
||||
kiss_fft_cpx *fout);
|
||||
|
||||
void opus_ifft_neon(const kiss_fft_state *st,
|
||||
const kiss_fft_cpx *fin,
|
||||
kiss_fft_cpx *fout);
|
||||
|
||||
#if !defined(OPUS_HAVE_RTCD)
|
||||
#define OVERRIDE_OPUS_FFT (1)
|
||||
|
||||
#define opus_fft_alloc_arch(_st, arch) \
|
||||
((void)(arch), opus_fft_alloc_arm_neon(_st))
|
||||
|
||||
#define opus_fft_free_arch(_st, arch) \
|
||||
((void)(arch), opus_fft_free_arm_neon(_st))
|
||||
|
||||
#define opus_fft(_st, _fin, _fout, arch) \
|
||||
((void)(arch), opus_fft_neon(_st, _fin, _fout))
|
||||
|
||||
#define opus_ifft(_st, _fin, _fout, arch) \
|
||||
((void)(arch), opus_ifft_neon(_st, _fin, _fout))
|
||||
|
||||
#endif /* OPUS_HAVE_RTCD */
|
||||
|
||||
#endif /* HAVE_ARM_NE10 */
|
||||
|
||||
#endif
|
@ -1,151 +0,0 @@
|
||||
/* Copyright (C) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (C) 2003-2008 Jean-Marc Valin
|
||||
Copyright (C) 2007-2008 CSIRO
|
||||
Copyright (C) 2013 Parrot */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_ARMv5E_H
|
||||
#define FIXED_ARMv5E_H
|
||||
|
||||
#include "opus/celt/arm/fixed_armv4.h"
|
||||
|
||||
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
|
||||
#undef MULT16_32_Q16
|
||||
static OPUS_INLINE opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#MULT16_32_Q16\n\t"
|
||||
"smulwb %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(b),"r"(a)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b))
|
||||
|
||||
|
||||
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
|
||||
#undef MULT16_32_Q15
|
||||
static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#MULT16_32_Q15\n\t"
|
||||
"smulwb %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(b), "r"(a)
|
||||
);
|
||||
return res<<1;
|
||||
}
|
||||
#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))
|
||||
|
||||
|
||||
/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
|
||||
b must fit in 31 bits.
|
||||
Result fits in 32 bits. */
|
||||
#undef MAC16_32_Q15
|
||||
static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a,
|
||||
opus_val32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#MAC16_32_Q15\n\t"
|
||||
"smlawb %0, %1, %2, %3;\n"
|
||||
: "=r"(res)
|
||||
: "r"(b<<1), "r"(a), "r"(c)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b))
|
||||
|
||||
/** 16x32 multiply, followed by a 16-bit shift right and 32-bit add.
|
||||
Result fits in 32 bits. */
|
||||
#undef MAC16_32_Q16
|
||||
static OPUS_INLINE opus_val32 MAC16_32_Q16_armv5e(opus_val32 c, opus_val16 a,
|
||||
opus_val32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#MAC16_32_Q16\n\t"
|
||||
"smlawb %0, %1, %2, %3;\n"
|
||||
: "=r"(res)
|
||||
: "r"(b), "r"(a), "r"(c)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define MAC16_32_Q16(c, a, b) (MAC16_32_Q16_armv5e(c, a, b))
|
||||
|
||||
/** 16x16 multiply-add where the result fits in 32 bits */
|
||||
#undef MAC16_16
|
||||
static OPUS_INLINE opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a,
|
||||
opus_val16 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#MAC16_16\n\t"
|
||||
"smlabb %0, %1, %2, %3;\n"
|
||||
: "=r"(res)
|
||||
: "r"(a), "r"(b), "r"(c)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b))
|
||||
|
||||
/** 16x16 multiplication where the result fits in 32 bits */
|
||||
#undef MULT16_16
|
||||
static OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#MULT16_16\n\t"
|
||||
"smulbb %0, %1, %2;\n"
|
||||
: "=r"(res)
|
||||
: "r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define MULT16_16(a, b) (MULT16_16_armv5e(a, b))
|
||||
|
||||
#ifdef OPUS_ARM_INLINE_MEDIA
|
||||
|
||||
#undef SIG2WORD16
|
||||
static OPUS_INLINE opus_val16 SIG2WORD16_armv6(opus_val32 x)
|
||||
{
|
||||
celt_sig res;
|
||||
__asm__(
|
||||
"#SIG2WORD16\n\t"
|
||||
"ssat %0, #16, %1, ASR #12\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(x+2048)
|
||||
);
|
||||
return EXTRACT16(res);
|
||||
}
|
||||
#define SIG2WORD16(x) (SIG2WORD16_armv6(x))
|
||||
|
||||
#endif /* OPUS_ARM_INLINE_MEDIA */
|
||||
|
||||
#endif
|
@ -1,121 +0,0 @@
|
||||
/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.*/
|
||||
|
||||
#ifndef KISS_FFT_ARMv4_H
|
||||
#define KISS_FFT_ARMv4_H
|
||||
|
||||
#if !defined(KISS_FFT_GUTS_H)
|
||||
#error "This file should only be included from _kiss_fft_guts.h"
|
||||
#endif
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
|
||||
#undef C_MUL
|
||||
#define C_MUL(m,a,b) \
|
||||
do{ \
|
||||
int br__; \
|
||||
int bi__; \
|
||||
int tt__; \
|
||||
__asm__ __volatile__( \
|
||||
"#C_MUL\n\t" \
|
||||
"ldrsh %[br], [%[bp], #0]\n\t" \
|
||||
"ldm %[ap], {r0,r1}\n\t" \
|
||||
"ldrsh %[bi], [%[bp], #2]\n\t" \
|
||||
"smull %[tt], %[mi], r1, %[br]\n\t" \
|
||||
"smlal %[tt], %[mi], r0, %[bi]\n\t" \
|
||||
"rsb %[bi], %[bi], #0\n\t" \
|
||||
"smull %[br], %[mr], r0, %[br]\n\t" \
|
||||
"mov %[tt], %[tt], lsr #15\n\t" \
|
||||
"smlal %[br], %[mr], r1, %[bi]\n\t" \
|
||||
"orr %[mi], %[tt], %[mi], lsl #17\n\t" \
|
||||
"mov %[br], %[br], lsr #15\n\t" \
|
||||
"orr %[mr], %[br], %[mr], lsl #17\n\t" \
|
||||
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
|
||||
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
|
||||
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#undef C_MUL4
|
||||
#define C_MUL4(m,a,b) \
|
||||
do{ \
|
||||
int br__; \
|
||||
int bi__; \
|
||||
int tt__; \
|
||||
__asm__ __volatile__( \
|
||||
"#C_MUL4\n\t" \
|
||||
"ldrsh %[br], [%[bp], #0]\n\t" \
|
||||
"ldm %[ap], {r0,r1}\n\t" \
|
||||
"ldrsh %[bi], [%[bp], #2]\n\t" \
|
||||
"smull %[tt], %[mi], r1, %[br]\n\t" \
|
||||
"smlal %[tt], %[mi], r0, %[bi]\n\t" \
|
||||
"rsb %[bi], %[bi], #0\n\t" \
|
||||
"smull %[br], %[mr], r0, %[br]\n\t" \
|
||||
"mov %[tt], %[tt], lsr #17\n\t" \
|
||||
"smlal %[br], %[mr], r1, %[bi]\n\t" \
|
||||
"orr %[mi], %[tt], %[mi], lsl #15\n\t" \
|
||||
"mov %[br], %[br], lsr #17\n\t" \
|
||||
"orr %[mr], %[br], %[mr], lsl #15\n\t" \
|
||||
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
|
||||
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
|
||||
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#undef C_MULC
|
||||
#define C_MULC(m,a,b) \
|
||||
do{ \
|
||||
int br__; \
|
||||
int bi__; \
|
||||
int tt__; \
|
||||
__asm__ __volatile__( \
|
||||
"#C_MULC\n\t" \
|
||||
"ldrsh %[br], [%[bp], #0]\n\t" \
|
||||
"ldm %[ap], {r0,r1}\n\t" \
|
||||
"ldrsh %[bi], [%[bp], #2]\n\t" \
|
||||
"smull %[tt], %[mr], r0, %[br]\n\t" \
|
||||
"smlal %[tt], %[mr], r1, %[bi]\n\t" \
|
||||
"rsb %[bi], %[bi], #0\n\t" \
|
||||
"smull %[br], %[mi], r1, %[br]\n\t" \
|
||||
"mov %[tt], %[tt], lsr #15\n\t" \
|
||||
"smlal %[br], %[mi], r0, %[bi]\n\t" \
|
||||
"orr %[mr], %[tt], %[mr], lsl #17\n\t" \
|
||||
"mov %[br], %[br], lsr #15\n\t" \
|
||||
"orr %[mi], %[br], %[mi], lsl #17\n\t" \
|
||||
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
|
||||
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
|
||||
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#endif /* FIXED_POINT */
|
||||
|
||||
#endif /* KISS_FFT_ARMv4_H */
|
@ -1,118 +0,0 @@
|
||||
/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.*/
|
||||
|
||||
#ifndef KISS_FFT_ARMv5E_H
|
||||
#define KISS_FFT_ARMv5E_H
|
||||
|
||||
#if !defined(KISS_FFT_GUTS_H)
|
||||
#error "This file should only be included from _kiss_fft_guts.h"
|
||||
#endif
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
|
||||
#if defined(__thumb__)||defined(__thumb2__)
|
||||
#define LDRD_CONS "Q"
|
||||
#else
|
||||
#define LDRD_CONS "Uq"
|
||||
#endif
|
||||
|
||||
#undef C_MUL
|
||||
#define C_MUL(m,a,b) \
|
||||
do{ \
|
||||
int mr1__; \
|
||||
int mr2__; \
|
||||
int mi__; \
|
||||
long long aval__; \
|
||||
int bval__; \
|
||||
__asm__( \
|
||||
"#C_MUL\n\t" \
|
||||
"ldrd %[aval], %H[aval], %[ap]\n\t" \
|
||||
"ldr %[bval], %[bp]\n\t" \
|
||||
"smulwb %[mi], %H[aval], %[bval]\n\t" \
|
||||
"smulwb %[mr1], %[aval], %[bval]\n\t" \
|
||||
"smulwt %[mr2], %H[aval], %[bval]\n\t" \
|
||||
"smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \
|
||||
: [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \
|
||||
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
|
||||
: [ap]LDRD_CONS(a), [bp]"m"(b) \
|
||||
); \
|
||||
(m).r = SHL32(SUB32(mr1__, mr2__), 1); \
|
||||
(m).i = SHL32(mi__, 1); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#undef C_MUL4
|
||||
#define C_MUL4(m,a,b) \
|
||||
do{ \
|
||||
int mr1__; \
|
||||
int mr2__; \
|
||||
int mi__; \
|
||||
long long aval__; \
|
||||
int bval__; \
|
||||
__asm__( \
|
||||
"#C_MUL4\n\t" \
|
||||
"ldrd %[aval], %H[aval], %[ap]\n\t" \
|
||||
"ldr %[bval], %[bp]\n\t" \
|
||||
"smulwb %[mi], %H[aval], %[bval]\n\t" \
|
||||
"smulwb %[mr1], %[aval], %[bval]\n\t" \
|
||||
"smulwt %[mr2], %H[aval], %[bval]\n\t" \
|
||||
"smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \
|
||||
: [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \
|
||||
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
|
||||
: [ap]LDRD_CONS(a), [bp]"m"(b) \
|
||||
); \
|
||||
(m).r = SHR32(SUB32(mr1__, mr2__), 1); \
|
||||
(m).i = SHR32(mi__, 1); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#undef C_MULC
|
||||
#define C_MULC(m,a,b) \
|
||||
do{ \
|
||||
int mr__; \
|
||||
int mi1__; \
|
||||
int mi2__; \
|
||||
long long aval__; \
|
||||
int bval__; \
|
||||
__asm__( \
|
||||
"#C_MULC\n\t" \
|
||||
"ldrd %[aval], %H[aval], %[ap]\n\t" \
|
||||
"ldr %[bval], %[bp]\n\t" \
|
||||
"smulwb %[mr], %[aval], %[bval]\n\t" \
|
||||
"smulwb %[mi1], %H[aval], %[bval]\n\t" \
|
||||
"smulwt %[mi2], %[aval], %[bval]\n\t" \
|
||||
"smlawt %[mr], %H[aval], %[bval], %[mr]\n\t" \
|
||||
: [mr]"=r"(mr__), [mi1]"=r"(mi1__), [mi2]"=r"(mi2__), \
|
||||
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
|
||||
: [ap]LDRD_CONS(a), [bp]"m"(b) \
|
||||
); \
|
||||
(m).r = SHL32(mr__, 1); \
|
||||
(m).i = SHL32(SUB32(mi1__, mi2__), 1); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#endif /* FIXED_POINT */
|
||||
|
||||
#endif /* KISS_FFT_GUTS_H */
|
@ -1,60 +0,0 @@
|
||||
/* Copyright (c) 2015 Xiph.Org Foundation
|
||||
Written by Viswanath Puttagunta */
|
||||
/**
|
||||
@file arm_mdct.h
|
||||
@brief ARM Neon Intrinsic optimizations for mdct using NE10 library
|
||||
*/
|
||||
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(MDCT_ARM_H)
|
||||
#define MDCT_ARM_H
|
||||
|
||||
#include "opus/opus_config.h"
|
||||
#include "opus/celt/mdct.h"
|
||||
|
||||
#if defined(HAVE_ARM_NE10)
|
||||
/** Compute a forward MDCT and scale by 4/N, trashes the input array */
|
||||
void clt_mdct_forward_neon(const mdct_lookup *l, kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window, int overlap,
|
||||
int shift, int stride, int arch);
|
||||
|
||||
void clt_mdct_backward_neon(const mdct_lookup *l, kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window, int overlap,
|
||||
int shift, int stride, int arch);
|
||||
|
||||
#if !defined(OPUS_HAVE_RTCD)
|
||||
#define OVERRIDE_OPUS_MDCT (1)
|
||||
#define clt_mdct_forward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \
|
||||
clt_mdct_forward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)
|
||||
#define clt_mdct_backward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \
|
||||
clt_mdct_backward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)
|
||||
#endif /* OPUS_HAVE_RTCD */
|
||||
#endif /* HAVE_ARM_NE10 */
|
||||
|
||||
#endif
|
@ -1,68 +0,0 @@
|
||||
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||
* Copyright (c) 2013 Parrot */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(PITCH_ARM_H)
|
||||
# define PITCH_ARM_H
|
||||
|
||||
# include "opus/celt/arm/armcpu.h"
|
||||
|
||||
# if defined(FIXED_POINT)
|
||||
|
||||
# if defined(OPUS_ARM_MAY_HAVE_NEON)
|
||||
opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,
|
||||
opus_val32 *xcorr, int len, int max_pitch);
|
||||
# endif
|
||||
|
||||
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
|
||||
# define celt_pitch_xcorr_media MAY_HAVE_EDSP(celt_pitch_xcorr)
|
||||
# endif
|
||||
|
||||
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
|
||||
opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
|
||||
opus_val32 *xcorr, int len, int max_pitch);
|
||||
# endif
|
||||
|
||||
# if !defined(OPUS_HAVE_RTCD)
|
||||
# define OVERRIDE_PITCH_XCORR (1)
|
||||
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
|
||||
((void)(arch),PRESUME_NEON(celt_pitch_xcorr)(_x, _y, xcorr, len, max_pitch))
|
||||
# endif
|
||||
|
||||
#else /* Start !FIXED_POINT */
|
||||
/* Float case */
|
||||
#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
|
||||
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
|
||||
opus_val32 *xcorr, int len, int max_pitch);
|
||||
#if !defined(OPUS_HAVE_RTCD) || defined(OPUS_ARM_PRESUME_NEON_INTR)
|
||||
#define OVERRIDE_PITCH_XCORR (1)
|
||||
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
|
||||
((void)(arch),celt_pitch_xcorr_float_neon(_x, _y, xcorr, len, max_pitch))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* end !FIXED_POINT */
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (c) 2008-2009 Gregory Maxwell
|
||||
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef BANDS_H
|
||||
#define BANDS_H
|
||||
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/modes.h"
|
||||
#include "opus/celt/entenc.h"
|
||||
#include "opus/celt/entdec.h"
|
||||
#include "opus/celt/rate.h"
|
||||
|
||||
/** Compute the amplitude (sqrt energy) in each of the bands
|
||||
* @param m Mode data
|
||||
* @param X Spectrum
|
||||
* @param bandE Square root of the energy for each band (returned)
|
||||
*/
|
||||
void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM);
|
||||
|
||||
/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/
|
||||
|
||||
/** Normalise each band of X such that the energy in each band is
|
||||
equal to 1
|
||||
* @param m Mode data
|
||||
* @param X Spectrum (returned normalised)
|
||||
* @param bandE Square root of the energy for each band
|
||||
*/
|
||||
void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M);
|
||||
|
||||
/** Denormalise each band of X to restore full amplitude
|
||||
* @param m Mode data
|
||||
* @param X Spectrum (returned de-normalised)
|
||||
* @param bandE Square root of the energy for each band
|
||||
*/
|
||||
void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
|
||||
celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandE, int start,
|
||||
int end, int M, int downsample, int silence);
|
||||
|
||||
#define SPREAD_NONE (0)
|
||||
#define SPREAD_LIGHT (1)
|
||||
#define SPREAD_NORMAL (2)
|
||||
#define SPREAD_AGGRESSIVE (3)
|
||||
|
||||
int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
|
||||
int last_decision, int *hf_average, int *tapset_decision, int update_hf,
|
||||
int end, int C, int M);
|
||||
|
||||
#ifdef MEASURE_NORM_MSE
|
||||
void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);
|
||||
#endif
|
||||
|
||||
void haar1(celt_norm *X, int N0, int stride);
|
||||
|
||||
/** Quantisation/encoding of the residual spectrum
|
||||
* @param encode flag that indicates whether we're encoding (1) or decoding (0)
|
||||
* @param m Mode data
|
||||
* @param start First band to process
|
||||
* @param end Last band to process + 1
|
||||
* @param X Residual (normalised)
|
||||
* @param Y Residual (normalised) for second channel (or NULL for mono)
|
||||
* @param collapse_masks Anti-collapse tracking mask
|
||||
* @param bandE Square root of the energy for each band
|
||||
* @param pulses Bit allocation (per band) for PVQ
|
||||
* @param shortBlocks Zero for long blocks, non-zero for short blocks
|
||||
* @param spread Amount of spreading to use
|
||||
* @param dual_stereo Zero for MS stereo, non-zero for dual stereo
|
||||
* @param intensity First band to use intensity stereo
|
||||
* @param tf_res Time-frequency resolution change
|
||||
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
|
||||
* @param balance Number of unallocated bits
|
||||
* @param en Entropy coder state
|
||||
* @param LM log2() of the number of 2.5 subframes in the frame
|
||||
* @param codedBands Last band to receive bits + 1
|
||||
* @param seed Random generator seed
|
||||
* @param arch Run-time architecture (see opus_select_arch())
|
||||
*/
|
||||
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks,
|
||||
const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
|
||||
int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
|
||||
opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed,
|
||||
int arch);
|
||||
|
||||
void anti_collapse(const CELTMode *m, celt_norm *X_,
|
||||
unsigned char *collapse_masks, int LM, int C, int size, int start,
|
||||
int end, const opus_val16 *logE, const opus_val16 *prev1logE,
|
||||
const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed,
|
||||
int arch);
|
||||
|
||||
opus_uint32 celt_lcg_rand(opus_uint32 seed);
|
||||
|
||||
int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev);
|
||||
|
||||
#endif /* BANDS_H */
|
@ -1,296 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2010 Xiph.Org Foundation
|
||||
Copyright (c) 2008 Gregory Maxwell
|
||||
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#define CELT_C
|
||||
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/mdct.h"
|
||||
#include <math.h>
|
||||
#include "opus/celt/celt.h"
|
||||
#include "opus/celt/pitch.h"
|
||||
#include "opus/celt/bands.h"
|
||||
#include "opus/celt/modes.h"
|
||||
#include "opus/celt/entcode.h"
|
||||
#include "opus/celt/quant_bands.h"
|
||||
#include "opus/celt/rate.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/float_cast.h"
|
||||
#include <stdarg.h>
|
||||
#include "opus/celt/celt_lpc.h"
|
||||
#include "opus/celt/vq.h"
|
||||
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "unknown"
|
||||
#endif
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "opus/celt/mips/celt_mipsr1.h"
|
||||
#endif
|
||||
|
||||
|
||||
int resampling_factor(opus_int32 rate)
|
||||
{
|
||||
int ret;
|
||||
switch (rate)
|
||||
{
|
||||
case 48000:
|
||||
ret = 1;
|
||||
break;
|
||||
case 24000:
|
||||
ret = 2;
|
||||
break;
|
||||
case 16000:
|
||||
ret = 3;
|
||||
break;
|
||||
case 12000:
|
||||
ret = 4;
|
||||
break;
|
||||
case 8000:
|
||||
ret = 6;
|
||||
break;
|
||||
default:
|
||||
#ifndef CUSTOM_MODES
|
||||
celt_assert(0);
|
||||
#endif
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)
|
||||
/* This version should be faster on ARM */
|
||||
#ifdef OPUS_ARM_ASM
|
||||
#ifndef NON_STATIC_COMB_FILTER_CONST_C
|
||||
static
|
||||
#endif
|
||||
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
|
||||
opus_val16 g10, opus_val16 g11, opus_val16 g12)
|
||||
{
|
||||
opus_val32 x0, x1, x2, x3, x4;
|
||||
int i;
|
||||
x4 = SHL32(x[-T-2], 1);
|
||||
x3 = SHL32(x[-T-1], 1);
|
||||
x2 = SHL32(x[-T], 1);
|
||||
x1 = SHL32(x[-T+1], 1);
|
||||
for (i=0;i<N-4;i+=5)
|
||||
{
|
||||
opus_val32 t;
|
||||
x0=SHL32(x[i-T+2],1);
|
||||
t = MAC16_32_Q16(x[i], g10, x2);
|
||||
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
|
||||
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
|
||||
y[i] = t;
|
||||
x4=SHL32(x[i-T+3],1);
|
||||
t = MAC16_32_Q16(x[i+1], g10, x1);
|
||||
t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
|
||||
t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
|
||||
y[i+1] = t;
|
||||
x3=SHL32(x[i-T+4],1);
|
||||
t = MAC16_32_Q16(x[i+2], g10, x0);
|
||||
t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
|
||||
t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
|
||||
y[i+2] = t;
|
||||
x2=SHL32(x[i-T+5],1);
|
||||
t = MAC16_32_Q16(x[i+3], g10, x4);
|
||||
t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
|
||||
t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
|
||||
y[i+3] = t;
|
||||
x1=SHL32(x[i-T+6],1);
|
||||
t = MAC16_32_Q16(x[i+4], g10, x3);
|
||||
t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
|
||||
t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
|
||||
y[i+4] = t;
|
||||
}
|
||||
#ifdef CUSTOM_MODES
|
||||
for (;i<N;i++)
|
||||
{
|
||||
opus_val32 t;
|
||||
x0=SHL32(x[i-T+2],1);
|
||||
t = MAC16_32_Q16(x[i], g10, x2);
|
||||
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
|
||||
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
|
||||
y[i] = t;
|
||||
x4=x3;
|
||||
x3=x2;
|
||||
x2=x1;
|
||||
x1=x0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#ifndef NON_STATIC_COMB_FILTER_CONST_C
|
||||
static
|
||||
#endif
|
||||
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
|
||||
opus_val16 g10, opus_val16 g11, opus_val16 g12)
|
||||
{
|
||||
opus_val32 x0, x1, x2, x3, x4;
|
||||
int i;
|
||||
x4 = x[-T-2];
|
||||
x3 = x[-T-1];
|
||||
x2 = x[-T];
|
||||
x1 = x[-T+1];
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
x0=x[i-T+2];
|
||||
y[i] = x[i]
|
||||
+ MULT16_32_Q15(g10,x2)
|
||||
+ MULT16_32_Q15(g11,ADD32(x1,x3))
|
||||
+ MULT16_32_Q15(g12,ADD32(x0,x4));
|
||||
x4=x3;
|
||||
x3=x2;
|
||||
x2=x1;
|
||||
x1=x0;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_comb_filter
|
||||
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
|
||||
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
|
||||
const opus_val16 *window, int overlap, int arch)
|
||||
{
|
||||
int i;
|
||||
/* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
|
||||
opus_val16 g00, g01, g02, g10, g11, g12;
|
||||
opus_val32 x0, x1, x2, x3, x4;
|
||||
static const opus_val16 gains[3][3] = {
|
||||
{QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
|
||||
{QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
|
||||
{QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
|
||||
|
||||
if (g0==0 && g1==0)
|
||||
{
|
||||
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
|
||||
if (x!=y)
|
||||
OPUS_MOVE(y, x, N);
|
||||
return;
|
||||
}
|
||||
g00 = MULT16_16_P15(g0, gains[tapset0][0]);
|
||||
g01 = MULT16_16_P15(g0, gains[tapset0][1]);
|
||||
g02 = MULT16_16_P15(g0, gains[tapset0][2]);
|
||||
g10 = MULT16_16_P15(g1, gains[tapset1][0]);
|
||||
g11 = MULT16_16_P15(g1, gains[tapset1][1]);
|
||||
g12 = MULT16_16_P15(g1, gains[tapset1][2]);
|
||||
x1 = x[-T1+1];
|
||||
x2 = x[-T1 ];
|
||||
x3 = x[-T1-1];
|
||||
x4 = x[-T1-2];
|
||||
/* If the filter didn't change, we don't need the overlap */
|
||||
if (g0==g1 && T0==T1 && tapset0==tapset1)
|
||||
overlap=0;
|
||||
for (i=0;i<overlap;i++)
|
||||
{
|
||||
opus_val16 f;
|
||||
x0=x[i-T1+2];
|
||||
f = MULT16_16_Q15(window[i],window[i]);
|
||||
y[i] = x[i]
|
||||
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
|
||||
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
|
||||
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
|
||||
+ MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
|
||||
+ MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
|
||||
+ MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
|
||||
x4=x3;
|
||||
x3=x2;
|
||||
x2=x1;
|
||||
x1=x0;
|
||||
|
||||
}
|
||||
if (g1==0)
|
||||
{
|
||||
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
|
||||
if (x!=y)
|
||||
OPUS_MOVE(y+overlap, x+overlap, N-overlap);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Compute the part with the constant filter. */
|
||||
comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
|
||||
}
|
||||
#endif /* OVERRIDE_comb_filter */
|
||||
|
||||
const signed char tf_select_table[4][8] = {
|
||||
{0, -1, 0, -1, 0,-1, 0,-1},
|
||||
{0, -1, 0, -2, 1, 0, 1,-1},
|
||||
{0, -2, 0, -3, 2, 0, 1,-1},
|
||||
{0, -2, 0, -3, 3, 0, 1,-1},
|
||||
};
|
||||
|
||||
|
||||
void init_caps(const CELTMode *m,int *cap,int LM,int C)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<m->nbEBands;i++)
|
||||
{
|
||||
int N;
|
||||
N=(m->eBands[i+1]-m->eBands[i])<<LM;
|
||||
cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *opus_strerror(int error)
|
||||
{
|
||||
static const char * const error_strings[8] = {
|
||||
"success",
|
||||
"invalid argument",
|
||||
"buffer too small",
|
||||
"internal error",
|
||||
"corrupted stream",
|
||||
"request not implemented",
|
||||
"invalid state",
|
||||
"memory allocation failed"
|
||||
};
|
||||
if (error > 0 || error < -7)
|
||||
return "unknown error";
|
||||
else
|
||||
return error_strings[-error];
|
||||
}
|
||||
|
||||
const char *opus_get_version_string(void)
|
||||
{
|
||||
return "libopus " PACKAGE_VERSION
|
||||
/* Applications may rely on the presence of this substring in the version
|
||||
string to determine if they have a fixed-point or floating-point build
|
||||
at runtime. */
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
"-fixed"
|
||||
#endif
|
||||
#ifdef FUZZING
|
||||
"-fuzzing"
|
||||
#endif
|
||||
;
|
||||
}
|
@ -1,229 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (c) 2008 Gregory Maxwell
|
||||
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||
/**
|
||||
@file celt.h
|
||||
@brief Contains all the functions for encoding and decoding audio
|
||||
*/
|
||||
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CELT_H
|
||||
#define CELT_H
|
||||
|
||||
#include "opus/opus_types.h"
|
||||
#include "opus/opus_defines.h"
|
||||
#include "opus/opus_custom.h"
|
||||
#include "opus/celt/entenc.h"
|
||||
#include "opus/celt/entdec.h"
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CELTEncoder OpusCustomEncoder
|
||||
#define CELTDecoder OpusCustomDecoder
|
||||
#define CELTMode OpusCustomMode
|
||||
|
||||
typedef struct {
|
||||
int valid;
|
||||
float tonality;
|
||||
float tonality_slope;
|
||||
float noisiness;
|
||||
float activity;
|
||||
float music_prob;
|
||||
int bandwidth;
|
||||
}AnalysisInfo;
|
||||
|
||||
#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
|
||||
|
||||
#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr)))
|
||||
|
||||
/* Encoder/decoder Requests */
|
||||
|
||||
/* Expose this option again when variable framesize actually works */
|
||||
#define OPUS_FRAMESIZE_VARIABLE 5010 /**< Optimize the frame size dynamically */
|
||||
|
||||
|
||||
#define CELT_SET_PREDICTION_REQUEST 10002
|
||||
/** Controls the use of interframe prediction.
|
||||
0=Independent frames
|
||||
1=Short term interframe prediction allowed
|
||||
2=Long term prediction allowed
|
||||
*/
|
||||
#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x)
|
||||
|
||||
#define CELT_SET_INPUT_CLIPPING_REQUEST 10004
|
||||
#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x)
|
||||
|
||||
#define CELT_GET_AND_CLEAR_ERROR_REQUEST 10007
|
||||
#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x)
|
||||
|
||||
#define CELT_SET_CHANNELS_REQUEST 10008
|
||||
#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x)
|
||||
|
||||
|
||||
/* Internal */
|
||||
#define CELT_SET_START_BAND_REQUEST 10010
|
||||
#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x)
|
||||
|
||||
#define CELT_SET_END_BAND_REQUEST 10012
|
||||
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x)
|
||||
|
||||
#define CELT_GET_MODE_REQUEST 10015
|
||||
/** Get the CELTMode used by an encoder or decoder */
|
||||
#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, __celt_check_mode_ptr_ptr(x)
|
||||
|
||||
#define CELT_SET_SIGNALLING_REQUEST 10016
|
||||
#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x)
|
||||
|
||||
#define CELT_SET_TONALITY_REQUEST 10018
|
||||
#define CELT_SET_TONALITY(x) CELT_SET_TONALITY_REQUEST, __opus_check_int(x)
|
||||
#define CELT_SET_TONALITY_SLOPE_REQUEST 10020
|
||||
#define CELT_SET_TONALITY_SLOPE(x) CELT_SET_TONALITY_SLOPE_REQUEST, __opus_check_int(x)
|
||||
|
||||
#define CELT_SET_ANALYSIS_REQUEST 10022
|
||||
#define CELT_SET_ANALYSIS(x) CELT_SET_ANALYSIS_REQUEST, __celt_check_analysis_ptr(x)
|
||||
|
||||
#define OPUS_SET_LFE_REQUEST 10024
|
||||
#define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x)
|
||||
|
||||
#define OPUS_SET_ENERGY_MASK_REQUEST 10026
|
||||
#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)
|
||||
|
||||
/* Encoder stuff */
|
||||
|
||||
int celt_encoder_get_size(int channels);
|
||||
|
||||
int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
|
||||
|
||||
int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,
|
||||
int arch);
|
||||
|
||||
|
||||
|
||||
/* Decoder stuff */
|
||||
|
||||
int celt_decoder_get_size(int channels);
|
||||
|
||||
|
||||
int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels);
|
||||
|
||||
int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data,
|
||||
int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum);
|
||||
|
||||
#define celt_encoder_ctl opus_custom_encoder_ctl
|
||||
#define celt_decoder_ctl opus_custom_decoder_ctl
|
||||
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
#define OPUS_CUSTOM_NOSTATIC
|
||||
#else
|
||||
#define OPUS_CUSTOM_NOSTATIC static OPUS_INLINE
|
||||
#endif
|
||||
|
||||
static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
|
||||
/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
|
||||
static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
|
||||
|
||||
static const unsigned char tapset_icdf[3]={2,1,0};
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
static const unsigned char toOpusTable[20] = {
|
||||
0xE0, 0xE8, 0xF0, 0xF8,
|
||||
0xC0, 0xC8, 0xD0, 0xD8,
|
||||
0xA0, 0xA8, 0xB0, 0xB8,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x88, 0x90, 0x98,
|
||||
};
|
||||
|
||||
static const unsigned char fromOpusTable[16] = {
|
||||
0x80, 0x88, 0x90, 0x98,
|
||||
0x40, 0x48, 0x50, 0x58,
|
||||
0x20, 0x28, 0x30, 0x38,
|
||||
0x00, 0x08, 0x10, 0x18
|
||||
};
|
||||
|
||||
static OPUS_INLINE int toOpus(unsigned char c)
|
||||
{
|
||||
int ret=0;
|
||||
if (c<0xA0)
|
||||
ret = toOpusTable[c>>3];
|
||||
if (ret == 0)
|
||||
return -1;
|
||||
else
|
||||
return ret|(c&0x7);
|
||||
}
|
||||
|
||||
static OPUS_INLINE int fromOpus(unsigned char c)
|
||||
{
|
||||
if (c<0x80)
|
||||
return -1;
|
||||
else
|
||||
return fromOpusTable[(c>>3)-16] | (c&0x7);
|
||||
}
|
||||
#endif /* CUSTOM_MODES */
|
||||
|
||||
#define COMBFILTER_MAXPERIOD 1024
|
||||
#define COMBFILTER_MINPERIOD 15
|
||||
|
||||
extern const signed char tf_select_table[4][8];
|
||||
|
||||
int resampling_factor(opus_int32 rate);
|
||||
|
||||
void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
|
||||
int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip);
|
||||
|
||||
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
|
||||
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
|
||||
const opus_val16 *window, int overlap, int arch);
|
||||
|
||||
#ifdef NON_STATIC_COMB_FILTER_CONST_C
|
||||
void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
|
||||
opus_val16 g10, opus_val16 g11, opus_val16 g12);
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_COMB_FILTER_CONST
|
||||
# define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
|
||||
((void)(arch),comb_filter_const_c(y, x, T, N, g10, g11, g12))
|
||||
#endif
|
||||
|
||||
void init_caps(const CELTMode *m,int *cap,int LM,int C);
|
||||
|
||||
#ifdef RESYNTH
|
||||
void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem);
|
||||
void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
|
||||
opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient,
|
||||
int LM, int downsample, int silence);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CELT_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,312 +0,0 @@
|
||||
/* Copyright (c) 2009-2010 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/celt_lpc.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/pitch.h"
|
||||
|
||||
void _celt_lpc(
|
||||
opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
|
||||
const opus_val32 *ac, /* in: [0...p] autocorrelation values */
|
||||
int p
|
||||
)
|
||||
{
|
||||
int i, j;
|
||||
opus_val32 r;
|
||||
opus_val32 error = ac[0];
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
opus_val32 lpc[LPC_ORDER];
|
||||
#else
|
||||
float *lpc = _lpc;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < p; i++)
|
||||
lpc[i] = 0;
|
||||
if (ac[0] != 0)
|
||||
{
|
||||
for (i = 0; i < p; i++) {
|
||||
/* Sum up this iteration's reflection coefficient */
|
||||
opus_val32 rr = 0;
|
||||
for (j = 0; j < i; j++)
|
||||
rr += MULT32_32_Q31(lpc[j],ac[i - j]);
|
||||
rr += SHR32(ac[i + 1],3);
|
||||
r = -frac_div32(SHL32(rr,3), error);
|
||||
/* Update LPC coefficients and total error */
|
||||
lpc[i] = SHR32(r,3);
|
||||
for (j = 0; j < (i+1)>>1; j++)
|
||||
{
|
||||
opus_val32 tmp1, tmp2;
|
||||
tmp1 = lpc[j];
|
||||
tmp2 = lpc[i-1-j];
|
||||
lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2);
|
||||
lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
|
||||
}
|
||||
|
||||
error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
|
||||
/* Bail out once we get 30 dB gain */
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
if (error<SHR32(ac[0],10))
|
||||
break;
|
||||
#else
|
||||
if (error<.001f*ac[0])
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
for (i=0;i<p;i++)
|
||||
_lpc[i] = ROUND16(lpc[i],16);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void celt_fir_c(
|
||||
const opus_val16 *_x,
|
||||
const opus_val16 *num,
|
||||
opus_val16 *_y,
|
||||
int N,
|
||||
int ord,
|
||||
opus_val16 *mem,
|
||||
int arch)
|
||||
{
|
||||
int i,j;
|
||||
VARDECL(opus_val16, rnum);
|
||||
VARDECL(opus_val16, x);
|
||||
SAVE_STACK;
|
||||
|
||||
ALLOC(rnum, ord, opus_val16);
|
||||
ALLOC(x, N+ord, opus_val16);
|
||||
for(i=0;i<ord;i++)
|
||||
rnum[i] = num[ord-i-1];
|
||||
for(i=0;i<ord;i++)
|
||||
x[i] = mem[ord-i-1];
|
||||
for (i=0;i<N;i++)
|
||||
x[i+ord]=_x[i];
|
||||
for(i=0;i<ord;i++)
|
||||
mem[i] = _x[N-i-1];
|
||||
#ifdef SMALL_FOOTPRINT
|
||||
(void)arch;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
|
||||
for (j=0;j<ord;j++)
|
||||
{
|
||||
sum = MAC16_16(sum,rnum[j],x[i+j]);
|
||||
}
|
||||
_y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
|
||||
}
|
||||
#else
|
||||
for (i=0;i<N-3;i+=4)
|
||||
{
|
||||
opus_val32 sum[4]={0,0,0,0};
|
||||
xcorr_kernel(rnum, x+i, sum, ord, arch);
|
||||
_y[i ] = SATURATE16(ADD32(EXTEND32(_x[i ]), PSHR32(sum[0], SIG_SHIFT)));
|
||||
_y[i+1] = SATURATE16(ADD32(EXTEND32(_x[i+1]), PSHR32(sum[1], SIG_SHIFT)));
|
||||
_y[i+2] = SATURATE16(ADD32(EXTEND32(_x[i+2]), PSHR32(sum[2], SIG_SHIFT)));
|
||||
_y[i+3] = SATURATE16(ADD32(EXTEND32(_x[i+3]), PSHR32(sum[3], SIG_SHIFT)));
|
||||
}
|
||||
for (;i<N;i++)
|
||||
{
|
||||
opus_val32 sum = 0;
|
||||
for (j=0;j<ord;j++)
|
||||
sum = MAC16_16(sum,rnum[j],x[i+j]);
|
||||
_y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));
|
||||
}
|
||||
#endif
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
void celt_iir(const opus_val32 *_x,
|
||||
const opus_val16 *den,
|
||||
opus_val32 *_y,
|
||||
int N,
|
||||
int ord,
|
||||
opus_val16 *mem,
|
||||
int arch)
|
||||
{
|
||||
#ifdef SMALL_FOOTPRINT
|
||||
int i,j;
|
||||
(void)arch;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
opus_val32 sum = _x[i];
|
||||
for (j=0;j<ord;j++)
|
||||
{
|
||||
sum -= MULT16_16(den[j],mem[j]);
|
||||
}
|
||||
for (j=ord-1;j>=1;j--)
|
||||
{
|
||||
mem[j]=mem[j-1];
|
||||
}
|
||||
mem[0] = ROUND16(sum,SIG_SHIFT);
|
||||
_y[i] = sum;
|
||||
}
|
||||
#else
|
||||
int i,j;
|
||||
VARDECL(opus_val16, rden);
|
||||
VARDECL(opus_val16, y);
|
||||
SAVE_STACK;
|
||||
|
||||
celt_assert((ord&3)==0);
|
||||
ALLOC(rden, ord, opus_val16);
|
||||
ALLOC(y, N+ord, opus_val16);
|
||||
for(i=0;i<ord;i++)
|
||||
rden[i] = den[ord-i-1];
|
||||
for(i=0;i<ord;i++)
|
||||
y[i] = -mem[ord-i-1];
|
||||
for(;i<N+ord;i++)
|
||||
y[i]=0;
|
||||
for (i=0;i<N-3;i+=4)
|
||||
{
|
||||
/* Unroll by 4 as if it were an FIR filter */
|
||||
opus_val32 sum[4];
|
||||
sum[0]=_x[i];
|
||||
sum[1]=_x[i+1];
|
||||
sum[2]=_x[i+2];
|
||||
sum[3]=_x[i+3];
|
||||
xcorr_kernel(rden, y+i, sum, ord, arch);
|
||||
|
||||
/* Patch up the result to compensate for the fact that this is an IIR */
|
||||
y[i+ord ] = -ROUND16(sum[0],SIG_SHIFT);
|
||||
_y[i ] = sum[0];
|
||||
sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]);
|
||||
y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT);
|
||||
_y[i+1] = sum[1];
|
||||
sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
|
||||
sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]);
|
||||
y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT);
|
||||
_y[i+2] = sum[2];
|
||||
|
||||
sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
|
||||
sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
|
||||
sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]);
|
||||
y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT);
|
||||
_y[i+3] = sum[3];
|
||||
}
|
||||
for (;i<N;i++)
|
||||
{
|
||||
opus_val32 sum = _x[i];
|
||||
for (j=0;j<ord;j++)
|
||||
sum -= MULT16_16(rden[j],y[i+j]);
|
||||
y[i+ord] = ROUND16(sum,SIG_SHIFT);
|
||||
_y[i] = sum;
|
||||
}
|
||||
for(i=0;i<ord;i++)
|
||||
mem[i] = _y[N-i-1];
|
||||
RESTORE_STACK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int _celt_autocorr(
|
||||
const opus_val16 *x, /* in: [0...n-1] samples x */
|
||||
opus_val32 *ac, /* out: [0...lag-1] ac values */
|
||||
const opus_val16 *window,
|
||||
int overlap,
|
||||
int lag,
|
||||
int n,
|
||||
int arch
|
||||
)
|
||||
{
|
||||
opus_val32 d;
|
||||
int i, k;
|
||||
int fastN=n-lag;
|
||||
int shift;
|
||||
const opus_val16 *xptr;
|
||||
VARDECL(opus_val16, xx);
|
||||
SAVE_STACK;
|
||||
ALLOC(xx, n, opus_val16);
|
||||
celt_assert(n>0);
|
||||
celt_assert(overlap>=0);
|
||||
if (overlap == 0)
|
||||
{
|
||||
xptr = x;
|
||||
} else {
|
||||
for (i=0;i<n;i++)
|
||||
xx[i] = x[i];
|
||||
for (i=0;i<overlap;i++)
|
||||
{
|
||||
xx[i] = MULT16_16_Q15(x[i],window[i]);
|
||||
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
|
||||
}
|
||||
xptr = xx;
|
||||
}
|
||||
shift=0;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
{
|
||||
opus_val32 ac0;
|
||||
ac0 = 1+(n<<7);
|
||||
if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);
|
||||
for(i=(n&1);i<n;i+=2)
|
||||
{
|
||||
ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);
|
||||
ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);
|
||||
}
|
||||
|
||||
shift = celt_ilog2(ac0)-30+10;
|
||||
shift = (shift)/2;
|
||||
if (shift>0)
|
||||
{
|
||||
for(i=0;i<n;i++)
|
||||
xx[i] = PSHR32(xptr[i], shift);
|
||||
xptr = xx;
|
||||
} else
|
||||
shift = 0;
|
||||
}
|
||||
#endif
|
||||
celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
|
||||
for (k=0;k<=lag;k++)
|
||||
{
|
||||
for (i = k+fastN, d = 0; i < n; i++)
|
||||
d = MAC16_16(d, xptr[i], xptr[i-k]);
|
||||
ac[k] += d;
|
||||
}
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
shift = 2*shift;
|
||||
if (shift<=0)
|
||||
ac[0] += SHL32((opus_int32)1, -shift);
|
||||
if (ac[0] < 268435456)
|
||||
{
|
||||
int shift2 = 29 - EC_ILOG(ac[0]);
|
||||
for (i=0;i<=lag;i++)
|
||||
ac[i] = SHL32(ac[i], shift2);
|
||||
shift -= shift2;
|
||||
} else if (ac[0] >= 536870912)
|
||||
{
|
||||
int shift2=1;
|
||||
if (ac[0] >= 1073741824)
|
||||
shift2++;
|
||||
for (i=0;i<=lag;i++)
|
||||
ac[i] = SHR32(ac[i], shift2);
|
||||
shift += shift2;
|
||||
}
|
||||
#endif
|
||||
|
||||
RESTORE_STACK;
|
||||
return shift;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/* Copyright (c) 2009-2010 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef PLC_H
|
||||
#define PLC_H
|
||||
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/cpu_support.h"
|
||||
|
||||
#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
|
||||
#include "opus/celt/x86/celt_lpc_sse.h"
|
||||
#endif
|
||||
|
||||
#define LPC_ORDER 24
|
||||
|
||||
void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p);
|
||||
|
||||
void celt_fir_c(
|
||||
const opus_val16 *x,
|
||||
const opus_val16 *num,
|
||||
opus_val16 *y,
|
||||
int N,
|
||||
int ord,
|
||||
opus_val16 *mem,
|
||||
int arch);
|
||||
|
||||
#if !defined(OVERRIDE_CELT_FIR)
|
||||
#define celt_fir(x, num, y, N, ord, mem, arch) \
|
||||
(celt_fir_c(x, num, y, N, ord, mem, arch))
|
||||
#endif
|
||||
|
||||
void celt_iir(const opus_val32 *x,
|
||||
const opus_val16 *den,
|
||||
opus_val32 *y,
|
||||
int N,
|
||||
int ord,
|
||||
opus_val16 *mem,
|
||||
int arch);
|
||||
|
||||
int _celt_autocorr(const opus_val16 *x, opus_val32 *ac,
|
||||
const opus_val16 *window, int overlap, int lag, int n, int arch);
|
||||
|
||||
#endif /* PLC_H */
|
@ -1,70 +0,0 @@
|
||||
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||
* Copyright (c) 2013 Parrot */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CPU_SUPPORT_H
|
||||
#define CPU_SUPPORT_H
|
||||
|
||||
#include "opus/opus_types.h"
|
||||
#include "opus/opus_defines.h"
|
||||
|
||||
#if defined(OPUS_HAVE_RTCD) && \
|
||||
(defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
|
||||
#include "opus/celt/arm/armcpu.h"
|
||||
|
||||
/* We currently support 4 ARM variants:
|
||||
* arch[0] -> ARMv4
|
||||
* arch[1] -> ARMv5E
|
||||
* arch[2] -> ARMv6
|
||||
* arch[3] -> NEON
|
||||
*/
|
||||
#define OPUS_ARCHMASK 3
|
||||
|
||||
#elif (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \
|
||||
(defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \
|
||||
(defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \
|
||||
(defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX))
|
||||
|
||||
#include "opus/celt/x86/x86cpu.h"
|
||||
/* We currently support 5 x86 variants:
|
||||
* arch[0] -> non-sse
|
||||
* arch[1] -> sse
|
||||
* arch[2] -> sse2
|
||||
* arch[3] -> sse4.1
|
||||
* arch[4] -> avx
|
||||
*/
|
||||
#define OPUS_ARCHMASK 7
|
||||
int opus_select_arch(void);
|
||||
|
||||
#else
|
||||
#define OPUS_ARCHMASK 0
|
||||
|
||||
static OPUS_INLINE int opus_select_arch(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -1,712 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (c) 2007-2009 Timothy B. Terriberry
|
||||
Written by Timothy B. Terriberry and Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/cwrs.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
|
||||
/*Guaranteed to return a conservatively large estimate of the binary logarithm
|
||||
with frac bits of fractional precision.
|
||||
Tested for all possible 32-bit inputs with frac=4, where the maximum
|
||||
overestimation is 0.06254243 bits.*/
|
||||
int log2_frac(opus_uint32 val, int frac)
|
||||
{
|
||||
int l;
|
||||
l=EC_ILOG(val);
|
||||
if(val&(val-1)){
|
||||
/*This is (val>>l-16), but guaranteed to round up, even if adding a bias
|
||||
before the shift would cause overflow (e.g., for 0xFFFFxxxx).
|
||||
Doesn't work for val=0, but that case fails the test above.*/
|
||||
if(l>16)val=((val-1)>>(l-16))+1;
|
||||
else val<<=16-l;
|
||||
l=(l-1)<<frac;
|
||||
/*Note that we always need one iteration, since the rounding up above means
|
||||
that we might need to adjust the integer part of the logarithm.*/
|
||||
do{
|
||||
int b;
|
||||
b=(int)(val>>16);
|
||||
l+=b<<frac;
|
||||
val=(val+b)>>b;
|
||||
val=(val*val+0x7FFF)>>15;
|
||||
}
|
||||
while(frac-->0);
|
||||
/*If val is not exactly 0x8000, then we have to round up the remainder.*/
|
||||
return l+(val>0x8000);
|
||||
}
|
||||
/*Exact powers of two require no rounding.*/
|
||||
else return (l-1)<<frac;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Although derived separately, the pulse vector coding scheme is equivalent to
|
||||
a Pyramid Vector Quantizer \cite{Fis86}.
|
||||
Some additional notes about an early version appear at
|
||||
http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
|
||||
and the definitions of some terms have evolved since that was written.
|
||||
|
||||
The conversion from a pulse vector to an integer index (encoding) and back
|
||||
(decoding) is governed by two related functions, V(N,K) and U(N,K).
|
||||
|
||||
V(N,K) = the number of combinations, with replacement, of N items, taken K
|
||||
at a time, when a sign bit is added to each item taken at least once (i.e.,
|
||||
the number of N-dimensional unit pulse vectors with K pulses).
|
||||
One way to compute this is via
|
||||
V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1,
|
||||
where choose() is the binomial function.
|
||||
A table of values for N<10 and K<10 looks like:
|
||||
V[10][10] = {
|
||||
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
|
||||
{1, 4, 8, 12, 16, 20, 24, 28, 32, 36},
|
||||
{1, 6, 18, 38, 66, 102, 146, 198, 258, 326},
|
||||
{1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992},
|
||||
{1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290},
|
||||
{1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436},
|
||||
{1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598},
|
||||
{1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688},
|
||||
{1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146}
|
||||
};
|
||||
|
||||
U(N,K) = the number of such combinations wherein N-1 objects are taken at
|
||||
most K-1 at a time.
|
||||
This is given by
|
||||
U(N,K) = sum(k=0...K-1,V(N-1,k))
|
||||
= K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0.
|
||||
The latter expression also makes clear that U(N,K) is half the number of such
|
||||
combinations wherein the first object is taken at least once.
|
||||
Although it may not be clear from either of these definitions, U(N,K) is the
|
||||
natural function to work with when enumerating the pulse vector codebooks,
|
||||
not V(N,K).
|
||||
U(N,K) is not well-defined for N=0, but with the extension
|
||||
U(0,K) = K>0 ? 0 : 1,
|
||||
the function becomes symmetric: U(N,K) = U(K,N), with a similar table:
|
||||
U[10][10] = {
|
||||
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{0, 1, 3, 5, 7, 9, 11, 13, 15, 17},
|
||||
{0, 1, 5, 13, 25, 41, 61, 85, 113, 145},
|
||||
{0, 1, 7, 25, 63, 129, 231, 377, 575, 833},
|
||||
{0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649},
|
||||
{0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073},
|
||||
{0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081},
|
||||
{0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545},
|
||||
{0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729}
|
||||
};
|
||||
|
||||
With this extension, V(N,K) may be written in terms of U(N,K):
|
||||
V(N,K) = U(N,K) + U(N,K+1)
|
||||
for all N>=0, K>=0.
|
||||
Thus U(N,K+1) represents the number of combinations where the first element
|
||||
is positive or zero, and U(N,K) represents the number of combinations where
|
||||
it is negative.
|
||||
With a large enough table of U(N,K) values, we could write O(N) encoding
|
||||
and O(min(N*log(K),N+K)) decoding routines, but such a table would be
|
||||
prohibitively large for small embedded devices (K may be as large as 32767
|
||||
for small N, and N may be as large as 200).
|
||||
|
||||
Both functions obey the same recurrence relation:
|
||||
V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1),
|
||||
U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1),
|
||||
for all N>0, K>0, with different initial conditions at N=0 or K=0.
|
||||
This allows us to construct a row of one of the tables above given the
|
||||
previous row or the next row.
|
||||
Thus we can derive O(NK) encoding and decoding routines with O(K) memory
|
||||
using only addition and subtraction.
|
||||
|
||||
When encoding, we build up from the U(2,K) row and work our way forwards.
|
||||
When decoding, we need to start at the U(N,K) row and work our way backwards,
|
||||
which requires a means of computing U(N,K).
|
||||
U(N,K) may be computed from two previous values with the same N:
|
||||
U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2)
|
||||
for all N>1, and since U(N,K) is symmetric, a similar relation holds for two
|
||||
previous values with the same K:
|
||||
U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K)
|
||||
for all K>1.
|
||||
This allows us to construct an arbitrary row of the U(N,K) table by starting
|
||||
with the first two values, which are constants.
|
||||
This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K)
|
||||
multiplications.
|
||||
Similar relations can be derived for V(N,K), but are not used here.
|
||||
|
||||
For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree
|
||||
polynomial for fixed N.
|
||||
The first few are
|
||||
U(1,K) = 1,
|
||||
U(2,K) = 2*K-1,
|
||||
U(3,K) = (2*K-2)*K+1,
|
||||
U(4,K) = (((4*K-6)*K+8)*K-3)/3,
|
||||
U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3,
|
||||
and
|
||||
V(1,K) = 2,
|
||||
V(2,K) = 4*K,
|
||||
V(3,K) = 4*K*K+2,
|
||||
V(4,K) = 8*(K*K+2)*K/3,
|
||||
V(5,K) = ((4*K*K+20)*K*K+6)/3,
|
||||
for all K>0.
|
||||
This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for
|
||||
small N (and indeed decoding is also O(N) for N<3).
|
||||
|
||||
@ARTICLE{Fis86,
|
||||
author="Thomas R. Fischer",
|
||||
title="A Pyramid Vector Quantizer",
|
||||
journal="IEEE Transactions on Information Theory",
|
||||
volume="IT-32",
|
||||
number=4,
|
||||
pages="568--583",
|
||||
month=Jul,
|
||||
year=1986
|
||||
}*/
|
||||
|
||||
#if !defined(SMALL_FOOTPRINT)
|
||||
|
||||
/*U(N,K) = U(K,N) := N>0?K>0?U(N-1,K)+U(N,K-1)+U(N-1,K-1):0:K>0?1:0*/
|
||||
# define CELT_PVQ_U(_n,_k) (CELT_PVQ_U_ROW[IMIN(_n,_k)][IMAX(_n,_k)])
|
||||
/*V(N,K) := U(N,K)+U(N,K+1) = the number of PVQ codewords for a band of size N
|
||||
with K pulses allocated to it.*/
|
||||
# define CELT_PVQ_V(_n,_k) (CELT_PVQ_U(_n,_k)+CELT_PVQ_U(_n,(_k)+1))
|
||||
|
||||
/*For each V(N,K) supported, we will access element U(min(N,K+1),max(N,K+1)).
|
||||
Thus, the number of entries in row I is the larger of the maximum number of
|
||||
pulses we will ever allocate for a given N=I (K=128, or however many fit in
|
||||
32 bits, whichever is smaller), plus one, and the maximum N for which
|
||||
K=I-1 pulses fit in 32 bits.
|
||||
The largest band size in an Opus Custom mode is 208.
|
||||
Otherwise, we can limit things to the set of N which can be achieved by
|
||||
splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48,
|
||||
44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/
|
||||
#if defined(CUSTOM_MODES)
|
||||
static const opus_uint32 CELT_PVQ_U_DATA[1488]={
|
||||
#else
|
||||
static const opus_uint32 CELT_PVQ_U_DATA[1272]={
|
||||
#endif
|
||||
/*N=0, K=0...176:*/
|
||||
1, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...208:*/
|
||||
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
|
||||
/*N=1, K=1...176:*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...208:*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1,
|
||||
#endif
|
||||
/*N=2, K=2...176:*/
|
||||
3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,
|
||||
43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
|
||||
81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113,
|
||||
115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143,
|
||||
145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
|
||||
175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203,
|
||||
205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233,
|
||||
235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263,
|
||||
265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293,
|
||||
295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323,
|
||||
325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...208:*/
|
||||
353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381,
|
||||
383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411,
|
||||
413, 415,
|
||||
#endif
|
||||
/*N=3, K=3...176:*/
|
||||
13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613,
|
||||
685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861,
|
||||
1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785,
|
||||
3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385,
|
||||
6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661,
|
||||
9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961,
|
||||
13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745,
|
||||
17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013,
|
||||
21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765,
|
||||
26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001,
|
||||
31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721,
|
||||
37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925,
|
||||
43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613,
|
||||
50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785,
|
||||
57461, 58141, 58825, 59513, 60205, 60901, 61601,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...208:*/
|
||||
62305, 63013, 63725, 64441, 65161, 65885, 66613, 67345, 68081, 68821, 69565,
|
||||
70313, 71065, 71821, 72581, 73345, 74113, 74885, 75661, 76441, 77225, 78013,
|
||||
78805, 79601, 80401, 81205, 82013, 82825, 83641, 84461, 85285, 86113,
|
||||
#endif
|
||||
/*N=4, K=4...176:*/
|
||||
63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017,
|
||||
7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775,
|
||||
30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153,
|
||||
82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193,
|
||||
161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575,
|
||||
267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217,
|
||||
410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951,
|
||||
597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609,
|
||||
833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023,
|
||||
1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407,
|
||||
1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759,
|
||||
1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175,
|
||||
2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751,
|
||||
2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583,
|
||||
3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767,
|
||||
3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399,
|
||||
4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575,
|
||||
5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391,
|
||||
6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943,
|
||||
7085049, 7207551,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...208:*/
|
||||
7331457, 7456775, 7583513, 7711679, 7841281, 7972327, 8104825, 8238783,
|
||||
8374209, 8511111, 8649497, 8789375, 8930753, 9073639, 9218041, 9363967,
|
||||
9511425, 9660423, 9810969, 9963071, 10116737, 10271975, 10428793, 10587199,
|
||||
10747201, 10908807, 11072025, 11236863, 11403329, 11571431, 11741177,
|
||||
11912575,
|
||||
#endif
|
||||
/*N=5, K=5...176:*/
|
||||
321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041,
|
||||
50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401,
|
||||
330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241,
|
||||
1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241,
|
||||
2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801,
|
||||
4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849,
|
||||
8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849,
|
||||
13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809,
|
||||
20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881,
|
||||
29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641,
|
||||
40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081,
|
||||
55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609,
|
||||
73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049,
|
||||
95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641,
|
||||
122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041,
|
||||
155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321,
|
||||
193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969,
|
||||
238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889,
|
||||
290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401,
|
||||
351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241,
|
||||
420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561,
|
||||
500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929,
|
||||
590359041, 604167209, 618216201, 632508801,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...208:*/
|
||||
647047809, 661836041, 676876329, 692171521, 707724481, 723538089, 739615241,
|
||||
755958849, 772571841, 789457161, 806617769, 824056641, 841776769, 859781161,
|
||||
878072841, 896654849, 915530241, 934702089, 954173481, 973947521, 994027329,
|
||||
1014416041, 1035116809, 1056132801, 1077467201, 1099123209, 1121104041,
|
||||
1143412929, 1166053121, 1189027881, 1212340489, 1235994241,
|
||||
#endif
|
||||
/*N=6, K=6...96:*/
|
||||
1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047,
|
||||
335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409,
|
||||
2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793,
|
||||
11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455,
|
||||
29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189,
|
||||
64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651,
|
||||
128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185,
|
||||
235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647,
|
||||
402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229,
|
||||
655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283,
|
||||
1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135,
|
||||
1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187,
|
||||
2011371957, 2120032959,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...109:*/
|
||||
2233340609U, 2351442379U, 2474488829U, 2602633639U, 2736033641U, 2874848851U,
|
||||
3019242501U, 3169381071U, 3325434321U, 3487575323U, 3655980493U, 3830829623U,
|
||||
4012305913U,
|
||||
#endif
|
||||
/*N=7, K=7...54*/
|
||||
8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777,
|
||||
1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233,
|
||||
19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013,
|
||||
88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805,
|
||||
292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433,
|
||||
793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821,
|
||||
1667010073, 1870535785, 2094367717,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...60:*/
|
||||
2340095869U, 2609401873U, 2904062449U, 3225952925U, 3577050821U, 3959439497U,
|
||||
#endif
|
||||
/*N=8, K=8...37*/
|
||||
48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767,
|
||||
9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017,
|
||||
104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351,
|
||||
638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615,
|
||||
2229491905U,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...40:*/
|
||||
2691463695U, 3233240945U, 3866006015U,
|
||||
#endif
|
||||
/*N=9, K=9...28:*/
|
||||
265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777,
|
||||
39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145,
|
||||
628496897, 872893441, 1196924561, 1621925137, 2173806145U,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...29:*/
|
||||
2883810113U,
|
||||
#endif
|
||||
/*N=10, K=10...24:*/
|
||||
1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073,
|
||||
254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629U,
|
||||
3375210671U,
|
||||
/*N=11, K=11...19:*/
|
||||
8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585,
|
||||
948062325, 1616336765,
|
||||
#if defined(CUSTOM_MODES)
|
||||
/*...20:*/
|
||||
2684641785U,
|
||||
#endif
|
||||
/*N=12, K=12...18:*/
|
||||
45046719, 103274625, 224298231, 464387817, 921406335, 1759885185,
|
||||
3248227095U,
|
||||
/*N=13, K=13...16:*/
|
||||
251595969, 579168825, 1267854873, 2653649025U,
|
||||
/*N=14, K=14:*/
|
||||
1409933619
|
||||
};
|
||||
|
||||
#if defined(CUSTOM_MODES)
|
||||
static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
|
||||
CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415,
|
||||
CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030,
|
||||
CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389,
|
||||
CELT_PVQ_U_DATA+1421,CELT_PVQ_U_DATA+1441,CELT_PVQ_U_DATA+1455,
|
||||
CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473
|
||||
};
|
||||
#else
|
||||
static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
|
||||
CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351,
|
||||
CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870,
|
||||
CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178,
|
||||
CELT_PVQ_U_DATA+1207,CELT_PVQ_U_DATA+1226,CELT_PVQ_U_DATA+1240,
|
||||
CELT_PVQ_U_DATA+1248,CELT_PVQ_U_DATA+1254,CELT_PVQ_U_DATA+1257
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CUSTOM_MODES)
|
||||
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
|
||||
int k;
|
||||
/*_maxk==0 => there's nothing to do.*/
|
||||
celt_assert(_maxk>0);
|
||||
_bits[0]=0;
|
||||
for(k=1;k<=_maxk;k++)_bits[k]=log2_frac(CELT_PVQ_V(_n,k),_frac);
|
||||
}
|
||||
#endif
|
||||
|
||||
static opus_uint32 icwrs(int _n,const int *_y){
|
||||
opus_uint32 i;
|
||||
int j;
|
||||
int k;
|
||||
celt_assert(_n>=2);
|
||||
j=_n-1;
|
||||
i=_y[j]<0;
|
||||
k=abs(_y[j]);
|
||||
do{
|
||||
j--;
|
||||
i+=CELT_PVQ_U(_n-j,k);
|
||||
k+=abs(_y[j]);
|
||||
if(_y[j]<0)i+=CELT_PVQ_U(_n-j,k+1);
|
||||
}
|
||||
while(j>0);
|
||||
return i;
|
||||
}
|
||||
|
||||
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
|
||||
celt_assert(_k>0);
|
||||
ec_enc_uint(_enc,icwrs(_n,_y),CELT_PVQ_V(_n,_k));
|
||||
}
|
||||
|
||||
static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){
|
||||
opus_uint32 p;
|
||||
int s;
|
||||
int k0;
|
||||
opus_int16 val;
|
||||
opus_val32 yy=0;
|
||||
celt_assert(_k>0);
|
||||
celt_assert(_n>1);
|
||||
while(_n>2){
|
||||
opus_uint32 q;
|
||||
/*Lots of pulses case:*/
|
||||
if(_k>=_n){
|
||||
const opus_uint32 *row;
|
||||
row=CELT_PVQ_U_ROW[_n];
|
||||
/*Are the pulses in this dimension negative?*/
|
||||
p=row[_k+1];
|
||||
s=-(_i>=p);
|
||||
_i-=p&s;
|
||||
/*Count how many pulses were placed in this dimension.*/
|
||||
k0=_k;
|
||||
q=row[_n];
|
||||
if(q>_i){
|
||||
celt_assert(p>q);
|
||||
_k=_n;
|
||||
do p=CELT_PVQ_U_ROW[--_k][_n];
|
||||
while(p>_i);
|
||||
}
|
||||
else for(p=row[_k];p>_i;p=row[_k])_k--;
|
||||
_i-=p;
|
||||
val=(k0-_k+s)^s;
|
||||
*_y++=val;
|
||||
yy=MAC16_16(yy,val,val);
|
||||
}
|
||||
/*Lots of dimensions case:*/
|
||||
else{
|
||||
/*Are there any pulses in this dimension at all?*/
|
||||
p=CELT_PVQ_U_ROW[_k][_n];
|
||||
q=CELT_PVQ_U_ROW[_k+1][_n];
|
||||
if(p<=_i&&_i<q){
|
||||
_i-=p;
|
||||
*_y++=0;
|
||||
}
|
||||
else{
|
||||
/*Are the pulses in this dimension negative?*/
|
||||
s=-(_i>=q);
|
||||
_i-=q&s;
|
||||
/*Count how many pulses were placed in this dimension.*/
|
||||
k0=_k;
|
||||
do p=CELT_PVQ_U_ROW[--_k][_n];
|
||||
while(p>_i);
|
||||
_i-=p;
|
||||
val=(k0-_k+s)^s;
|
||||
*_y++=val;
|
||||
yy=MAC16_16(yy,val,val);
|
||||
}
|
||||
}
|
||||
_n--;
|
||||
}
|
||||
/*_n==2*/
|
||||
p=2*_k+1;
|
||||
s=-(_i>=p);
|
||||
_i-=p&s;
|
||||
k0=_k;
|
||||
_k=(_i+1)>>1;
|
||||
if(_k)_i-=2*_k-1;
|
||||
val=(k0-_k+s)^s;
|
||||
*_y++=val;
|
||||
yy=MAC16_16(yy,val,val);
|
||||
/*_n==1*/
|
||||
s=-(int)_i;
|
||||
val=(_k+s)^s;
|
||||
*_y=val;
|
||||
yy=MAC16_16(yy,val,val);
|
||||
return yy;
|
||||
}
|
||||
|
||||
opus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){
|
||||
return cwrsi(_n,_k,ec_dec_uint(_dec,CELT_PVQ_V(_n,_k)),_y);
|
||||
}
|
||||
|
||||
#else /* SMALL_FOOTPRINT */
|
||||
|
||||
/*Computes the next row/column of any recurrence that obeys the relation
|
||||
u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
|
||||
_ui0 is the base case for the new row/column.*/
|
||||
static OPUS_INLINE void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){
|
||||
opus_uint32 ui1;
|
||||
unsigned j;
|
||||
/*This do-while will overrun the array if we don't have storage for at least
|
||||
2 values.*/
|
||||
j=1; do {
|
||||
ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);
|
||||
_ui[j-1]=_ui0;
|
||||
_ui0=ui1;
|
||||
} while (++j<_len);
|
||||
_ui[j-1]=_ui0;
|
||||
}
|
||||
|
||||
/*Computes the previous row/column of any recurrence that obeys the relation
|
||||
u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].
|
||||
_ui0 is the base case for the new row/column.*/
|
||||
static OPUS_INLINE void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){
|
||||
opus_uint32 ui1;
|
||||
unsigned j;
|
||||
/*This do-while will overrun the array if we don't have storage for at least
|
||||
2 values.*/
|
||||
j=1; do {
|
||||
ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);
|
||||
_ui[j-1]=_ui0;
|
||||
_ui0=ui1;
|
||||
} while (++j<_n);
|
||||
_ui[j-1]=_ui0;
|
||||
}
|
||||
|
||||
/*Compute V(_n,_k), as well as U(_n,0..._k+1).
|
||||
_u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/
|
||||
static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){
|
||||
opus_uint32 um2;
|
||||
unsigned len;
|
||||
unsigned k;
|
||||
len=_k+2;
|
||||
/*We require storage at least 3 values (e.g., _k>0).*/
|
||||
celt_assert(len>=3);
|
||||
_u[0]=0;
|
||||
_u[1]=um2=1;
|
||||
/*If _n==0, _u[0] should be 1 and the rest should be 0.*/
|
||||
/*If _n==1, _u[i] should be 1 for i>1.*/
|
||||
celt_assert(_n>=2);
|
||||
/*If _k==0, the following do-while loop will overflow the buffer.*/
|
||||
celt_assert(_k>0);
|
||||
k=2;
|
||||
do _u[k]=(k<<1)-1;
|
||||
while(++k<len);
|
||||
for(k=2;k<_n;k++)unext(_u+1,_k+1,1);
|
||||
return _u[_k]+_u[_k+1];
|
||||
}
|
||||
|
||||
/*Returns the _i'th combination of _k elements chosen from a set of size _n
|
||||
with associated sign bits.
|
||||
_y: Returns the vector of pulses.
|
||||
_u: Must contain entries [0..._k+1] of row _n of U() on input.
|
||||
Its contents will be destructively modified.*/
|
||||
static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){
|
||||
int j;
|
||||
opus_int16 val;
|
||||
opus_val32 yy=0;
|
||||
celt_assert(_n>0);
|
||||
j=0;
|
||||
do{
|
||||
opus_uint32 p;
|
||||
int s;
|
||||
int yj;
|
||||
p=_u[_k+1];
|
||||
s=-(_i>=p);
|
||||
_i-=p&s;
|
||||
yj=_k;
|
||||
p=_u[_k];
|
||||
while(p>_i)p=_u[--_k];
|
||||
_i-=p;
|
||||
yj-=_k;
|
||||
val=(yj+s)^s;
|
||||
_y[j]=val;
|
||||
yy=MAC16_16(yy,val,val);
|
||||
uprev(_u,_k+2,0);
|
||||
}
|
||||
while(++j<_n);
|
||||
return yy;
|
||||
}
|
||||
|
||||
/*Returns the index of the given combination of K elements chosen from a set
|
||||
of size 1 with associated sign bits.
|
||||
_y: The vector of pulses, whose sum of absolute values is K.
|
||||
_k: Returns K.*/
|
||||
static OPUS_INLINE opus_uint32 icwrs1(const int *_y,int *_k){
|
||||
*_k=abs(_y[0]);
|
||||
return _y[0]<0;
|
||||
}
|
||||
|
||||
/*Returns the index of the given combination of K elements chosen from a set
|
||||
of size _n with associated sign bits.
|
||||
_y: The vector of pulses, whose sum of absolute values must be _k.
|
||||
_nc: Returns V(_n,_k).*/
|
||||
static OPUS_INLINE opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y,
|
||||
opus_uint32 *_u){
|
||||
opus_uint32 i;
|
||||
int j;
|
||||
int k;
|
||||
/*We can't unroll the first two iterations of the loop unless _n>=2.*/
|
||||
celt_assert(_n>=2);
|
||||
_u[0]=0;
|
||||
for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1;
|
||||
i=icwrs1(_y+_n-1,&k);
|
||||
j=_n-2;
|
||||
i+=_u[k];
|
||||
k+=abs(_y[j]);
|
||||
if(_y[j]<0)i+=_u[k+1];
|
||||
while(j-->0){
|
||||
unext(_u,_k+2,0);
|
||||
i+=_u[k];
|
||||
k+=abs(_y[j]);
|
||||
if(_y[j]<0)i+=_u[k+1];
|
||||
}
|
||||
*_nc=_u[k]+_u[k+1];
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
|
||||
int k;
|
||||
/*_maxk==0 => there's nothing to do.*/
|
||||
celt_assert(_maxk>0);
|
||||
_bits[0]=0;
|
||||
if (_n==1)
|
||||
{
|
||||
for (k=1;k<=_maxk;k++)
|
||||
_bits[k] = 1<<_frac;
|
||||
}
|
||||
else {
|
||||
VARDECL(opus_uint32,u);
|
||||
SAVE_STACK;
|
||||
ALLOC(u,_maxk+2U,opus_uint32);
|
||||
ncwrs_urow(_n,_maxk,u);
|
||||
for(k=1;k<=_maxk;k++)
|
||||
_bits[k]=log2_frac(u[k]+u[k+1],_frac);
|
||||
RESTORE_STACK;
|
||||
}
|
||||
}
|
||||
#endif /* CUSTOM_MODES */
|
||||
|
||||
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
|
||||
opus_uint32 i;
|
||||
VARDECL(opus_uint32,u);
|
||||
opus_uint32 nc;
|
||||
SAVE_STACK;
|
||||
celt_assert(_k>0);
|
||||
ALLOC(u,_k+2U,opus_uint32);
|
||||
i=icwrs(_n,_k,&nc,_y,u);
|
||||
ec_enc_uint(_enc,i,nc);
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
opus_val32 decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){
|
||||
VARDECL(opus_uint32,u);
|
||||
int ret;
|
||||
SAVE_STACK;
|
||||
celt_assert(_k>0);
|
||||
ALLOC(u,_k+2U,opus_uint32);
|
||||
ret = cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u);
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* SMALL_FOOTPRINT */
|
@ -1,48 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (c) 2007-2009 Timothy B. Terriberry
|
||||
Written by Timothy B. Terriberry and Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CWRS_H
|
||||
#define CWRS_H
|
||||
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
#include "opus/celt/entenc.h"
|
||||
#include "opus/celt/entdec.h"
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
int log2_frac(opus_uint32 val, int frac);
|
||||
#endif
|
||||
|
||||
void get_required_bits(opus_int16 *bits, int N, int K, int frac);
|
||||
|
||||
void encode_pulses(const int *_y, int N, int K, ec_enc *enc);
|
||||
|
||||
opus_val32 decode_pulses(int *_y, int N, int K, ec_dec *dec);
|
||||
|
||||
#endif /* CWRS_H */
|
@ -1,87 +0,0 @@
|
||||
/* Copyright (c) 2003-2008 Timothy B. Terriberry
|
||||
Copyright (c) 2008 Xiph.Org Foundation */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*Some common macros for potential platform-specific optimization.*/
|
||||
#include "opus/opus_types.h"
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include "opus/celt/arch.h"
|
||||
#if !defined(_ecintrin_H)
|
||||
# define _ecintrin_H (1)
|
||||
|
||||
/*Some specific platforms may have optimized intrinsic or OPUS_INLINE assembly
|
||||
versions of these functions which can substantially improve performance.
|
||||
We define macros for them to allow easy incorporation of these non-ANSI
|
||||
features.*/
|
||||
|
||||
/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if
|
||||
given an appropriate architecture, but the branchless bit-twiddling versions
|
||||
are just as fast, and do not require any special target architecture.
|
||||
Earlier gcc versions (3.x) compiled both code to the same assembly
|
||||
instructions, because of the way they represented ((_b)>(_a)) internally.*/
|
||||
# define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a))))
|
||||
|
||||
/*Count leading zeros.
|
||||
This macro should only be used for implementing ec_ilog(), if it is defined.
|
||||
All other code should use EC_ILOG() instead.*/
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
# include <intrin.h>
|
||||
/*In _DEBUG mode this is not an intrinsic by default.*/
|
||||
# pragma intrinsic(_BitScanReverse)
|
||||
|
||||
static __inline int ec_bsr(unsigned long _x){
|
||||
unsigned long ret;
|
||||
_BitScanReverse(&ret,_x);
|
||||
return (int)ret;
|
||||
}
|
||||
# define EC_CLZ0 (1)
|
||||
# define EC_CLZ(_x) (-ec_bsr(_x))
|
||||
#elif defined(ENABLE_TI_DSPLIB)
|
||||
# include "dsplib.h"
|
||||
# define EC_CLZ0 (31)
|
||||
# define EC_CLZ(_x) (_lnorm(_x))
|
||||
#elif __GNUC_PREREQ(3,4)
|
||||
# if INT_MAX>=2147483647
|
||||
# define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT)
|
||||
# define EC_CLZ(_x) (__builtin_clz(_x))
|
||||
# elif LONG_MAX>=2147483647L
|
||||
# define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT)
|
||||
# define EC_CLZ(_x) (__builtin_clzl(_x))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(EC_CLZ)
|
||||
/*Note that __builtin_clz is not defined when _x==0, according to the gcc
|
||||
documentation (and that of the BSR instruction that implements it on x86).
|
||||
The majority of the time we can never pass it zero.
|
||||
When we need to, it can be special cased.*/
|
||||
# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x))
|
||||
#else
|
||||
int ec_ilog(opus_uint32 _v);
|
||||
# define EC_ILOG(_x) (ec_ilog(_x))
|
||||
#endif
|
||||
#endif
|
@ -1,150 +0,0 @@
|
||||
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/entcode.h"
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
#if !defined(EC_CLZ)
|
||||
/*This is a fallback for systems where we don't know how to access
|
||||
a BSR or CLZ instruction (see ecintrin.h).
|
||||
If you are optimizing Opus on a new platform and it has a native CLZ or
|
||||
BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be
|
||||
an easy performance win.*/
|
||||
int ec_ilog(opus_uint32 _v){
|
||||
/*On a Pentium M, this branchless version tested as the fastest on
|
||||
1,000,000,000 random 32-bit integers, edging out a similar version with
|
||||
branches, and a 256-entry LUT version.*/
|
||||
int ret;
|
||||
int m;
|
||||
ret=!!_v;
|
||||
m=!!(_v&0xFFFF0000)<<4;
|
||||
_v>>=m;
|
||||
ret|=m;
|
||||
m=!!(_v&0xFF00)<<3;
|
||||
_v>>=m;
|
||||
ret|=m;
|
||||
m=!!(_v&0xF0)<<2;
|
||||
_v>>=m;
|
||||
ret|=m;
|
||||
m=!!(_v&0xC)<<1;
|
||||
_v>>=m;
|
||||
ret|=m;
|
||||
ret+=!!(_v&0x2);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/* This is a faster version of ec_tell_frac() that takes advantage
|
||||
of the low (1/8 bit) resolution to use just a linear function
|
||||
followed by a lookup to determine the exact transition thresholds. */
|
||||
opus_uint32 ec_tell_frac(ec_ctx *_this){
|
||||
static const unsigned correction[8] =
|
||||
{35733, 38967, 42495, 46340,
|
||||
50535, 55109, 60097, 65535};
|
||||
opus_uint32 nbits;
|
||||
opus_uint32 r;
|
||||
int l;
|
||||
unsigned b;
|
||||
nbits=_this->nbits_total<<BITRES;
|
||||
l=EC_ILOG(_this->rng);
|
||||
r=_this->rng>>(l-16);
|
||||
b = (r>>12)-8;
|
||||
b += r>correction[b];
|
||||
l = (l<<3)+b;
|
||||
return nbits-l;
|
||||
}
|
||||
#else
|
||||
opus_uint32 ec_tell_frac(ec_ctx *_this){
|
||||
opus_uint32 nbits;
|
||||
opus_uint32 r;
|
||||
int l;
|
||||
int i;
|
||||
/*To handle the non-integral number of bits still left in the encoder/decoder
|
||||
state, we compute the worst-case number of bits of val that must be
|
||||
encoded to ensure that the value is inside the range for any possible
|
||||
subsequent bits.
|
||||
The computation here is independent of val itself (the decoder does not
|
||||
even track that value), even though the real number of bits used after
|
||||
ec_enc_done() may be 1 smaller if rng is a power of two and the
|
||||
corresponding trailing bits of val are all zeros.
|
||||
If we did try to track that special case, then coding a value with a
|
||||
probability of 1/(1<<n) might sometimes appear to use more than n bits.
|
||||
This may help explain the surprising result that a newly initialized
|
||||
encoder or decoder claims to have used 1 bit.*/
|
||||
nbits=_this->nbits_total<<BITRES;
|
||||
l=EC_ILOG(_this->rng);
|
||||
r=_this->rng>>(l-16);
|
||||
for(i=BITRES;i-->0;){
|
||||
int b;
|
||||
r=r*r>>15;
|
||||
b=(int)(r>>16);
|
||||
l=l<<1|b;
|
||||
r>>=b;
|
||||
}
|
||||
return nbits-l;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SMALL_DIV_TABLE
|
||||
/* Result of 2^32/(2*i+1), except for i=0. */
|
||||
const opus_uint32 SMALL_DIV_TABLE[129] = {
|
||||
0xFFFFFFFF, 0x55555555, 0x33333333, 0x24924924,
|
||||
0x1C71C71C, 0x1745D174, 0x13B13B13, 0x11111111,
|
||||
0x0F0F0F0F, 0x0D79435E, 0x0C30C30C, 0x0B21642C,
|
||||
0x0A3D70A3, 0x097B425E, 0x08D3DCB0, 0x08421084,
|
||||
0x07C1F07C, 0x07507507, 0x06EB3E45, 0x06906906,
|
||||
0x063E7063, 0x05F417D0, 0x05B05B05, 0x0572620A,
|
||||
0x05397829, 0x05050505, 0x04D4873E, 0x04A7904A,
|
||||
0x047DC11F, 0x0456C797, 0x04325C53, 0x04104104,
|
||||
0x03F03F03, 0x03D22635, 0x03B5CC0E, 0x039B0AD1,
|
||||
0x0381C0E0, 0x0369D036, 0x03531DEC, 0x033D91D2,
|
||||
0x0329161F, 0x03159721, 0x03030303, 0x02F14990,
|
||||
0x02E05C0B, 0x02D02D02, 0x02C0B02C, 0x02B1DA46,
|
||||
0x02A3A0FD, 0x0295FAD4, 0x0288DF0C, 0x027C4597,
|
||||
0x02702702, 0x02647C69, 0x02593F69, 0x024E6A17,
|
||||
0x0243F6F0, 0x0239E0D5, 0x02302302, 0x0226B902,
|
||||
0x021D9EAD, 0x0214D021, 0x020C49BA, 0x02040810,
|
||||
0x01FC07F0, 0x01F44659, 0x01ECC07B, 0x01E573AC,
|
||||
0x01DE5D6E, 0x01D77B65, 0x01D0CB58, 0x01CA4B30,
|
||||
0x01C3F8F0, 0x01BDD2B8, 0x01B7D6C3, 0x01B20364,
|
||||
0x01AC5701, 0x01A6D01A, 0x01A16D3F, 0x019C2D14,
|
||||
0x01970E4F, 0x01920FB4, 0x018D3018, 0x01886E5F,
|
||||
0x0183C977, 0x017F405F, 0x017AD220, 0x01767DCE,
|
||||
0x01724287, 0x016E1F76, 0x016A13CD, 0x01661EC6,
|
||||
0x01623FA7, 0x015E75BB, 0x015AC056, 0x01571ED3,
|
||||
0x01539094, 0x01501501, 0x014CAB88, 0x0149539E,
|
||||
0x01460CBC, 0x0142D662, 0x013FB013, 0x013C995A,
|
||||
0x013991C2, 0x013698DF, 0x0133AE45, 0x0130D190,
|
||||
0x012E025C, 0x012B404A, 0x01288B01, 0x0125E227,
|
||||
0x01234567, 0x0120B470, 0x011E2EF3, 0x011BB4A4,
|
||||
0x01194538, 0x0116E068, 0x011485F0, 0x0112358E,
|
||||
0x010FEF01, 0x010DB20A, 0x010B7E6E, 0x010953F3,
|
||||
0x01073260, 0x0105197F, 0x0103091B, 0x01010101
|
||||
};
|
||||
#endif
|
@ -1,152 +0,0 @@
|
||||
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "opus/opus_types.h"
|
||||
#include "opus/opus_defines.h"
|
||||
|
||||
#if !defined(_entcode_H)
|
||||
# define _entcode_H (1)
|
||||
# include <limits.h>
|
||||
# include <stddef.h>
|
||||
# include "opus/celt/ecintrin.h"
|
||||
|
||||
extern const opus_uint32 SMALL_DIV_TABLE[129];
|
||||
|
||||
#ifdef OPUS_ARM_ASM
|
||||
#define USE_SMALL_DIV_TABLE
|
||||
#endif
|
||||
|
||||
/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a
|
||||
larger type, you can speed up the decoder by using it here.*/
|
||||
typedef opus_uint32 ec_window;
|
||||
typedef struct ec_ctx ec_ctx;
|
||||
typedef struct ec_ctx ec_enc;
|
||||
typedef struct ec_ctx ec_dec;
|
||||
|
||||
# define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT)
|
||||
|
||||
/*The number of bits to use for the range-coded part of unsigned integers.*/
|
||||
# define EC_UINT_BITS (8)
|
||||
|
||||
/*The resolution of fractional-precision bit usage measurements, i.e.,
|
||||
3 => 1/8th bits.*/
|
||||
# define BITRES 3
|
||||
|
||||
/*The entropy encoder/decoder context.
|
||||
We use the same structure for both, so that common functions like ec_tell()
|
||||
can be used on either one.*/
|
||||
struct ec_ctx{
|
||||
/*Buffered input/output.*/
|
||||
unsigned char *buf;
|
||||
/*The size of the buffer.*/
|
||||
opus_uint32 storage;
|
||||
/*The offset at which the last byte containing raw bits was read/written.*/
|
||||
opus_uint32 end_offs;
|
||||
/*Bits that will be read from/written at the end.*/
|
||||
ec_window end_window;
|
||||
/*Number of valid bits in end_window.*/
|
||||
int nend_bits;
|
||||
/*The total number of whole bits read/written.
|
||||
This does not include partial bits currently in the range coder.*/
|
||||
int nbits_total;
|
||||
/*The offset at which the next range coder byte will be read/written.*/
|
||||
opus_uint32 offs;
|
||||
/*The number of values in the current range.*/
|
||||
opus_uint32 rng;
|
||||
/*In the decoder: the difference between the top of the current range and
|
||||
the input value, minus one.
|
||||
In the encoder: the low end of the current range.*/
|
||||
opus_uint32 val;
|
||||
/*In the decoder: the saved normalization factor from ec_decode().
|
||||
In the encoder: the number of oustanding carry propagating symbols.*/
|
||||
opus_uint32 ext;
|
||||
/*A buffered input/output symbol, awaiting carry propagation.*/
|
||||
int rem;
|
||||
/*Nonzero if an error occurred.*/
|
||||
int error;
|
||||
};
|
||||
|
||||
static OPUS_INLINE opus_uint32 ec_range_bytes(ec_ctx *_this){
|
||||
return _this->offs;
|
||||
}
|
||||
|
||||
static OPUS_INLINE unsigned char *ec_get_buffer(ec_ctx *_this){
|
||||
return _this->buf;
|
||||
}
|
||||
|
||||
static OPUS_INLINE int ec_get_error(ec_ctx *_this){
|
||||
return _this->error;
|
||||
}
|
||||
|
||||
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
|
||||
This same number can be computed in either the encoder or the decoder, and is
|
||||
suitable for making coding decisions.
|
||||
Return: The number of bits.
|
||||
This will always be slightly larger than the exact value (e.g., all
|
||||
rounding error is in the positive direction).*/
|
||||
static OPUS_INLINE int ec_tell(ec_ctx *_this){
|
||||
return _this->nbits_total-EC_ILOG(_this->rng);
|
||||
}
|
||||
|
||||
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
|
||||
This same number can be computed in either the encoder or the decoder, and is
|
||||
suitable for making coding decisions.
|
||||
Return: The number of bits scaled by 2**BITRES.
|
||||
This will always be slightly larger than the exact value (e.g., all
|
||||
rounding error is in the positive direction).*/
|
||||
opus_uint32 ec_tell_frac(ec_ctx *_this);
|
||||
|
||||
/* Tested exhaustively for all n and for 1<=d<=256 */
|
||||
static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {
|
||||
celt_assert(d>0);
|
||||
#ifdef USE_SMALL_DIV_TABLE
|
||||
if (d>256)
|
||||
return n/d;
|
||||
else {
|
||||
opus_uint32 t, q;
|
||||
t = EC_ILOG(d&-d);
|
||||
q = (opus_uint64)SMALL_DIV_TABLE[d>>t]*(n>>(t-1))>>32;
|
||||
return q+(n-q*d >= d);
|
||||
}
|
||||
#else
|
||||
return n/d;
|
||||
#endif
|
||||
}
|
||||
|
||||
static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) {
|
||||
celt_assert(d>0);
|
||||
#ifdef USE_SMALL_DIV_TABLE
|
||||
if (n<0)
|
||||
return -(opus_int32)celt_udiv(-n, d);
|
||||
else
|
||||
return celt_udiv(n, d);
|
||||
#else
|
||||
return n/d;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -1,242 +0,0 @@
|
||||
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/entdec.h"
|
||||
#include "opus/celt/mfrngcod.h"
|
||||
|
||||
/*A range decoder.
|
||||
This is an entropy decoder based upon \cite{Mar79}, which is itself a
|
||||
rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}.
|
||||
It is very similar to arithmetic encoding, except that encoding is done with
|
||||
digits in any base, instead of with bits, and so it is faster when using
|
||||
larger bases (i.e.: a byte).
|
||||
The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$
|
||||
is the base, longer than the theoretical optimum, but to my knowledge there
|
||||
is no published justification for this claim.
|
||||
This only seems true when using near-infinite precision arithmetic so that
|
||||
the process is carried out with no rounding errors.
|
||||
|
||||
An excellent description of implementation details is available at
|
||||
http://www.arturocampos.com/ac_range.html
|
||||
A recent work \cite{MNW98} which proposes several changes to arithmetic
|
||||
encoding for efficiency actually re-discovers many of the principles
|
||||
behind range encoding, and presents a good theoretical analysis of them.
|
||||
|
||||
End of stream is handled by writing out the smallest number of bits that
|
||||
ensures that the stream will be correctly decoded regardless of the value of
|
||||
any subsequent bits.
|
||||
ec_tell() can be used to determine how many bits were needed to decode
|
||||
all the symbols thus far; other data can be packed in the remaining bits of
|
||||
the input buffer.
|
||||
@PHDTHESIS{Pas76,
|
||||
author="Richard Clark Pasco",
|
||||
title="Source coding algorithms for fast data compression",
|
||||
school="Dept. of Electrical Engineering, Stanford University",
|
||||
address="Stanford, CA",
|
||||
month=May,
|
||||
year=1976
|
||||
}
|
||||
@INPROCEEDINGS{Mar79,
|
||||
author="Martin, G.N.N.",
|
||||
title="Range encoding: an algorithm for removing redundancy from a digitised
|
||||
message",
|
||||
booktitle="Video & Data Recording Conference",
|
||||
year=1979,
|
||||
address="Southampton",
|
||||
month=Jul
|
||||
}
|
||||
@ARTICLE{MNW98,
|
||||
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
||||
title="Arithmetic Coding Revisited",
|
||||
journal="{ACM} Transactions on Information Systems",
|
||||
year=1998,
|
||||
volume=16,
|
||||
number=3,
|
||||
pages="256--294",
|
||||
month=Jul,
|
||||
URL="http://www.stanford.edu/class/ee398a/handouts/papers/Moffat98ArithmCoding.pdf"
|
||||
}*/
|
||||
|
||||
static int ec_read_byte(ec_dec *_this){
|
||||
return _this->offs<_this->storage?_this->buf[_this->offs++]:0;
|
||||
}
|
||||
|
||||
static int ec_read_byte_from_end(ec_dec *_this){
|
||||
return _this->end_offs<_this->storage?
|
||||
_this->buf[_this->storage-++(_this->end_offs)]:0;
|
||||
}
|
||||
|
||||
/*Normalizes the contents of val and rng so that rng lies entirely in the
|
||||
high-order symbol.*/
|
||||
static void ec_dec_normalize(ec_dec *_this){
|
||||
/*If the range is too small, rescale it and input some bits.*/
|
||||
while(_this->rng<=EC_CODE_BOT){
|
||||
int sym;
|
||||
_this->nbits_total+=EC_SYM_BITS;
|
||||
_this->rng<<=EC_SYM_BITS;
|
||||
/*Use up the remaining bits from our last symbol.*/
|
||||
sym=_this->rem;
|
||||
/*Read the next value from the input.*/
|
||||
_this->rem=ec_read_byte(_this);
|
||||
/*Take the rest of the bits we need from this new symbol.*/
|
||||
sym=(sym<<EC_SYM_BITS|_this->rem)>>(EC_SYM_BITS-EC_CODE_EXTRA);
|
||||
/*And subtract them from val, capped to be less than EC_CODE_TOP.*/
|
||||
_this->val=((_this->val<<EC_SYM_BITS)+(EC_SYM_MAX&~sym))&(EC_CODE_TOP-1);
|
||||
}
|
||||
}
|
||||
|
||||
void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage){
|
||||
_this->buf=_buf;
|
||||
_this->storage=_storage;
|
||||
_this->end_offs=0;
|
||||
_this->end_window=0;
|
||||
_this->nend_bits=0;
|
||||
/*This is the offset from which ec_tell() will subtract partial bits.
|
||||
The final value after the ec_dec_normalize() call will be the same as in
|
||||
the encoder, but we have to compensate for the bits that are added there.*/
|
||||
_this->nbits_total=EC_CODE_BITS+1
|
||||
-((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS;
|
||||
_this->offs=0;
|
||||
_this->rng=1U<<EC_CODE_EXTRA;
|
||||
_this->rem=ec_read_byte(_this);
|
||||
_this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA));
|
||||
_this->error=0;
|
||||
/*Normalize the interval.*/
|
||||
ec_dec_normalize(_this);
|
||||
}
|
||||
|
||||
unsigned ec_decode(ec_dec *_this,unsigned _ft){
|
||||
unsigned s;
|
||||
_this->ext=celt_udiv(_this->rng,_ft);
|
||||
s=(unsigned)(_this->val/_this->ext);
|
||||
return _ft-EC_MINI(s+1,_ft);
|
||||
}
|
||||
|
||||
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
|
||||
unsigned s;
|
||||
_this->ext=_this->rng>>_bits;
|
||||
s=(unsigned)(_this->val/_this->ext);
|
||||
return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits);
|
||||
}
|
||||
|
||||
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
|
||||
opus_uint32 s;
|
||||
s=IMUL32(_this->ext,_ft-_fh);
|
||||
_this->val-=s;
|
||||
_this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s;
|
||||
ec_dec_normalize(_this);
|
||||
}
|
||||
|
||||
/*The probability of having a "one" is 1/(1<<_logp).*/
|
||||
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){
|
||||
opus_uint32 r;
|
||||
opus_uint32 d;
|
||||
opus_uint32 s;
|
||||
int ret;
|
||||
r=_this->rng;
|
||||
d=_this->val;
|
||||
s=r>>_logp;
|
||||
ret=d<s;
|
||||
if(!ret)_this->val=d-s;
|
||||
_this->rng=ret?s:r-s;
|
||||
ec_dec_normalize(_this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){
|
||||
opus_uint32 r;
|
||||
opus_uint32 d;
|
||||
opus_uint32 s;
|
||||
opus_uint32 t;
|
||||
int ret;
|
||||
s=_this->rng;
|
||||
d=_this->val;
|
||||
r=s>>_ftb;
|
||||
ret=-1;
|
||||
do{
|
||||
t=s;
|
||||
s=IMUL32(r,_icdf[++ret]);
|
||||
}
|
||||
while(d<s);
|
||||
_this->val=d-s;
|
||||
_this->rng=t-s;
|
||||
ec_dec_normalize(_this);
|
||||
return ret;
|
||||
}
|
||||
|
||||
opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){
|
||||
unsigned ft;
|
||||
unsigned s;
|
||||
int ftb;
|
||||
/*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
|
||||
celt_assert(_ft>1);
|
||||
_ft--;
|
||||
ftb=EC_ILOG(_ft);
|
||||
if(ftb>EC_UINT_BITS){
|
||||
opus_uint32 t;
|
||||
ftb-=EC_UINT_BITS;
|
||||
ft=(unsigned)(_ft>>ftb)+1;
|
||||
s=ec_decode(_this,ft);
|
||||
ec_dec_update(_this,s,s+1,ft);
|
||||
t=(opus_uint32)s<<ftb|ec_dec_bits(_this,ftb);
|
||||
if(t<=_ft)return t;
|
||||
_this->error=1;
|
||||
return _ft;
|
||||
}
|
||||
else{
|
||||
_ft++;
|
||||
s=ec_decode(_this,(unsigned)_ft);
|
||||
ec_dec_update(_this,s,s+1,(unsigned)_ft);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){
|
||||
ec_window window;
|
||||
int available;
|
||||
opus_uint32 ret;
|
||||
window=_this->end_window;
|
||||
available=_this->nend_bits;
|
||||
if((unsigned)available<_bits){
|
||||
do{
|
||||
window|=(ec_window)ec_read_byte_from_end(_this)<<available;
|
||||
available+=EC_SYM_BITS;
|
||||
}
|
||||
while(available<=EC_WINDOW_SIZE-EC_SYM_BITS);
|
||||
}
|
||||
ret=(opus_uint32)window&(((opus_uint32)1<<_bits)-1U);
|
||||
window>>=_bits;
|
||||
available-=_bits;
|
||||
_this->end_window=window;
|
||||
_this->nend_bits=available;
|
||||
_this->nbits_total+=_bits;
|
||||
return ret;
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(_entdec_H)
|
||||
# define _entdec_H (1)
|
||||
# include <limits.h>
|
||||
# include "opus/celt/entcode.h"
|
||||
|
||||
/*Initializes the decoder.
|
||||
_buf: The input buffer to use.
|
||||
Return: 0 on success, or a negative value on error.*/
|
||||
void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage);
|
||||
|
||||
/*Calculates the cumulative frequency for the next symbol.
|
||||
This can then be fed into the probability model to determine what that
|
||||
symbol is, and the additional frequency information required to advance to
|
||||
the next symbol.
|
||||
This function cannot be called more than once without a corresponding call to
|
||||
ec_dec_update(), or decoding will not proceed correctly.
|
||||
_ft: The total frequency of the symbols in the alphabet the next symbol was
|
||||
encoded with.
|
||||
Return: A cumulative frequency representing the encoded symbol.
|
||||
If the cumulative frequency of all the symbols before the one that
|
||||
was encoded was fl, and the cumulative frequency of all the symbols
|
||||
up to and including the one encoded is fh, then the returned value
|
||||
will fall in the range [fl,fh).*/
|
||||
unsigned ec_decode(ec_dec *_this,unsigned _ft);
|
||||
|
||||
/*Equivalent to ec_decode() with _ft==1<<_bits.*/
|
||||
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits);
|
||||
|
||||
/*Advance the decoder past the next symbol using the frequency information the
|
||||
symbol was encoded with.
|
||||
Exactly one call to ec_decode() must have been made so that all necessary
|
||||
intermediate calculations are performed.
|
||||
_fl: The cumulative frequency of all symbols that come before the symbol
|
||||
decoded.
|
||||
_fh: The cumulative frequency of all symbols up to and including the symbol
|
||||
decoded.
|
||||
Together with _fl, this defines the range [_fl,_fh) in which the value
|
||||
returned above must fall.
|
||||
_ft: The total frequency of the symbols in the alphabet the symbol decoded
|
||||
was encoded in.
|
||||
This must be the same as passed to the preceding call to ec_decode().*/
|
||||
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft);
|
||||
|
||||
/* Decode a bit that has a 1/(1<<_logp) probability of being a one */
|
||||
int ec_dec_bit_logp(ec_dec *_this,unsigned _logp);
|
||||
|
||||
/*Decodes a symbol given an "inverse" CDF table.
|
||||
No call to ec_dec_update() is necessary after this call.
|
||||
_icdf: The "inverse" CDF, such that symbol s falls in the range
|
||||
[s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb.
|
||||
The values must be monotonically non-increasing, and the last value
|
||||
must be 0.
|
||||
_ftb: The number of bits of precision in the cumulative distribution.
|
||||
Return: The decoded symbol s.*/
|
||||
int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
|
||||
|
||||
/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream.
|
||||
The bits must have been encoded with ec_enc_uint().
|
||||
No call to ec_dec_update() is necessary after this call.
|
||||
_ft: The number of integers that can be decoded (one more than the max).
|
||||
This must be at least one, and no more than 2**32-1.
|
||||
Return: The decoded bits.*/
|
||||
opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);
|
||||
|
||||
/*Extracts a sequence of raw bits from the stream.
|
||||
The bits must have been encoded with ec_enc_bits().
|
||||
No call to ec_dec_update() is necessary after this call.
|
||||
_ftb: The number of bits to extract.
|
||||
This must be between 0 and 25, inclusive.
|
||||
Return: The decoded bits.*/
|
||||
opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb);
|
||||
|
||||
#endif
|
@ -1,291 +0,0 @@
|
||||
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/entenc.h"
|
||||
#include "opus/celt/mfrngcod.h"
|
||||
|
||||
/*A range encoder.
|
||||
See entdec.c and the references for implementation details \cite{Mar79,MNW98}.
|
||||
|
||||
@INPROCEEDINGS{Mar79,
|
||||
author="Martin, G.N.N.",
|
||||
title="Range encoding: an algorithm for removing redundancy from a digitised
|
||||
message",
|
||||
booktitle="Video \& Data Recording Conference",
|
||||
year=1979,
|
||||
address="Southampton",
|
||||
month=Jul
|
||||
}
|
||||
@ARTICLE{MNW98,
|
||||
author="Alistair Moffat and Radford Neal and Ian H. Witten",
|
||||
title="Arithmetic Coding Revisited",
|
||||
journal="{ACM} Transactions on Information Systems",
|
||||
year=1998,
|
||||
volume=16,
|
||||
number=3,
|
||||
pages="256--294",
|
||||
month=Jul,
|
||||
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
|
||||
}*/
|
||||
|
||||
static int ec_write_byte(ec_enc *_this,unsigned _value){
|
||||
if(_this->offs+_this->end_offs>=_this->storage)return -1;
|
||||
_this->buf[_this->offs++]=(unsigned char)_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){
|
||||
if(_this->offs+_this->end_offs>=_this->storage)return -1;
|
||||
_this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Outputs a symbol, with a carry bit.
|
||||
If there is a potential to propagate a carry over several symbols, they are
|
||||
buffered until it can be determined whether or not an actual carry will
|
||||
occur.
|
||||
If the counter for the buffered symbols overflows, then the stream becomes
|
||||
undecodable.
|
||||
This gives a theoretical limit of a few billion symbols in a single packet on
|
||||
32-bit systems.
|
||||
The alternative is to truncate the range in order to force a carry, but
|
||||
requires similar carry tracking in the decoder, needlessly slowing it down.*/
|
||||
static void ec_enc_carry_out(ec_enc *_this,int _c){
|
||||
if(_c!=EC_SYM_MAX){
|
||||
/*No further carry propagation possible, flush buffer.*/
|
||||
int carry;
|
||||
carry=_c>>EC_SYM_BITS;
|
||||
/*Don't output a byte on the first write.
|
||||
This compare should be taken care of by branch-prediction thereafter.*/
|
||||
if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry);
|
||||
if(_this->ext>0){
|
||||
unsigned sym;
|
||||
sym=(EC_SYM_MAX+carry)&EC_SYM_MAX;
|
||||
do _this->error|=ec_write_byte(_this,sym);
|
||||
while(--(_this->ext)>0);
|
||||
}
|
||||
_this->rem=_c&EC_SYM_MAX;
|
||||
}
|
||||
else _this->ext++;
|
||||
}
|
||||
|
||||
static OPUS_INLINE void ec_enc_normalize(ec_enc *_this){
|
||||
/*If the range is too small, output some bits and rescale it.*/
|
||||
while(_this->rng<=EC_CODE_BOT){
|
||||
ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT));
|
||||
/*Move the next-to-high-order symbol into the high-order position.*/
|
||||
_this->val=(_this->val<<EC_SYM_BITS)&(EC_CODE_TOP-1);
|
||||
_this->rng<<=EC_SYM_BITS;
|
||||
_this->nbits_total+=EC_SYM_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){
|
||||
_this->buf=_buf;
|
||||
_this->end_offs=0;
|
||||
_this->end_window=0;
|
||||
_this->nend_bits=0;
|
||||
/*This is the offset from which ec_tell() will subtract partial bits.*/
|
||||
_this->nbits_total=EC_CODE_BITS+1;
|
||||
_this->offs=0;
|
||||
_this->rng=EC_CODE_TOP;
|
||||
_this->rem=-1;
|
||||
_this->val=0;
|
||||
_this->ext=0;
|
||||
_this->storage=_size;
|
||||
_this->error=0;
|
||||
}
|
||||
|
||||
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
|
||||
opus_uint32 r;
|
||||
r=celt_udiv(_this->rng,_ft);
|
||||
if(_fl>0){
|
||||
_this->val+=_this->rng-IMUL32(r,(_ft-_fl));
|
||||
_this->rng=IMUL32(r,(_fh-_fl));
|
||||
}
|
||||
else _this->rng-=IMUL32(r,(_ft-_fh));
|
||||
ec_enc_normalize(_this);
|
||||
}
|
||||
|
||||
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){
|
||||
opus_uint32 r;
|
||||
r=_this->rng>>_bits;
|
||||
if(_fl>0){
|
||||
_this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl));
|
||||
_this->rng=IMUL32(r,(_fh-_fl));
|
||||
}
|
||||
else _this->rng-=IMUL32(r,((1U<<_bits)-_fh));
|
||||
ec_enc_normalize(_this);
|
||||
}
|
||||
|
||||
/*The probability of having a "one" is 1/(1<<_logp).*/
|
||||
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){
|
||||
opus_uint32 r;
|
||||
opus_uint32 s;
|
||||
opus_uint32 l;
|
||||
r=_this->rng;
|
||||
l=_this->val;
|
||||
s=r>>_logp;
|
||||
r-=s;
|
||||
if(_val)_this->val=l+r;
|
||||
_this->rng=_val?s:r;
|
||||
ec_enc_normalize(_this);
|
||||
}
|
||||
|
||||
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){
|
||||
opus_uint32 r;
|
||||
r=_this->rng>>_ftb;
|
||||
if(_s>0){
|
||||
_this->val+=_this->rng-IMUL32(r,_icdf[_s-1]);
|
||||
_this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]);
|
||||
}
|
||||
else _this->rng-=IMUL32(r,_icdf[_s]);
|
||||
ec_enc_normalize(_this);
|
||||
}
|
||||
|
||||
void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){
|
||||
unsigned ft;
|
||||
unsigned fl;
|
||||
int ftb;
|
||||
/*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
|
||||
celt_assert(_ft>1);
|
||||
_ft--;
|
||||
ftb=EC_ILOG(_ft);
|
||||
if(ftb>EC_UINT_BITS){
|
||||
ftb-=EC_UINT_BITS;
|
||||
ft=(_ft>>ftb)+1;
|
||||
fl=(unsigned)(_fl>>ftb);
|
||||
ec_encode(_this,fl,fl+1,ft);
|
||||
ec_enc_bits(_this,_fl&(((opus_uint32)1<<ftb)-1U),ftb);
|
||||
}
|
||||
else ec_encode(_this,_fl,_fl+1,_ft+1);
|
||||
}
|
||||
|
||||
void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _bits){
|
||||
ec_window window;
|
||||
int used;
|
||||
window=_this->end_window;
|
||||
used=_this->nend_bits;
|
||||
celt_assert(_bits>0);
|
||||
if(used+_bits>EC_WINDOW_SIZE){
|
||||
do{
|
||||
_this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
|
||||
window>>=EC_SYM_BITS;
|
||||
used-=EC_SYM_BITS;
|
||||
}
|
||||
while(used>=EC_SYM_BITS);
|
||||
}
|
||||
window|=(ec_window)_fl<<used;
|
||||
used+=_bits;
|
||||
_this->end_window=window;
|
||||
_this->nend_bits=used;
|
||||
_this->nbits_total+=_bits;
|
||||
}
|
||||
|
||||
void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){
|
||||
int shift;
|
||||
unsigned mask;
|
||||
celt_assert(_nbits<=EC_SYM_BITS);
|
||||
shift=EC_SYM_BITS-_nbits;
|
||||
mask=((1<<_nbits)-1)<<shift;
|
||||
if(_this->offs>0){
|
||||
/*The first byte has been finalized.*/
|
||||
_this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<<shift);
|
||||
}
|
||||
else if(_this->rem>=0){
|
||||
/*The first byte is still awaiting carry propagation.*/
|
||||
_this->rem=(_this->rem&~mask)|_val<<shift;
|
||||
}
|
||||
else if(_this->rng<=(EC_CODE_TOP>>_nbits)){
|
||||
/*The renormalization loop has never been run.*/
|
||||
_this->val=(_this->val&~((opus_uint32)mask<<EC_CODE_SHIFT))|
|
||||
(opus_uint32)_val<<(EC_CODE_SHIFT+shift);
|
||||
}
|
||||
/*The encoder hasn't even encoded _nbits of data yet.*/
|
||||
else _this->error=-1;
|
||||
}
|
||||
|
||||
void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){
|
||||
celt_assert(_this->offs+_this->end_offs<=_size);
|
||||
OPUS_MOVE(_this->buf+_size-_this->end_offs,
|
||||
_this->buf+_this->storage-_this->end_offs,_this->end_offs);
|
||||
_this->storage=_size;
|
||||
}
|
||||
|
||||
void ec_enc_done(ec_enc *_this){
|
||||
ec_window window;
|
||||
int used;
|
||||
opus_uint32 msk;
|
||||
opus_uint32 end;
|
||||
int l;
|
||||
/*We output the minimum number of bits that ensures that the symbols encoded
|
||||
thus far will be decoded correctly regardless of the bits that follow.*/
|
||||
l=EC_CODE_BITS-EC_ILOG(_this->rng);
|
||||
msk=(EC_CODE_TOP-1)>>l;
|
||||
end=(_this->val+msk)&~msk;
|
||||
if((end|msk)>=_this->val+_this->rng){
|
||||
l++;
|
||||
msk>>=1;
|
||||
end=(_this->val+msk)&~msk;
|
||||
}
|
||||
while(l>0){
|
||||
ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT));
|
||||
end=(end<<EC_SYM_BITS)&(EC_CODE_TOP-1);
|
||||
l-=EC_SYM_BITS;
|
||||
}
|
||||
/*If we have a buffered byte flush it into the output buffer.*/
|
||||
if(_this->rem>=0||_this->ext>0)ec_enc_carry_out(_this,0);
|
||||
/*If we have buffered extra bits, flush them as well.*/
|
||||
window=_this->end_window;
|
||||
used=_this->nend_bits;
|
||||
while(used>=EC_SYM_BITS){
|
||||
_this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX);
|
||||
window>>=EC_SYM_BITS;
|
||||
used-=EC_SYM_BITS;
|
||||
}
|
||||
/*Clear any excess space and add any remaining extra bits to the last byte.*/
|
||||
if(!_this->error){
|
||||
OPUS_CLEAR(_this->buf+_this->offs,
|
||||
_this->storage-_this->offs-_this->end_offs);
|
||||
if(used>0){
|
||||
/*If there's no range coder data at all, give up.*/
|
||||
if(_this->end_offs>=_this->storage)_this->error=-1;
|
||||
else{
|
||||
l=-l;
|
||||
/*If we've busted, don't add too many extra bits to the last byte; it
|
||||
would corrupt the range coder data, and that's more important.*/
|
||||
if(_this->offs+_this->end_offs>=_this->storage&&l<used){
|
||||
window&=(1<<l)-1;
|
||||
_this->error=-1;
|
||||
}
|
||||
_this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
/* Copyright (c) 2001-2011 Timothy B. Terriberry
|
||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(_entenc_H)
|
||||
# define _entenc_H (1)
|
||||
# include <stddef.h>
|
||||
# include "opus/celt/entcode.h"
|
||||
|
||||
/*Initializes the encoder.
|
||||
_buf: The buffer to store output bytes in.
|
||||
_size: The size of the buffer, in chars.*/
|
||||
void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size);
|
||||
/*Encodes a symbol given its frequency information.
|
||||
The frequency information must be discernable by the decoder, assuming it
|
||||
has read only the previous symbols from the stream.
|
||||
It is allowable to change the frequency information, or even the entire
|
||||
source alphabet, so long as the decoder can tell from the context of the
|
||||
previously encoded information that it is supposed to do so as well.
|
||||
_fl: The cumulative frequency of all symbols that come before the one to be
|
||||
encoded.
|
||||
_fh: The cumulative frequency of all symbols up to and including the one to
|
||||
be encoded.
|
||||
Together with _fl, this defines the range [_fl,_fh) in which the
|
||||
decoded value will fall.
|
||||
_ft: The sum of the frequencies of all the symbols*/
|
||||
void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft);
|
||||
|
||||
/*Equivalent to ec_encode() with _ft==1<<_bits.*/
|
||||
void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits);
|
||||
|
||||
/* Encode a bit that has a 1/(1<<_logp) probability of being a one */
|
||||
void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp);
|
||||
|
||||
/*Encodes a symbol given an "inverse" CDF table.
|
||||
_s: The index of the symbol to encode.
|
||||
_icdf: The "inverse" CDF, such that symbol _s falls in the range
|
||||
[_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb.
|
||||
The values must be monotonically non-increasing, and the last value
|
||||
must be 0.
|
||||
_ftb: The number of bits of precision in the cumulative distribution.*/
|
||||
void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
|
||||
|
||||
/*Encodes a raw unsigned integer in the stream.
|
||||
_fl: The integer to encode.
|
||||
_ft: The number of integers that can be encoded (one more than the max).
|
||||
This must be at least one, and no more than 2**32-1.*/
|
||||
void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft);
|
||||
|
||||
/*Encodes a sequence of raw bits in the stream.
|
||||
_fl: The bits to encode.
|
||||
_ftb: The number of bits to encode.
|
||||
This must be between 1 and 25, inclusive.*/
|
||||
void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _ftb);
|
||||
|
||||
/*Overwrites a few bits at the very start of an existing stream, after they
|
||||
have already been encoded.
|
||||
This makes it possible to have a few flags up front, where it is easy for
|
||||
decoders to access them without parsing the whole stream, even if their
|
||||
values are not determined until late in the encoding process, without having
|
||||
to buffer all the intermediate symbols in the encoder.
|
||||
In order for this to work, at least _nbits bits must have already been
|
||||
encoded using probabilities that are an exact power of two.
|
||||
The encoder can verify the number of encoded bits is sufficient, but cannot
|
||||
check this latter condition.
|
||||
_val: The bits to encode (in the least _nbits significant bits).
|
||||
They will be decoded in order from most-significant to least.
|
||||
_nbits: The number of bits to overwrite.
|
||||
This must be no more than 8.*/
|
||||
void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits);
|
||||
|
||||
/*Compacts the data to fit in the target size.
|
||||
This moves up the raw bits at the end of the current buffer so they are at
|
||||
the end of the new buffer size.
|
||||
The caller must ensure that the amount of data that's already been written
|
||||
will fit in the new size.
|
||||
_size: The number of bytes in the new buffer.
|
||||
This must be large enough to contain the bits already written, and
|
||||
must be no larger than the existing size.*/
|
||||
void ec_enc_shrink(ec_enc *_this,opus_uint32 _size);
|
||||
|
||||
/*Indicates that there are no more symbols to encode.
|
||||
All reamining output bytes are flushed to the output buffer.
|
||||
ec_enc_init() must be called before the encoder can be used again.*/
|
||||
void ec_enc_done(ec_enc *_this);
|
||||
|
||||
#endif
|
@ -1,784 +0,0 @@
|
||||
/* Copyright (C) 2003-2008 Jean-Marc Valin
|
||||
Copyright (C) 2007-2012 Xiph.Org Foundation */
|
||||
/**
|
||||
@file fixed_debug.h
|
||||
@brief Fixed-point operations with debugging
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_DEBUG_H
|
||||
#define FIXED_DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "opus/opus_defines.h"
|
||||
|
||||
#ifdef CELT_C
|
||||
OPUS_EXPORT opus_int64 celt_mips=0;
|
||||
#else
|
||||
extern opus_int64 celt_mips;
|
||||
#endif
|
||||
|
||||
#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
|
||||
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15))
|
||||
|
||||
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
|
||||
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
|
||||
|
||||
#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
|
||||
|
||||
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
|
||||
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
|
||||
|
||||
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
|
||||
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
|
||||
#define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
|
||||
|
||||
#define SHR(a,b) SHR32(a,b)
|
||||
#define PSHR(a,b) PSHR32(a,b)
|
||||
|
||||
static OPUS_INLINE short NEG16(int x)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(x))
|
||||
{
|
||||
fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = -x;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
static OPUS_INLINE int NEG32(opus_int64 x)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_INT(x))
|
||||
{
|
||||
fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = -x;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
|
||||
static OPUS_INLINE short EXTRACT16_(int x, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(x))
|
||||
{
|
||||
fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = x;
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int EXTEND32_(int x, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(x))
|
||||
{
|
||||
fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = x;
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
|
||||
static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a>>shift;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
|
||||
static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a<<shift;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
static OPUS_INLINE int SHR32(opus_int64 a, int shift)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a>>shift;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
||||
{
|
||||
fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a<<shift;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", a, shift, res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
|
||||
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
|
||||
|
||||
#define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
|
||||
#define HALF16(x) (SHR16(x,1))
|
||||
#define HALF32(x) (SHR32(x,1))
|
||||
|
||||
//#define SHR(a,shift) ((a) >> (shift))
|
||||
//#define SHL(a,shift) ((a) << (shift))
|
||||
|
||||
#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a+b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE short SUB16_(int a, int b, char *file, int line)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a-b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a+b;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a-b;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef UADD32
|
||||
#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
|
||||
{
|
||||
opus_uint64 res;
|
||||
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
|
||||
{
|
||||
fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a+b;
|
||||
if (!VERIFY_UINT(res))
|
||||
{
|
||||
fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef USUB32
|
||||
#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
|
||||
{
|
||||
opus_uint64 res;
|
||||
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
|
||||
{
|
||||
fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
if (a<b)
|
||||
{
|
||||
fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a-b;
|
||||
if (!VERIFY_UINT(res))
|
||||
{
|
||||
fprintf (stderr, "USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\n", a, b, res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* result fits in 16 bits */
|
||||
static OPUS_INLINE short MULT16_16_16(int a, int b)
|
||||
{
|
||||
int res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a*b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips++;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MAC16_16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
|
||||
|
||||
#define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
if (ABS32(b)>=((opus_val32)(1)<<(15+Q)))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = (((opus_int64)a)*(opus_int64)b) >> Q;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
if (Q==15)
|
||||
celt_mips+=3;
|
||||
else
|
||||
celt_mips+=4;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
if (ABS32(b)>=((opus_int64)(1)<<(15+Q)))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
if (Q==15)
|
||||
celt_mips+=4;
|
||||
else
|
||||
celt_mips+=5;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
|
||||
#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
|
||||
#define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))
|
||||
|
||||
static OPUS_INLINE int SATURATE(int a, int b)
|
||||
{
|
||||
if (a>b)
|
||||
a=b;
|
||||
if (a<-b)
|
||||
a = -b;
|
||||
celt_mips+=3;
|
||||
return a;
|
||||
}
|
||||
|
||||
static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
|
||||
{
|
||||
celt_mips+=3;
|
||||
if (a>32767)
|
||||
return 32767;
|
||||
else if (a<-32768)
|
||||
return -32768;
|
||||
else return a;
|
||||
}
|
||||
|
||||
static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
res >>= 11;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=3;
|
||||
return res;
|
||||
}
|
||||
static OPUS_INLINE short MULT16_16_Q13(int a, int b)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
res >>= 13;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=3;
|
||||
return res;
|
||||
}
|
||||
static OPUS_INLINE short MULT16_16_Q14(int a, int b)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
res >>= 14;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=3;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
res >>= 15;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=1;
|
||||
return res;
|
||||
}
|
||||
|
||||
static OPUS_INLINE short MULT16_16_P13(int a, int b)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
res += 4096;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res >>= 13;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=4;
|
||||
return res;
|
||||
}
|
||||
static OPUS_INLINE short MULT16_16_P14(int a, int b)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
res += 8192;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res >>= 14;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=4;
|
||||
return res;
|
||||
}
|
||||
static OPUS_INLINE short MULT16_16_P15(int a, int b)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = ((opus_int64)a)*b;
|
||||
res += 16384;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res >>= 15;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=2;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
|
||||
|
||||
static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (b==0)
|
||||
{
|
||||
fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
|
||||
{
|
||||
fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a/b;
|
||||
if (!VERIFY_SHORT(res))
|
||||
{
|
||||
fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
|
||||
if (res>32767)
|
||||
res = 32767;
|
||||
if (res<-32768)
|
||||
res = -32768;
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=35;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
|
||||
static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||
{
|
||||
opus_int64 res;
|
||||
if (b==0)
|
||||
{
|
||||
fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||
{
|
||||
fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
res = a/b;
|
||||
if (!VERIFY_INT(res))
|
||||
{
|
||||
fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
celt_assert(0);
|
||||
#endif
|
||||
}
|
||||
celt_mips+=70;
|
||||
return res;
|
||||
}
|
||||
|
||||
static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
|
||||
{
|
||||
x = PSHR32(x, SIG_SHIFT);
|
||||
x = MAX32(x, -32768);
|
||||
x = MIN32(x, 32767);
|
||||
return EXTRACT16(x);
|
||||
}
|
||||
#define SIG2WORD16(x) (SIG2WORD16_generic(x))
|
||||
|
||||
|
||||
#undef PRINT_MIPS
|
||||
#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0);
|
||||
|
||||
#endif
|
@ -1,151 +0,0 @@
|
||||
/* Copyright (C) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (C) 2003-2008 Jean-Marc Valin
|
||||
Copyright (C) 2007-2008 CSIRO */
|
||||
/**
|
||||
@file fixed_generic.h
|
||||
@brief Generic fixed-point operations
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FIXED_GENERIC_H
|
||||
#define FIXED_GENERIC_H
|
||||
|
||||
/** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */
|
||||
#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
|
||||
|
||||
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
|
||||
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
|
||||
|
||||
/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */
|
||||
#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
|
||||
|
||||
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
|
||||
#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
|
||||
|
||||
/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
|
||||
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))
|
||||
|
||||
/** Compile-time conversion of float constant to 16-bit value */
|
||||
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
|
||||
|
||||
/** Compile-time conversion of float constant to 32-bit value */
|
||||
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
|
||||
|
||||
/** Negate a 16-bit value */
|
||||
#define NEG16(x) (-(x))
|
||||
/** Negate a 32-bit value */
|
||||
#define NEG32(x) (-(x))
|
||||
|
||||
/** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */
|
||||
#define EXTRACT16(x) ((opus_val16)(x))
|
||||
/** Change a 16-bit value into a 32-bit value */
|
||||
#define EXTEND32(x) ((opus_val32)(x))
|
||||
|
||||
/** Arithmetic shift-right of a 16-bit value */
|
||||
#define SHR16(a,shift) ((a) >> (shift))
|
||||
/** Arithmetic shift-left of a 16-bit value */
|
||||
#define SHL16(a,shift) ((opus_int16)((opus_uint16)(a)<<(shift)))
|
||||
/** Arithmetic shift-right of a 32-bit value */
|
||||
#define SHR32(a,shift) ((a) >> (shift))
|
||||
/** Arithmetic shift-left of a 32-bit value */
|
||||
#define SHL32(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift)))
|
||||
|
||||
/** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */
|
||||
#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
||||
/** 32-bit arithmetic shift right where the argument can be negative */
|
||||
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
|
||||
|
||||
/** "RAW" macros, should not be used outside of this header file */
|
||||
#define SHR(a,shift) ((a) >> (shift))
|
||||
#define SHL(a,shift) SHL32(a,shift)
|
||||
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
||||
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||
|
||||
#define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x)))
|
||||
|
||||
/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
|
||||
#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
|
||||
/** Divide by two */
|
||||
#define HALF16(x) (SHR16(x,1))
|
||||
#define HALF32(x) (SHR32(x,1))
|
||||
|
||||
/** Add two 16-bit values */
|
||||
#define ADD16(a,b) ((opus_val16)((opus_val16)(a)+(opus_val16)(b)))
|
||||
/** Subtract two 16-bit values */
|
||||
#define SUB16(a,b) ((opus_val16)(a)-(opus_val16)(b))
|
||||
/** Add two 32-bit values */
|
||||
#define ADD32(a,b) ((opus_val32)(a)+(opus_val32)(b))
|
||||
/** Subtract two 32-bit values */
|
||||
#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b))
|
||||
|
||||
/** 16x16 multiplication where the result fits in 16 bits */
|
||||
#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b))))
|
||||
|
||||
/* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */
|
||||
/** 16x16 multiplication where the result fits in 32 bits */
|
||||
#define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b)))
|
||||
|
||||
/** 16x16 multiply-add where the result fits in 32 bits */
|
||||
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
|
||||
/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
|
||||
b must fit in 31 bits.
|
||||
Result fits in 32 bits. */
|
||||
#define MAC16_32_Q15(c,a,b) ADD32((c),ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
|
||||
|
||||
/** 16x32 multiplication, followed by a 16-bit shift right and 32-bit add.
|
||||
Results fits in 32 bits */
|
||||
#define MAC16_32_Q16(c,a,b) ADD32((c),ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16)))
|
||||
|
||||
#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
|
||||
#define MULT16_16_Q11(a,b) (SHR(MULT16_16((a),(b)),11))
|
||||
#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
|
||||
#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
|
||||
#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
|
||||
|
||||
#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
|
||||
#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
|
||||
#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
|
||||
|
||||
/** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */
|
||||
#define DIV32_16(a,b) ((opus_val16)(((opus_val32)(a))/((opus_val16)(b))))
|
||||
|
||||
/** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */
|
||||
#define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b)))
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "opus/celt/mips/fixed_generic_mipsr1.h"
|
||||
#endif
|
||||
|
||||
static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
|
||||
{
|
||||
x = PSHR32(x, SIG_SHIFT);
|
||||
x = MAX32(x, -32768);
|
||||
x = MIN32(x, 32767);
|
||||
return EXTRACT16(x);
|
||||
}
|
||||
#define SIG2WORD16(x) (SIG2WORD16_generic(x))
|
||||
|
||||
#endif
|
@ -1,140 +0,0 @@
|
||||
/* Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com> */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Version 1.1 */
|
||||
|
||||
#ifndef FLOAT_CAST_H
|
||||
#define FLOAT_CAST_H
|
||||
|
||||
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
/*============================================================================
|
||||
** On Intel Pentium processors (especially PIII and probably P4), converting
|
||||
** from float to int is very slow. To meet the C specs, the code produced by
|
||||
** most C compilers targeting Pentium needs to change the FPU rounding mode
|
||||
** before the float to int conversion is performed.
|
||||
**
|
||||
** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
|
||||
** is this flushing of the pipeline which is so slow.
|
||||
**
|
||||
** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
|
||||
** llrint and llrintf which fix this problem as a side effect.
|
||||
**
|
||||
** On Unix-like systems, the configure process should have detected the
|
||||
** presence of these functions. If they weren't found we have to replace them
|
||||
** here with a standard C cast.
|
||||
*/
|
||||
|
||||
/*
|
||||
** The C99 prototypes for lrint and lrintf are as follows:
|
||||
**
|
||||
** long int lrintf (float x) ;
|
||||
** long int lrint (double x) ;
|
||||
*/
|
||||
|
||||
/* The presence of the required functions are detected during the configure
|
||||
** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
|
||||
** the config.h file.
|
||||
*/
|
||||
|
||||
#if (HAVE_LRINTF)
|
||||
|
||||
/* These defines enable functionality introduced with the 1999 ISO C
|
||||
** standard. They must be defined before the inclusion of math.h to
|
||||
** engage them. If optimisation is enabled, these functions will be
|
||||
** inlined. With optimisation switched off, you have to link in the
|
||||
** maths library using -lm.
|
||||
*/
|
||||
|
||||
#define _ISOC9X_SOURCE 1
|
||||
#define _ISOC99_SOURCE 1
|
||||
|
||||
#define __USE_ISOC9X 1
|
||||
#define __USE_ISOC99 1
|
||||
|
||||
#include <math.h>
|
||||
#define float2int(x) lrintf(x)
|
||||
|
||||
#elif (defined(HAVE_LRINT))
|
||||
|
||||
#define _ISOC9X_SOURCE 1
|
||||
#define _ISOC99_SOURCE 1
|
||||
|
||||
#define __USE_ISOC9X 1
|
||||
#define __USE_ISOC99 1
|
||||
|
||||
#include <math.h>
|
||||
#define float2int(x) lrint(x)
|
||||
|
||||
#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_X64)
|
||||
#include <xmmintrin.h>
|
||||
|
||||
__inline long int float2int(float value)
|
||||
{
|
||||
return _mm_cvtss_si32(_mm_load_ss(&value));
|
||||
}
|
||||
#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86)
|
||||
#include <math.h>
|
||||
|
||||
/* Win32 doesn't seem to have these functions.
|
||||
** Therefore implement OPUS_INLINE versions of these functions here.
|
||||
*/
|
||||
|
||||
__inline long int
|
||||
float2int (float flt)
|
||||
{ int intgr;
|
||||
|
||||
_asm
|
||||
{ fld flt
|
||||
fistp intgr
|
||||
} ;
|
||||
|
||||
return intgr ;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L)
|
||||
/* supported by gcc in C99 mode, but not by all other compilers */
|
||||
#warning "Don't have the functions lrint() and lrintf ()."
|
||||
#warning "Replacing these functions with a standard C cast."
|
||||
#endif /* __STDC_VERSION__ >= 199901L */
|
||||
#include <math.h>
|
||||
#define float2int(flt) ((int)(floor(.5+flt)))
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
static OPUS_INLINE opus_int16 FLOAT2INT16(float x)
|
||||
{
|
||||
x = x*CELT_SIG_SCALE;
|
||||
x = MAX32(x, -32768);
|
||||
x = MIN32(x, 32767);
|
||||
return (opus_int16)float2int(x);
|
||||
}
|
||||
#endif /* DISABLE_FLOAT_API */
|
||||
|
||||
#endif /* FLOAT_CAST_H */
|
@ -1,602 +0,0 @@
|
||||
/*Copyright (c) 2003-2004, Mark Borgerding
|
||||
Lots of modifications by Jean-Marc Valin
|
||||
Copyright (c) 2005-2007, Xiph.Org Foundation
|
||||
Copyright (c) 2008, Xiph.Org Foundation, CSIRO
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.*/
|
||||
|
||||
/* This code is originally from Mark Borgerding's KISS-FFT but has been
|
||||
heavily modified to better suit Opus */
|
||||
|
||||
#ifndef SKIP_CONFIG_H
|
||||
#include "opus/opus_config.h"
|
||||
#endif
|
||||
|
||||
#include "opus/celt/_kiss_fft_guts.h"
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
|
||||
/* The guts header contains all the multiplication and addition macros that are defined for
|
||||
complex numbers. It also delares the kf_ internal functions.
|
||||
*/
|
||||
|
||||
static void kf_bfly2(
|
||||
kiss_fft_cpx * Fout,
|
||||
int m,
|
||||
int N
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx * Fout2;
|
||||
int i;
|
||||
(void)m;
|
||||
#ifdef CUSTOM_MODES
|
||||
if (m==1)
|
||||
{
|
||||
celt_assert(m==1);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
kiss_fft_cpx t;
|
||||
Fout2 = Fout + 1;
|
||||
t = *Fout2;
|
||||
C_SUB( *Fout2 , *Fout , t );
|
||||
C_ADDTO( *Fout , t );
|
||||
Fout += 2;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
opus_val16 tw;
|
||||
tw = QCONST16(0.7071067812f, 15);
|
||||
/* We know that m==4 here because the radix-2 is just after a radix-4 */
|
||||
celt_assert(m==4);
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
kiss_fft_cpx t;
|
||||
Fout2 = Fout + 4;
|
||||
t = Fout2[0];
|
||||
C_SUB( Fout2[0] , Fout[0] , t );
|
||||
C_ADDTO( Fout[0] , t );
|
||||
|
||||
t.r = S_MUL(Fout2[1].r+Fout2[1].i, tw);
|
||||
t.i = S_MUL(Fout2[1].i-Fout2[1].r, tw);
|
||||
C_SUB( Fout2[1] , Fout[1] , t );
|
||||
C_ADDTO( Fout[1] , t );
|
||||
|
||||
t.r = Fout2[2].i;
|
||||
t.i = -Fout2[2].r;
|
||||
C_SUB( Fout2[2] , Fout[2] , t );
|
||||
C_ADDTO( Fout[2] , t );
|
||||
|
||||
t.r = S_MUL(Fout2[3].i-Fout2[3].r, tw);
|
||||
t.i = S_MUL(-Fout2[3].i-Fout2[3].r, tw);
|
||||
C_SUB( Fout2[3] , Fout[3] , t );
|
||||
C_ADDTO( Fout[3] , t );
|
||||
Fout += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void kf_bfly4(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_state *st,
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (m==1)
|
||||
{
|
||||
/* Degenerate case where all the twiddles are 1. */
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
kiss_fft_cpx scratch0, scratch1;
|
||||
|
||||
C_SUB( scratch0 , *Fout, Fout[2] );
|
||||
C_ADDTO(*Fout, Fout[2]);
|
||||
C_ADD( scratch1 , Fout[1] , Fout[3] );
|
||||
C_SUB( Fout[2], *Fout, scratch1 );
|
||||
C_ADDTO( *Fout , scratch1 );
|
||||
C_SUB( scratch1 , Fout[1] , Fout[3] );
|
||||
|
||||
Fout[1].r = scratch0.r + scratch1.i;
|
||||
Fout[1].i = scratch0.i - scratch1.r;
|
||||
Fout[3].r = scratch0.r - scratch1.i;
|
||||
Fout[3].i = scratch0.i + scratch1.r;
|
||||
Fout+=4;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
kiss_fft_cpx scratch[6];
|
||||
const kiss_twiddle_cpx *tw1,*tw2,*tw3;
|
||||
const int m2=2*m;
|
||||
const int m3=3*m;
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
Fout = Fout_beg + i*mm;
|
||||
tw3 = tw2 = tw1 = st->twiddles;
|
||||
/* m is guaranteed to be a multiple of 4. */
|
||||
for (j=0;j<m;j++)
|
||||
{
|
||||
C_MUL(scratch[0],Fout[m] , *tw1 );
|
||||
C_MUL(scratch[1],Fout[m2] , *tw2 );
|
||||
C_MUL(scratch[2],Fout[m3] , *tw3 );
|
||||
|
||||
C_SUB( scratch[5] , *Fout, scratch[1] );
|
||||
C_ADDTO(*Fout, scratch[1]);
|
||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
tw3 += fstride*3;
|
||||
C_ADDTO( *Fout , scratch[3] );
|
||||
|
||||
Fout[m].r = scratch[5].r + scratch[4].i;
|
||||
Fout[m].i = scratch[5].i - scratch[4].r;
|
||||
Fout[m3].r = scratch[5].r - scratch[4].i;
|
||||
Fout[m3].i = scratch[5].i + scratch[4].r;
|
||||
++Fout;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef RADIX_TWO_ONLY
|
||||
|
||||
static void kf_bfly3(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_state *st,
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
int i;
|
||||
size_t k;
|
||||
const size_t m2 = 2*m;
|
||||
const kiss_twiddle_cpx *tw1,*tw2;
|
||||
kiss_fft_cpx scratch[5];
|
||||
kiss_twiddle_cpx epi3;
|
||||
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
epi3.r = -16384;
|
||||
epi3.i = -28378;
|
||||
#else
|
||||
epi3 = st->twiddles[fstride*m];
|
||||
#endif
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
Fout = Fout_beg + i*mm;
|
||||
tw1=tw2=st->twiddles;
|
||||
/* For non-custom modes, m is guaranteed to be a multiple of 4. */
|
||||
k=m;
|
||||
do {
|
||||
|
||||
C_MUL(scratch[1],Fout[m] , *tw1);
|
||||
C_MUL(scratch[2],Fout[m2] , *tw2);
|
||||
|
||||
C_ADD(scratch[3],scratch[1],scratch[2]);
|
||||
C_SUB(scratch[0],scratch[1],scratch[2]);
|
||||
tw1 += fstride;
|
||||
tw2 += fstride*2;
|
||||
|
||||
Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
|
||||
Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
|
||||
|
||||
C_MULBYSCALAR( scratch[0] , epi3.i );
|
||||
|
||||
C_ADDTO(*Fout,scratch[3]);
|
||||
|
||||
Fout[m2].r = Fout[m].r + scratch[0].i;
|
||||
Fout[m2].i = Fout[m].i - scratch[0].r;
|
||||
|
||||
Fout[m].r -= scratch[0].i;
|
||||
Fout[m].i += scratch[0].r;
|
||||
|
||||
++Fout;
|
||||
} while(--k);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef OVERRIDE_kf_bfly5
|
||||
static void kf_bfly5(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_state *st,
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
|
||||
int i, u;
|
||||
kiss_fft_cpx scratch[13];
|
||||
const kiss_twiddle_cpx *tw;
|
||||
kiss_twiddle_cpx ya,yb;
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
ya.r = 10126;
|
||||
ya.i = -31164;
|
||||
yb.r = -26510;
|
||||
yb.i = -19261;
|
||||
#else
|
||||
ya = st->twiddles[fstride*m];
|
||||
yb = st->twiddles[fstride*2*m];
|
||||
#endif
|
||||
tw=st->twiddles;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
Fout = Fout_beg + i*mm;
|
||||
Fout0=Fout;
|
||||
Fout1=Fout0+m;
|
||||
Fout2=Fout0+2*m;
|
||||
Fout3=Fout0+3*m;
|
||||
Fout4=Fout0+4*m;
|
||||
|
||||
/* For non-custom modes, m is guaranteed to be a multiple of 4. */
|
||||
for ( u=0; u<m; ++u ) {
|
||||
scratch[0] = *Fout0;
|
||||
|
||||
C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
|
||||
C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
|
||||
C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
|
||||
C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
|
||||
|
||||
C_ADD( scratch[7],scratch[1],scratch[4]);
|
||||
C_SUB( scratch[10],scratch[1],scratch[4]);
|
||||
C_ADD( scratch[8],scratch[2],scratch[3]);
|
||||
C_SUB( scratch[9],scratch[2],scratch[3]);
|
||||
|
||||
Fout0->r += scratch[7].r + scratch[8].r;
|
||||
Fout0->i += scratch[7].i + scratch[8].i;
|
||||
|
||||
scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
|
||||
scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
|
||||
|
||||
scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
|
||||
scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
|
||||
|
||||
C_SUB(*Fout1,scratch[5],scratch[6]);
|
||||
C_ADD(*Fout4,scratch[5],scratch[6]);
|
||||
|
||||
scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
|
||||
scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
|
||||
scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
|
||||
scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
|
||||
|
||||
C_ADD(*Fout2,scratch[11],scratch[12]);
|
||||
C_SUB(*Fout3,scratch[11],scratch[12]);
|
||||
|
||||
++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* OVERRIDE_kf_bfly5 */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
|
||||
static
|
||||
void compute_bitrev_table(
|
||||
int Fout,
|
||||
opus_int16 *f,
|
||||
const size_t fstride,
|
||||
int in_stride,
|
||||
opus_int16 * factors,
|
||||
const kiss_fft_state *st
|
||||
)
|
||||
{
|
||||
const int p=*factors++; /* the radix */
|
||||
const int m=*factors++; /* stage's fft length/p */
|
||||
|
||||
/*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/
|
||||
if (m==1)
|
||||
{
|
||||
int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
*f = Fout+j;
|
||||
f += fstride*in_stride;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
for (j=0;j<p;j++)
|
||||
{
|
||||
compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st);
|
||||
f += fstride*in_stride;
|
||||
Fout += m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* facbuf is populated by p1,m1,p2,m2, ...
|
||||
where
|
||||
p[i] * m[i] = m[i-1]
|
||||
m0 = n */
|
||||
static
|
||||
int kf_factor(int n,opus_int16 * facbuf)
|
||||
{
|
||||
int p=4;
|
||||
int i;
|
||||
int stages=0;
|
||||
int nbak = n;
|
||||
|
||||
/*factor out powers of 4, powers of 2, then any remaining primes */
|
||||
do {
|
||||
while (n % p) {
|
||||
switch (p) {
|
||||
case 4: p = 2; break;
|
||||
case 2: p = 3; break;
|
||||
default: p += 2; break;
|
||||
}
|
||||
if (p>32000 || (opus_int32)p*(opus_int32)p > n)
|
||||
p = n; /* no more factors, skip to end */
|
||||
}
|
||||
n /= p;
|
||||
#ifdef RADIX_TWO_ONLY
|
||||
if (p!=2 && p != 4)
|
||||
#else
|
||||
if (p>5)
|
||||
#endif
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
facbuf[2*stages] = p;
|
||||
if (p==2 && stages > 1)
|
||||
{
|
||||
facbuf[2*stages] = 4;
|
||||
facbuf[2] = 2;
|
||||
}
|
||||
stages++;
|
||||
} while (n > 1);
|
||||
n = nbak;
|
||||
/* Reverse the order to get the radix 4 at the end, so we can use the
|
||||
fast degenerate case. It turns out that reversing the order also
|
||||
improves the noise behaviour. */
|
||||
for (i=0;i<stages/2;i++)
|
||||
{
|
||||
int tmp;
|
||||
tmp = facbuf[2*i];
|
||||
facbuf[2*i] = facbuf[2*(stages-i-1)];
|
||||
facbuf[2*(stages-i-1)] = tmp;
|
||||
}
|
||||
for (i=0;i<stages;i++)
|
||||
{
|
||||
n /= facbuf[2*i];
|
||||
facbuf[2*i+1] = n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
|
||||
{
|
||||
int i;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
for (i=0;i<nfft;++i) {
|
||||
opus_val32 phase = -i;
|
||||
kf_cexp2(twiddles+i, DIV32(SHL32(phase,17),nfft));
|
||||
}
|
||||
#else
|
||||
for (i=0;i<nfft;++i) {
|
||||
const double pi=3.14159265358979323846264338327;
|
||||
double phase = ( -2*pi /nfft ) * i;
|
||||
kf_cexp(twiddles+i, phase );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int opus_fft_alloc_arch_c(kiss_fft_state *st) {
|
||||
(void)st;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Allocates all necessary storage space for the fft and ifft.
|
||||
* The return value is a contiguous block of memory. As such,
|
||||
* It can be freed with free().
|
||||
* */
|
||||
kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,
|
||||
const kiss_fft_state *base, int arch)
|
||||
{
|
||||
kiss_fft_state *st=NULL;
|
||||
size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/
|
||||
|
||||
if ( lenmem==NULL ) {
|
||||
st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded );
|
||||
}else{
|
||||
if (mem != NULL && *lenmem >= memneeded)
|
||||
st = (kiss_fft_state*)mem;
|
||||
*lenmem = memneeded;
|
||||
}
|
||||
if (st) {
|
||||
opus_int16 *bitrev;
|
||||
kiss_twiddle_cpx *twiddles;
|
||||
|
||||
st->nfft=nfft;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
st->scale_shift = celt_ilog2(st->nfft);
|
||||
if (st->nfft == 1<<st->scale_shift)
|
||||
st->scale = Q15ONE;
|
||||
else
|
||||
st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift);
|
||||
#else
|
||||
st->scale = 1.f/nfft;
|
||||
#endif
|
||||
if (base != NULL)
|
||||
{
|
||||
st->twiddles = base->twiddles;
|
||||
st->shift = 0;
|
||||
while (st->shift < 32 && nfft<<st->shift != base->nfft)
|
||||
st->shift++;
|
||||
if (st->shift>=32)
|
||||
goto fail;
|
||||
} else {
|
||||
st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft);
|
||||
compute_twiddles(twiddles, nfft);
|
||||
st->shift = -1;
|
||||
}
|
||||
if (!kf_factor(nfft,st->factors))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* bitrev */
|
||||
st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft);
|
||||
if (st->bitrev==NULL)
|
||||
goto fail;
|
||||
compute_bitrev_table(0, bitrev, 1,1, st->factors,st);
|
||||
|
||||
/* Initialize architecture specific fft parameters */
|
||||
if (opus_fft_alloc_arch(st, arch))
|
||||
goto fail;
|
||||
}
|
||||
return st;
|
||||
fail:
|
||||
opus_fft_free(st, arch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch)
|
||||
{
|
||||
return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL, arch);
|
||||
}
|
||||
|
||||
void opus_fft_free_arch_c(kiss_fft_state *st) {
|
||||
(void)st;
|
||||
}
|
||||
|
||||
void opus_fft_free(const kiss_fft_state *cfg, int arch)
|
||||
{
|
||||
if (cfg)
|
||||
{
|
||||
opus_fft_free_arch((kiss_fft_state *)cfg, arch);
|
||||
opus_free((opus_int16*)cfg->bitrev);
|
||||
if (cfg->shift < 0)
|
||||
opus_free((kiss_twiddle_cpx*)cfg->twiddles);
|
||||
opus_free((kiss_fft_state*)cfg);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CUSTOM_MODES */
|
||||
|
||||
void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout)
|
||||
{
|
||||
int m2, m;
|
||||
int p;
|
||||
int L;
|
||||
int fstride[MAXFACTORS];
|
||||
int i;
|
||||
int shift;
|
||||
|
||||
/* st->shift can be -1 */
|
||||
shift = st->shift>0 ? st->shift : 0;
|
||||
|
||||
fstride[0] = 1;
|
||||
L=0;
|
||||
do {
|
||||
p = st->factors[2*L];
|
||||
m = st->factors[2*L+1];
|
||||
fstride[L+1] = fstride[L]*p;
|
||||
L++;
|
||||
} while(m!=1);
|
||||
m = st->factors[2*L-1];
|
||||
for (i=L-1;i>=0;i--)
|
||||
{
|
||||
if (i!=0)
|
||||
m2 = st->factors[2*i-1];
|
||||
else
|
||||
m2 = 1;
|
||||
switch (st->factors[2*i])
|
||||
{
|
||||
case 2:
|
||||
kf_bfly2(fout, m, fstride[i]);
|
||||
break;
|
||||
case 4:
|
||||
kf_bfly4(fout,fstride[i]<<shift,st,m, fstride[i], m2);
|
||||
break;
|
||||
#ifndef RADIX_TWO_ONLY
|
||||
case 3:
|
||||
kf_bfly3(fout,fstride[i]<<shift,st,m, fstride[i], m2);
|
||||
break;
|
||||
case 5:
|
||||
kf_bfly5(fout,fstride[i]<<shift,st,m, fstride[i], m2);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
m = m2;
|
||||
}
|
||||
}
|
||||
|
||||
void opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
|
||||
{
|
||||
int i;
|
||||
opus_val16 scale;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
/* Allows us to scale with MULT16_32_Q16(), which is faster than
|
||||
MULT16_32_Q15() on ARM. */
|
||||
int scale_shift = st->scale_shift-1;
|
||||
#endif
|
||||
scale = st->scale;
|
||||
|
||||
celt_assert2 (fin != fout, "In-place FFT not supported");
|
||||
/* Bit-reverse the input */
|
||||
for (i=0;i<st->nfft;i++)
|
||||
{
|
||||
kiss_fft_cpx x = fin[i];
|
||||
fout[st->bitrev[i]].r = SHR32(MULT16_32_Q16(scale, x.r), scale_shift);
|
||||
fout[st->bitrev[i]].i = SHR32(MULT16_32_Q16(scale, x.i), scale_shift);
|
||||
}
|
||||
opus_fft_impl(st, fout);
|
||||
}
|
||||
|
||||
|
||||
void opus_ifft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
|
||||
{
|
||||
int i;
|
||||
celt_assert2 (fin != fout, "In-place FFT not supported");
|
||||
/* Bit-reverse the input */
|
||||
for (i=0;i<st->nfft;i++)
|
||||
fout[st->bitrev[i]] = fin[i];
|
||||
for (i=0;i<st->nfft;i++)
|
||||
fout[i].i = -fout[i].i;
|
||||
opus_fft_impl(st, fout);
|
||||
for (i=0;i<st->nfft;i++)
|
||||
fout[i].i = -fout[i].i;
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
/*Copyright (c) 2003-2004, Mark Borgerding
|
||||
Lots of modifications by Jean-Marc Valin
|
||||
Copyright (c) 2005-2007, Xiph.Org Foundation
|
||||
Copyright (c) 2008, Xiph.Org Foundation, CSIRO
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.*/
|
||||
|
||||
#ifndef KISS_FFT_H
|
||||
#define KISS_FFT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/cpu_support.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef USE_SIMD
|
||||
# include <xmmintrin.h>
|
||||
# define kiss_fft_scalar __m128
|
||||
#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes)
|
||||
#else
|
||||
#define KISS_FFT_MALLOC opus_alloc
|
||||
#endif
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
# define kiss_fft_scalar opus_int32
|
||||
# define kiss_twiddle_scalar opus_int16
|
||||
|
||||
|
||||
#else
|
||||
# ifndef kiss_fft_scalar
|
||||
/* default is float */
|
||||
# define kiss_fft_scalar float
|
||||
# define kiss_twiddle_scalar float
|
||||
# define KF_SUFFIX _celt_single
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
kiss_fft_scalar r;
|
||||
kiss_fft_scalar i;
|
||||
}kiss_fft_cpx;
|
||||
|
||||
typedef struct {
|
||||
kiss_twiddle_scalar r;
|
||||
kiss_twiddle_scalar i;
|
||||
}kiss_twiddle_cpx;
|
||||
|
||||
#define MAXFACTORS 8
|
||||
/* e.g. an fft of length 128 has 4 factors
|
||||
as far as kissfft is concerned
|
||||
4*4*4*2
|
||||
*/
|
||||
|
||||
typedef struct arch_fft_state{
|
||||
int is_supported;
|
||||
void *priv;
|
||||
} arch_fft_state;
|
||||
|
||||
typedef struct kiss_fft_state{
|
||||
int nfft;
|
||||
opus_val16 scale;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
int scale_shift;
|
||||
#endif
|
||||
int shift;
|
||||
opus_int16 factors[2*MAXFACTORS];
|
||||
const opus_int16 *bitrev;
|
||||
const kiss_twiddle_cpx *twiddles;
|
||||
arch_fft_state *arch_fft;
|
||||
} kiss_fft_state;
|
||||
|
||||
#if defined(HAVE_ARM_NE10)
|
||||
#include "opus/celt/arm/fft_arm.h"
|
||||
#endif
|
||||
|
||||
/*typedef struct kiss_fft_state* kiss_fft_cfg;*/
|
||||
|
||||
/**
|
||||
* opus_fft_alloc
|
||||
*
|
||||
* Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
|
||||
*
|
||||
* typical usage: kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL);
|
||||
*
|
||||
* The return value from fft_alloc is a cfg buffer used internally
|
||||
* by the fft routine or NULL.
|
||||
*
|
||||
* If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc.
|
||||
* The returned value should be free()d when done to avoid memory leaks.
|
||||
*
|
||||
* The state can be placed in a user supplied buffer 'mem':
|
||||
* If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
|
||||
* then the function places the cfg in mem and the size used in *lenmem
|
||||
* and returns mem.
|
||||
*
|
||||
* If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
|
||||
* then the function returns NULL and places the minimum cfg
|
||||
* buffer size in *lenmem.
|
||||
* */
|
||||
|
||||
kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base, int arch);
|
||||
|
||||
kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch);
|
||||
|
||||
/**
|
||||
* opus_fft(cfg,in_out_buf)
|
||||
*
|
||||
* Perform an FFT on a complex input buffer.
|
||||
* for a forward FFT,
|
||||
* fin should be f[0] , f[1] , ... ,f[nfft-1]
|
||||
* fout will be F[0] , F[1] , ... ,F[nfft-1]
|
||||
* Note that each element is complex and can be accessed like
|
||||
f[k].r and f[k].i
|
||||
* */
|
||||
void opus_fft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
|
||||
void opus_ifft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
|
||||
|
||||
void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);
|
||||
void opus_ifft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);
|
||||
|
||||
void opus_fft_free(const kiss_fft_state *cfg, int arch);
|
||||
|
||||
|
||||
void opus_fft_free_arch_c(kiss_fft_state *st);
|
||||
int opus_fft_alloc_arch_c(kiss_fft_state *st);
|
||||
|
||||
#if !defined(OVERRIDE_OPUS_FFT)
|
||||
/* Is run-time CPU detection enabled on this platform? */
|
||||
#if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10))
|
||||
|
||||
extern int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(
|
||||
kiss_fft_state *st);
|
||||
|
||||
#define opus_fft_alloc_arch(_st, arch) \
|
||||
((*OPUS_FFT_ALLOC_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))
|
||||
|
||||
extern void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(
|
||||
kiss_fft_state *st);
|
||||
#define opus_fft_free_arch(_st, arch) \
|
||||
((*OPUS_FFT_FREE_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))
|
||||
|
||||
extern void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
|
||||
const kiss_fft_cpx *fin, kiss_fft_cpx *fout);
|
||||
#define opus_fft(_cfg, _fin, _fout, arch) \
|
||||
((*OPUS_FFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))
|
||||
|
||||
extern void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
|
||||
const kiss_fft_cpx *fin, kiss_fft_cpx *fout);
|
||||
#define opus_ifft(_cfg, _fin, _fout, arch) \
|
||||
((*OPUS_IFFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))
|
||||
|
||||
#else /* else for if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */
|
||||
|
||||
#define opus_fft_alloc_arch(_st, arch) \
|
||||
((void)(arch), opus_fft_alloc_arch_c(_st))
|
||||
|
||||
#define opus_fft_free_arch(_st, arch) \
|
||||
((void)(arch), opus_fft_free_arch_c(_st))
|
||||
|
||||
#define opus_fft(_cfg, _fin, _fout, arch) \
|
||||
((void)(arch), opus_fft_c(_cfg, _fin, _fout))
|
||||
|
||||
#define opus_ifft(_cfg, _fin, _fout, arch) \
|
||||
((void)(arch), opus_ifft_c(_cfg, _fin, _fout))
|
||||
|
||||
#endif /* end if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */
|
||||
#endif /* end if !defined(OVERRIDE_OPUS_FFT) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,131 +0,0 @@
|
||||
/* Copyright (c) 2007 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/laplace.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
|
||||
/* The minimum probability of an energy delta (out of 32768). */
|
||||
#define LAPLACE_LOG_MINP (0)
|
||||
#define LAPLACE_MINP (1<<LAPLACE_LOG_MINP)
|
||||
/* The minimum number of guaranteed representable energy deltas (in one
|
||||
direction). */
|
||||
#define LAPLACE_NMIN (16)
|
||||
|
||||
/* When called, decay is positive and at most 11456. */
|
||||
static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
|
||||
{
|
||||
unsigned ft;
|
||||
ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
|
||||
return ft*(opus_int32)(16384-decay)>>15;
|
||||
}
|
||||
|
||||
void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)
|
||||
{
|
||||
unsigned fl;
|
||||
int val = *value;
|
||||
fl = 0;
|
||||
if (val)
|
||||
{
|
||||
int s;
|
||||
int i;
|
||||
s = -(val<0);
|
||||
val = (val+s)^s;
|
||||
fl = fs;
|
||||
fs = ec_laplace_get_freq1(fs, decay);
|
||||
/* Search the decaying part of the PDF.*/
|
||||
for (i=1; fs > 0 && i < val; i++)
|
||||
{
|
||||
fs *= 2;
|
||||
fl += fs+2*LAPLACE_MINP;
|
||||
fs = (fs*(opus_int32)decay)>>15;
|
||||
}
|
||||
/* Everything beyond that has probability LAPLACE_MINP. */
|
||||
if (!fs)
|
||||
{
|
||||
int di;
|
||||
int ndi_max;
|
||||
ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP;
|
||||
ndi_max = (ndi_max-s)>>1;
|
||||
di = IMIN(val - i, ndi_max - 1);
|
||||
fl += (2*di+1+s)*LAPLACE_MINP;
|
||||
fs = IMIN(LAPLACE_MINP, 32768-fl);
|
||||
*value = (i+di+s)^s;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs += LAPLACE_MINP;
|
||||
fl += fs&~s;
|
||||
}
|
||||
celt_assert(fl+fs<=32768);
|
||||
celt_assert(fs>0);
|
||||
}
|
||||
ec_encode_bin(enc, fl, fl+fs, 15);
|
||||
}
|
||||
|
||||
int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay)
|
||||
{
|
||||
int val=0;
|
||||
unsigned fl;
|
||||
unsigned fm;
|
||||
fm = ec_decode_bin(dec, 15);
|
||||
fl = 0;
|
||||
if (fm >= fs)
|
||||
{
|
||||
val++;
|
||||
fl = fs;
|
||||
fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP;
|
||||
/* Search the decaying part of the PDF.*/
|
||||
while(fs > LAPLACE_MINP && fm >= fl+2*fs)
|
||||
{
|
||||
fs *= 2;
|
||||
fl += fs;
|
||||
fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15;
|
||||
fs += LAPLACE_MINP;
|
||||
val++;
|
||||
}
|
||||
/* Everything beyond that has probability LAPLACE_MINP. */
|
||||
if (fs <= LAPLACE_MINP)
|
||||
{
|
||||
int di;
|
||||
di = (fm-fl)>>(LAPLACE_LOG_MINP+1);
|
||||
val += di;
|
||||
fl += 2*di*LAPLACE_MINP;
|
||||
}
|
||||
if (fm < fl+fs)
|
||||
val = -val;
|
||||
else
|
||||
fl += fs;
|
||||
}
|
||||
celt_assert(fl<32768);
|
||||
celt_assert(fs>0);
|
||||
celt_assert(fl<=fm);
|
||||
celt_assert(fm<IMIN(fl+fs,32768));
|
||||
ec_dec_update(dec, fl, IMIN(fl+fs,32768), 32768);
|
||||
return val;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/* Copyright (c) 2007 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "opus/celt/entenc.h"
|
||||
#include "opus/celt/entdec.h"
|
||||
|
||||
/** Encode a value that is assumed to be the realisation of a
|
||||
Laplace-distributed random process
|
||||
@param enc Entropy encoder state
|
||||
@param value Value to encode
|
||||
@param fs Probability of 0, multiplied by 32768
|
||||
@param decay Probability of the value +/- 1, multiplied by 16384
|
||||
*/
|
||||
void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay);
|
||||
|
||||
/** Decode a value that is assumed to be the realisation of a
|
||||
Laplace-distributed random process
|
||||
@param dec Entropy decoder state
|
||||
@param fs Probability of 0, multiplied by 32768
|
||||
@param decay Probability of the value +/- 1, multiplied by 16384
|
||||
@return Value decoded
|
||||
*/
|
||||
int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay);
|
@ -1,205 +0,0 @@
|
||||
/* Copyright (c) 2002-2008 Jean-Marc Valin
|
||||
Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/**
|
||||
@file mathops.h
|
||||
@brief Various math functions
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/mathops.h"
|
||||
|
||||
/*Compute floor(sqrt(_val)) with exact arithmetic.
|
||||
This has been tested on all possible 32-bit inputs.*/
|
||||
unsigned isqrt32(opus_uint32 _val){
|
||||
unsigned b;
|
||||
unsigned g;
|
||||
int bshift;
|
||||
/*Uses the second method from
|
||||
http://www.azillionmonkeys.com/qed/sqroot.html
|
||||
The main idea is to search for the largest binary digit b such that
|
||||
(g+b)*(g+b) <= _val, and add it to the solution g.*/
|
||||
g=0;
|
||||
bshift=(EC_ILOG(_val)-1)>>1;
|
||||
b=1U<<bshift;
|
||||
do{
|
||||
opus_uint32 t;
|
||||
t=(((opus_uint32)g<<1)+b)<<bshift;
|
||||
if(t<=_val){
|
||||
g+=b;
|
||||
_val-=t;
|
||||
}
|
||||
b>>=1;
|
||||
bshift--;
|
||||
}
|
||||
while(bshift>=0);
|
||||
return g;
|
||||
}
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
|
||||
opus_val32 frac_div32(opus_val32 a, opus_val32 b)
|
||||
{
|
||||
opus_val16 rcp;
|
||||
opus_val32 result, rem;
|
||||
int shift = celt_ilog2(b)-29;
|
||||
a = VSHR32(a,shift);
|
||||
b = VSHR32(b,shift);
|
||||
/* 16-bit reciprocal */
|
||||
rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);
|
||||
result = MULT16_32_Q15(rcp, a);
|
||||
rem = PSHR32(a,2)-MULT32_32_Q31(result, b);
|
||||
result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2));
|
||||
if (result >= 536870912) /* 2^29 */
|
||||
return 2147483647; /* 2^31 - 1 */
|
||||
else if (result <= -536870912) /* -2^29 */
|
||||
return -2147483647; /* -2^31 */
|
||||
else
|
||||
return SHL32(result, 2);
|
||||
}
|
||||
|
||||
/** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */
|
||||
opus_val16 celt_rsqrt_norm(opus_val32 x)
|
||||
{
|
||||
opus_val16 n;
|
||||
opus_val16 r;
|
||||
opus_val16 r2;
|
||||
opus_val16 y;
|
||||
/* Range of n is [-16384,32767] ([-0.5,1) in Q15). */
|
||||
n = x-32768;
|
||||
/* Get a rough initial guess for the root.
|
||||
The optimal minimax quadratic approximation (using relative error) is
|
||||
r = 1.437799046117536+n*(-0.823394375837328+n*0.4096419668459485).
|
||||
Coefficients here, and the final result r, are Q14.*/
|
||||
r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713))));
|
||||
/* We want y = x*r*r-1 in Q15, but x is 32-bit Q16 and r is Q14.
|
||||
We can compute the result from n and r using Q15 multiplies with some
|
||||
adjustment, carefully done to avoid overflow.
|
||||
Range of y is [-1564,1594]. */
|
||||
r2 = MULT16_16_Q15(r, r);
|
||||
y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1);
|
||||
/* Apply a 2nd-order Householder iteration: r += r*y*(y*0.375-0.5).
|
||||
This yields the Q14 reciprocal square root of the Q16 x, with a maximum
|
||||
relative error of 1.04956E-4, a (relative) RMSE of 2.80979E-5, and a
|
||||
peak absolute error of 2.26591/16384. */
|
||||
return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y,
|
||||
SUB16(MULT16_16_Q15(y, 12288), 16384))));
|
||||
}
|
||||
|
||||
/** Sqrt approximation (QX input, QX/2 output) */
|
||||
opus_val32 celt_sqrt(opus_val32 x)
|
||||
{
|
||||
int k;
|
||||
opus_val16 n;
|
||||
opus_val32 rt;
|
||||
static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};
|
||||
if (x==0)
|
||||
return 0;
|
||||
else if (x>=1073741824)
|
||||
return 32767;
|
||||
k = (celt_ilog2(x)>>1)-7;
|
||||
x = VSHR32(x, 2*k);
|
||||
n = x-32768;
|
||||
rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2],
|
||||
MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4])))))))));
|
||||
rt = VSHR32(rt,7-k);
|
||||
return rt;
|
||||
}
|
||||
|
||||
#define L1 32767
|
||||
#define L2 -7651
|
||||
#define L3 8277
|
||||
#define L4 -626
|
||||
|
||||
static OPUS_INLINE opus_val16 _celt_cos_pi_2(opus_val16 x)
|
||||
{
|
||||
opus_val16 x2;
|
||||
|
||||
x2 = MULT16_16_P15(x,x);
|
||||
return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2
|
||||
))))))));
|
||||
}
|
||||
|
||||
#undef L1
|
||||
#undef L2
|
||||
#undef L3
|
||||
#undef L4
|
||||
|
||||
opus_val16 celt_cos_norm(opus_val32 x)
|
||||
{
|
||||
x = x&0x0001ffff;
|
||||
if (x>SHL32(EXTEND32(1), 16))
|
||||
x = SUB32(SHL32(EXTEND32(1), 17),x);
|
||||
if (x&0x00007fff)
|
||||
{
|
||||
if (x<SHL32(EXTEND32(1), 15))
|
||||
{
|
||||
return _celt_cos_pi_2(EXTRACT16(x));
|
||||
} else {
|
||||
return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));
|
||||
}
|
||||
} else {
|
||||
if (x&0x0000ffff)
|
||||
return 0;
|
||||
else if (x&0x0001ffff)
|
||||
return -32767;
|
||||
else
|
||||
return 32767;
|
||||
}
|
||||
}
|
||||
|
||||
/** Reciprocal approximation (Q15 input, Q16 output) */
|
||||
opus_val32 celt_rcp(opus_val32 x)
|
||||
{
|
||||
int i;
|
||||
opus_val16 n;
|
||||
opus_val16 r;
|
||||
celt_assert2(x>0, "celt_rcp() only defined for positive values");
|
||||
i = celt_ilog2(x);
|
||||
/* n is Q15 with range [0,1). */
|
||||
n = VSHR32(x,i-15)-32768;
|
||||
/* Start with a linear approximation:
|
||||
r = 1.8823529411764706-0.9411764705882353*n.
|
||||
The coefficients and the result are Q14 in the range [15420,30840].*/
|
||||
r = ADD16(30840, MULT16_16_Q15(-15420, n));
|
||||
/* Perform two Newton iterations:
|
||||
r -= r*((r*n)-1.Q15)
|
||||
= r*((r*n)+(r-1.Q15)). */
|
||||
r = SUB16(r, MULT16_16_Q15(r,
|
||||
ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))));
|
||||
/* We subtract an extra 1 in the second iteration to avoid overflow; it also
|
||||
neatly compensates for truncation error in the rest of the process. */
|
||||
r = SUB16(r, ADD16(1, MULT16_16_Q15(r,
|
||||
ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))));
|
||||
/* r is now the Q15 solution to 2/(n+1), with a maximum relative error
|
||||
of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute
|
||||
error of 1.24665/32768. */
|
||||
return VSHR32(EXTEND32(r),i-16);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,258 +0,0 @@
|
||||
/* Copyright (c) 2002-2008 Jean-Marc Valin
|
||||
Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/**
|
||||
@file mathops.h
|
||||
@brief Various math functions
|
||||
*/
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MATHOPS_H
|
||||
#define MATHOPS_H
|
||||
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/entcode.h"
|
||||
#include "opus/celt/os_support.h"
|
||||
|
||||
/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */
|
||||
#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15)
|
||||
|
||||
unsigned isqrt32(opus_uint32 _val);
|
||||
|
||||
#ifndef OVERRIDE_CELT_MAXABS16
|
||||
static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len)
|
||||
{
|
||||
int i;
|
||||
opus_val16 maxval = 0;
|
||||
opus_val16 minval = 0;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
maxval = MAX16(maxval, x[i]);
|
||||
minval = MIN16(minval, x[i]);
|
||||
}
|
||||
return MAX32(EXTEND32(maxval),-EXTEND32(minval));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_CELT_MAXABS32
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
static OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)
|
||||
{
|
||||
int i;
|
||||
opus_val32 maxval = 0;
|
||||
opus_val32 minval = 0;
|
||||
for (i=0;i<len;i++)
|
||||
{
|
||||
maxval = MAX32(maxval, x[i]);
|
||||
minval = MIN32(minval, x[i]);
|
||||
}
|
||||
return MAX32(maxval, -minval);
|
||||
}
|
||||
#else
|
||||
#define celt_maxabs32(x,len) celt_maxabs16(x,len)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OPUS_FIXED_POINT
|
||||
|
||||
#define PI 3.141592653f
|
||||
#define celt_sqrt(x) ((float)sqrt(x))
|
||||
#define celt_rsqrt(x) (1.f/celt_sqrt(x))
|
||||
#define celt_rsqrt_norm(x) (celt_rsqrt(x))
|
||||
#define celt_cos_norm(x) ((float)cos((.5f*PI)*(x)))
|
||||
#define celt_rcp(x) (1.f/(x))
|
||||
#define celt_div(a,b) ((a)/(b))
|
||||
#define frac_div32(a,b) ((float)(a)/(b))
|
||||
|
||||
#ifdef FLOAT_APPROX
|
||||
|
||||
/* Note: This assumes radix-2 floating point with the exponent at bits 23..30 and an offset of 127
|
||||
denorm, +/- inf and NaN are *not* handled */
|
||||
|
||||
/** Base-2 log approximation (log2(x)). */
|
||||
static OPUS_INLINE float celt_log2(float x)
|
||||
{
|
||||
int integer;
|
||||
float frac;
|
||||
union {
|
||||
float f;
|
||||
opus_uint32 i;
|
||||
} in;
|
||||
in.f = x;
|
||||
integer = (in.i>>23)-127;
|
||||
in.i -= integer<<23;
|
||||
frac = in.f - 1.5f;
|
||||
frac = -0.41445418f + frac*(0.95909232f
|
||||
+ frac*(-0.33951290f + frac*0.16541097f));
|
||||
return 1+integer+frac;
|
||||
}
|
||||
|
||||
/** Base-2 exponential approximation (2^x). */
|
||||
static OPUS_INLINE float celt_exp2(float x)
|
||||
{
|
||||
int integer;
|
||||
float frac;
|
||||
union {
|
||||
float f;
|
||||
opus_uint32 i;
|
||||
} res;
|
||||
integer = floor(x);
|
||||
if (integer < -50)
|
||||
return 0;
|
||||
frac = x-integer;
|
||||
/* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */
|
||||
res.f = 0.99992522f + frac * (0.69583354f
|
||||
+ frac * (0.22606716f + 0.078024523f*frac));
|
||||
res.i = (res.i + (integer<<23)) & 0x7fffffff;
|
||||
return res.f;
|
||||
}
|
||||
|
||||
#else
|
||||
#define celt_log2(x) ((float)(1.442695040888963387*log(x)))
|
||||
#define celt_exp2(x) ((float)exp(0.6931471805599453094*(x)))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
|
||||
#include "opus/celt/os_support.h"
|
||||
|
||||
#ifndef OVERRIDE_CELT_ILOG2
|
||||
/** Integer log in base2. Undefined for zero and negative numbers */
|
||||
static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x)
|
||||
{
|
||||
celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers");
|
||||
return EC_ILOG(x)-1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** Integer log in base2. Defined for zero, but not for negative numbers */
|
||||
static OPUS_INLINE opus_int16 celt_zlog2(opus_val32 x)
|
||||
{
|
||||
return x <= 0 ? 0 : celt_ilog2(x);
|
||||
}
|
||||
|
||||
opus_val16 celt_rsqrt_norm(opus_val32 x);
|
||||
|
||||
opus_val32 celt_sqrt(opus_val32 x);
|
||||
|
||||
opus_val16 celt_cos_norm(opus_val32 x);
|
||||
|
||||
/** Base-2 logarithm approximation (log2(x)). (Q14 input, Q10 output) */
|
||||
static OPUS_INLINE opus_val16 celt_log2(opus_val32 x)
|
||||
{
|
||||
int i;
|
||||
opus_val16 n, frac;
|
||||
/* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605,
|
||||
0.15530808010959576, -0.08556153059057618 */
|
||||
static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401};
|
||||
if (x==0)
|
||||
return -32767;
|
||||
i = celt_ilog2(x);
|
||||
n = VSHR32(x,i-15)-32768-16384;
|
||||
frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4]))))))));
|
||||
return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
K0 = 1
|
||||
K1 = log(2)
|
||||
K2 = 3-4*log(2)
|
||||
K3 = 3*log(2) - 2
|
||||
*/
|
||||
#define D0 16383
|
||||
#define D1 22804
|
||||
#define D2 14819
|
||||
#define D3 10204
|
||||
|
||||
static OPUS_INLINE opus_val32 celt_exp2_frac(opus_val16 x)
|
||||
{
|
||||
opus_val16 frac;
|
||||
frac = SHL16(x, 4);
|
||||
return ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac))))));
|
||||
}
|
||||
/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */
|
||||
static OPUS_INLINE opus_val32 celt_exp2(opus_val16 x)
|
||||
{
|
||||
int integer;
|
||||
opus_val16 frac;
|
||||
integer = SHR16(x,10);
|
||||
if (integer>14)
|
||||
return 0x7f000000;
|
||||
else if (integer < -15)
|
||||
return 0;
|
||||
frac = celt_exp2_frac(x-SHL16(integer,10));
|
||||
return VSHR32(EXTEND32(frac), -integer-2);
|
||||
}
|
||||
|
||||
opus_val32 celt_rcp(opus_val32 x);
|
||||
|
||||
#define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b))
|
||||
|
||||
opus_val32 frac_div32(opus_val32 a, opus_val32 b);
|
||||
|
||||
#define M1 32767
|
||||
#define M2 -21
|
||||
#define M3 -11943
|
||||
#define M4 4936
|
||||
|
||||
/* Atan approximation using a 4th order polynomial. Input is in Q15 format
|
||||
and normalized by pi/4. Output is in Q15 format */
|
||||
static OPUS_INLINE opus_val16 celt_atan01(opus_val16 x)
|
||||
{
|
||||
return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
|
||||
}
|
||||
|
||||
#undef M1
|
||||
#undef M2
|
||||
#undef M3
|
||||
#undef M4
|
||||
|
||||
/* atan2() approximation valid for positive input values */
|
||||
static OPUS_INLINE opus_val16 celt_atan2p(opus_val16 y, opus_val16 x)
|
||||
{
|
||||
if (y < x)
|
||||
{
|
||||
opus_val32 arg;
|
||||
arg = celt_div(SHL32(EXTEND32(y),15),x);
|
||||
if (arg >= 32767)
|
||||
arg = 32767;
|
||||
return SHR16(celt_atan01(EXTRACT16(arg)),1);
|
||||
} else {
|
||||
opus_val32 arg;
|
||||
arg = celt_div(SHL32(EXTEND32(x),15),y);
|
||||
if (arg >= 32767)
|
||||
arg = 32767;
|
||||
return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FIXED_POINT */
|
||||
#endif /* MATHOPS_H */
|
@ -1,341 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2008 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This is a simple MDCT implementation that uses a N/4 complex FFT
|
||||
to do most of the work. It should be relatively straightforward to
|
||||
plug in pretty much and FFT here.
|
||||
|
||||
This replaces the Vorbis FFT (and uses the exact same API), which
|
||||
was a bit too messy and that was ending up duplicating code
|
||||
(might as well use the same FFT everywhere).
|
||||
|
||||
The algorithm is similar to (and inspired from) Fabrice Bellard's
|
||||
MDCT implementation in FFMPEG, but has differences in signs, ordering
|
||||
and scaling in many places.
|
||||
*/
|
||||
|
||||
#ifndef SKIP_CONFIG_H
|
||||
#include "opus/opus_config.h"
|
||||
#endif
|
||||
|
||||
#include "opus/celt/mdct.h"
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/_kiss_fft_guts.h"
|
||||
#include <math.h>
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "opus/celt/mips/mdct_mipsr1.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
|
||||
int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch)
|
||||
{
|
||||
int i;
|
||||
kiss_twiddle_scalar *trig;
|
||||
int shift;
|
||||
int N2=N>>1;
|
||||
l->n = N;
|
||||
l->maxshift = maxshift;
|
||||
for (i=0;i<=maxshift;i++)
|
||||
{
|
||||
if (i==0)
|
||||
l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0, arch);
|
||||
else
|
||||
l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0], arch);
|
||||
#ifndef ENABLE_TI_DSPLIB55
|
||||
if (l->kfft[i]==NULL)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N-(N2>>maxshift))*sizeof(kiss_twiddle_scalar));
|
||||
if (l->trig==NULL)
|
||||
return 0;
|
||||
for (shift=0;shift<=maxshift;shift++)
|
||||
{
|
||||
/* We have enough points that sine isn't necessary */
|
||||
#if defined(FIXED_POINT)
|
||||
#if 1
|
||||
for (i=0;i<N2;i++)
|
||||
trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2+16384),N));
|
||||
#else
|
||||
for (i=0;i<N2;i++)
|
||||
trig[i] = (kiss_twiddle_scalar)MAX32(-32767,MIN32(32767,floor(.5+32768*cos(2*M_PI*(i+.125)/N))));
|
||||
#endif
|
||||
#else
|
||||
for (i=0;i<N2;i++)
|
||||
trig[i] = (kiss_twiddle_scalar)cos(2*PI*(i+.125)/N);
|
||||
#endif
|
||||
trig += N2;
|
||||
N2 >>= 1;
|
||||
N >>= 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void clt_mdct_clear(mdct_lookup *l, int arch)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<=l->maxshift;i++)
|
||||
opus_fft_free(l->kfft[i], arch);
|
||||
opus_free((kiss_twiddle_scalar*)l->trig);
|
||||
}
|
||||
|
||||
#endif /* CUSTOM_MODES */
|
||||
|
||||
/* Forward MDCT trashes the input array */
|
||||
#ifndef OVERRIDE_clt_mdct_forward
|
||||
void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window, int overlap, int shift, int stride, int arch)
|
||||
{
|
||||
int i;
|
||||
int N, N2, N4;
|
||||
VARDECL(kiss_fft_scalar, f);
|
||||
VARDECL(kiss_fft_cpx, f2);
|
||||
const kiss_fft_state *st = l->kfft[shift];
|
||||
const kiss_twiddle_scalar *trig;
|
||||
opus_val16 scale;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
/* Allows us to scale with MULT16_32_Q16(), which is faster than
|
||||
MULT16_32_Q15() on ARM. */
|
||||
int scale_shift = st->scale_shift-1;
|
||||
#endif
|
||||
SAVE_STACK;
|
||||
(void)arch;
|
||||
scale = st->scale;
|
||||
|
||||
N = l->n;
|
||||
trig = l->trig;
|
||||
for (i=0;i<shift;i++)
|
||||
{
|
||||
N >>= 1;
|
||||
trig += N;
|
||||
}
|
||||
N2 = N>>1;
|
||||
N4 = N>>2;
|
||||
|
||||
ALLOC(f, N2, kiss_fft_scalar);
|
||||
ALLOC(f2, N4, kiss_fft_cpx);
|
||||
|
||||
/* Consider the input to be composed of four blocks: [a, b, c, d] */
|
||||
/* Window, shuffle, fold */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
|
||||
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
|
||||
for(i=0;i<((overlap+3)>>2);i++)
|
||||
{
|
||||
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
|
||||
*yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
|
||||
*yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]);
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
wp1+=2;
|
||||
wp2-=2;
|
||||
}
|
||||
wp1 = window;
|
||||
wp2 = window+overlap-1;
|
||||
for(;i<N4-((overlap+3)>>2);i++)
|
||||
{
|
||||
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
||||
*yp++ = *xp2;
|
||||
*yp++ = *xp1;
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
}
|
||||
for(;i<N4;i++)
|
||||
{
|
||||
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
||||
*yp++ = -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);
|
||||
*yp++ = MULT16_32_Q15(*wp2, *xp1) + MULT16_32_Q15(*wp1, xp2[N2]);
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
wp1+=2;
|
||||
wp2-=2;
|
||||
}
|
||||
}
|
||||
/* Pre-rotation */
|
||||
{
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
kiss_fft_cpx yc;
|
||||
kiss_twiddle_scalar t0, t1;
|
||||
kiss_fft_scalar re, im, yr, yi;
|
||||
t0 = t[i];
|
||||
t1 = t[N4+i];
|
||||
re = *yp++;
|
||||
im = *yp++;
|
||||
yr = S_MUL(re,t0) - S_MUL(im,t1);
|
||||
yi = S_MUL(im,t0) + S_MUL(re,t1);
|
||||
yc.r = yr;
|
||||
yc.i = yi;
|
||||
yc.r = PSHR32(MULT16_32_Q16(scale, yc.r), scale_shift);
|
||||
yc.i = PSHR32(MULT16_32_Q16(scale, yc.i), scale_shift);
|
||||
f2[st->bitrev[i]] = yc;
|
||||
}
|
||||
}
|
||||
|
||||
/* N/4 complex FFT, does not downscale anymore */
|
||||
opus_fft_impl(st, f2);
|
||||
|
||||
/* Post-rotate */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
kiss_fft_scalar yr, yi;
|
||||
yr = S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]);
|
||||
yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]);
|
||||
*yp1 = yr;
|
||||
*yp2 = yi;
|
||||
fp++;
|
||||
yp1 += 2*stride;
|
||||
yp2 -= 2*stride;
|
||||
}
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
#endif /* OVERRIDE_clt_mdct_forward */
|
||||
|
||||
#ifndef OVERRIDE_clt_mdct_backward
|
||||
void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)
|
||||
{
|
||||
int i;
|
||||
int N, N2, N4;
|
||||
const kiss_twiddle_scalar *trig;
|
||||
(void) arch;
|
||||
|
||||
N = l->n;
|
||||
trig = l->trig;
|
||||
for (i=0;i<shift;i++)
|
||||
{
|
||||
N >>= 1;
|
||||
trig += N;
|
||||
}
|
||||
N2 = N>>1;
|
||||
N4 = N>>2;
|
||||
|
||||
/* Pre-rotate */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);
|
||||
const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
|
||||
const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
int rev;
|
||||
kiss_fft_scalar yr, yi;
|
||||
rev = *bitrev++;
|
||||
yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);
|
||||
yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);
|
||||
/* We swap real and imag because we use an FFT instead of an IFFT. */
|
||||
yp[2*rev+1] = yr;
|
||||
yp[2*rev] = yi;
|
||||
/* Storing the pre-rotation directly in the bitrev order. */
|
||||
xp1+=2*stride;
|
||||
xp2-=2*stride;
|
||||
}
|
||||
}
|
||||
|
||||
opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)));
|
||||
|
||||
/* Post-rotate and de-shuffle from both ends of the buffer at once to make
|
||||
it in-place. */
|
||||
{
|
||||
kiss_fft_scalar * yp0 = out+(overlap>>1);
|
||||
kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
/* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
|
||||
middle pair will be computed twice. */
|
||||
for(i=0;i<(N4+1)>>1;i++)
|
||||
{
|
||||
kiss_fft_scalar re, im, yr, yi;
|
||||
kiss_twiddle_scalar t0, t1;
|
||||
/* We swap real and imag because we're using an FFT instead of an IFFT. */
|
||||
re = yp0[1];
|
||||
im = yp0[0];
|
||||
t0 = t[i];
|
||||
t1 = t[N4+i];
|
||||
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||
yr = S_MUL(re,t0) + S_MUL(im,t1);
|
||||
yi = S_MUL(re,t1) - S_MUL(im,t0);
|
||||
/* We swap real and imag because we're using an FFT instead of an IFFT. */
|
||||
re = yp1[1];
|
||||
im = yp1[0];
|
||||
yp0[0] = yr;
|
||||
yp1[1] = yi;
|
||||
|
||||
t0 = t[(N4-i-1)];
|
||||
t1 = t[(N2-i-1)];
|
||||
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||
yr = S_MUL(re,t0) + S_MUL(im,t1);
|
||||
yi = S_MUL(re,t1) - S_MUL(im,t0);
|
||||
yp1[0] = yr;
|
||||
yp0[1] = yi;
|
||||
yp0 += 2;
|
||||
yp1 -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mirror on both sides for TDAC */
|
||||
{
|
||||
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||
const opus_val16 * OPUS_RESTRICT wp1 = window;
|
||||
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
|
||||
|
||||
for(i = 0; i < overlap/2; i++)
|
||||
{
|
||||
kiss_fft_scalar x1, x2;
|
||||
x1 = *xp1;
|
||||
x2 = *yp1;
|
||||
*yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
|
||||
*xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
|
||||
wp1++;
|
||||
wp2--;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* OVERRIDE_clt_mdct_backward */
|
@ -1,112 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2008 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This is a simple MDCT implementation that uses a N/4 complex FFT
|
||||
to do most of the work. It should be relatively straightforward to
|
||||
plug in pretty much and FFT here.
|
||||
|
||||
This replaces the Vorbis FFT (and uses the exact same API), which
|
||||
was a bit too messy and that was ending up duplicating code
|
||||
(might as well use the same FFT everywhere).
|
||||
|
||||
The algorithm is similar to (and inspired from) Fabrice Bellard's
|
||||
MDCT implementation in FFMPEG, but has differences in signs, ordering
|
||||
and scaling in many places.
|
||||
*/
|
||||
|
||||
#ifndef MDCT_H
|
||||
#define MDCT_H
|
||||
|
||||
#include "opus/opus_defines.h"
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
typedef struct {
|
||||
int n;
|
||||
int maxshift;
|
||||
const kiss_fft_state *kfft[4];
|
||||
const kiss_twiddle_scalar * OPUS_RESTRICT trig;
|
||||
} mdct_lookup;
|
||||
|
||||
#if defined(HAVE_ARM_NE10)
|
||||
#include "opus/celt/arm/mdct_arm.h"
|
||||
#endif
|
||||
|
||||
|
||||
int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch);
|
||||
void clt_mdct_clear(mdct_lookup *l, int arch);
|
||||
|
||||
/** Compute a forward MDCT and scale by 4/N, trashes the input array */
|
||||
void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window, int overlap,
|
||||
int shift, int stride, int arch);
|
||||
|
||||
/** Compute a backward MDCT (no scaling) and performs weighted overlap-add
|
||||
(scales implicitly by 1/2) */
|
||||
void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 * OPUS_RESTRICT window,
|
||||
int overlap, int shift, int stride, int arch);
|
||||
|
||||
#if !defined(OVERRIDE_OPUS_MDCT)
|
||||
/* Is run-time CPU detection enabled on this platform? */
|
||||
#if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10)
|
||||
|
||||
extern void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(
|
||||
const mdct_lookup *l, kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
|
||||
int overlap, int shift, int stride, int arch);
|
||||
|
||||
#define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
|
||||
((*CLT_MDCT_FORWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \
|
||||
_window, _overlap, _shift, \
|
||||
_stride, _arch))
|
||||
|
||||
extern void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(
|
||||
const mdct_lookup *l, kiss_fft_scalar *in,
|
||||
kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
|
||||
int overlap, int shift, int stride, int arch);
|
||||
|
||||
#define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
|
||||
(*CLT_MDCT_BACKWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \
|
||||
_window, _overlap, _shift, \
|
||||
_stride, _arch)
|
||||
|
||||
#else /* if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) */
|
||||
|
||||
#define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
|
||||
clt_mdct_forward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)
|
||||
|
||||
#define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
|
||||
clt_mdct_backward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)
|
||||
|
||||
#endif /* end if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) && !defined(FIXED_POINT) */
|
||||
#endif /* end if !defined(OVERRIDE_OPUS_MDCT) */
|
||||
|
||||
#endif
|
@ -1,48 +0,0 @@
|
||||
/* Copyright (c) 2001-2008 Timothy B. Terriberry
|
||||
Copyright (c) 2008-2009 Xiph.Org Foundation */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(_mfrngcode_H)
|
||||
# define _mfrngcode_H (1)
|
||||
# include "opus/celt/entcode.h"
|
||||
|
||||
/*Constants used by the entropy encoder/decoder.*/
|
||||
|
||||
/*The number of bits to output at a time.*/
|
||||
# define EC_SYM_BITS (8)
|
||||
/*The total number of bits in each of the state registers.*/
|
||||
# define EC_CODE_BITS (32)
|
||||
/*The maximum symbol value.*/
|
||||
# define EC_SYM_MAX ((1U<<EC_SYM_BITS)-1)
|
||||
/*Bits to shift by to move a symbol into the high-order position.*/
|
||||
# define EC_CODE_SHIFT (EC_CODE_BITS-EC_SYM_BITS-1)
|
||||
/*Carry bit of the high-order range symbol.*/
|
||||
# define EC_CODE_TOP (((opus_uint32)1U)<<(EC_CODE_BITS-1))
|
||||
/*Low-order bit of the high-order range symbol.*/
|
||||
# define EC_CODE_BOT (EC_CODE_TOP>>EC_SYM_BITS)
|
||||
/*The number of bits available for the last, partial symbol in the code field.*/
|
||||
# define EC_CODE_EXTRA ((EC_CODE_BITS-2)%EC_SYM_BITS+1)
|
||||
#endif
|
@ -1,148 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2010 Xiph.Org Foundation
|
||||
Copyright (c) 2008 Gregory Maxwell
|
||||
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __CELT_MIPSR1_H__
|
||||
#define __CELT_MIPSR1_H__
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#define CELT_C
|
||||
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/mdct.h"
|
||||
#include <math.h>
|
||||
#include "opus/celt/celt.h"
|
||||
#include "opus/celt/pitch.h"
|
||||
#include "opus/celt/bands.h"
|
||||
#include "opus/celt/modes.h"
|
||||
#include "opus/celt/entcode.h"
|
||||
#include "opus/celt/quant_bands.h"
|
||||
#include "opus/celt/rate.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/float_cast.h"
|
||||
#include <stdarg.h>
|
||||
#include "opus/celt/celt_lpc.h"
|
||||
#include "opus/celt/vq.h"
|
||||
|
||||
#define OVERRIDE_comb_filter
|
||||
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
|
||||
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
|
||||
const opus_val16 *window, int overlap, int arch)
|
||||
{
|
||||
int i;
|
||||
opus_val32 x0, x1, x2, x3, x4;
|
||||
|
||||
(void)arch;
|
||||
|
||||
/* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
|
||||
opus_val16 g00, g01, g02, g10, g11, g12;
|
||||
static const opus_val16 gains[3][3] = {
|
||||
{QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
|
||||
{QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
|
||||
{QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
|
||||
|
||||
if (g0==0 && g1==0)
|
||||
{
|
||||
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
|
||||
if (x!=y)
|
||||
OPUS_MOVE(y, x, N);
|
||||
return;
|
||||
}
|
||||
|
||||
g00 = MULT16_16_P15(g0, gains[tapset0][0]);
|
||||
g01 = MULT16_16_P15(g0, gains[tapset0][1]);
|
||||
g02 = MULT16_16_P15(g0, gains[tapset0][2]);
|
||||
g10 = MULT16_16_P15(g1, gains[tapset1][0]);
|
||||
g11 = MULT16_16_P15(g1, gains[tapset1][1]);
|
||||
g12 = MULT16_16_P15(g1, gains[tapset1][2]);
|
||||
x1 = x[-T1+1];
|
||||
x2 = x[-T1 ];
|
||||
x3 = x[-T1-1];
|
||||
x4 = x[-T1-2];
|
||||
/* If the filter didn't change, we don't need the overlap */
|
||||
if (g0==g1 && T0==T1 && tapset0==tapset1)
|
||||
overlap=0;
|
||||
|
||||
for (i=0;i<overlap;i++)
|
||||
{
|
||||
opus_val16 f;
|
||||
opus_val32 res;
|
||||
f = MULT16_16_Q15(window[i],window[i]);
|
||||
x0= x[i-T1+2];
|
||||
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g00)), "r" ((int)x[i-T0]));
|
||||
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g01)), "r" ((int)ADD32(x[i-T0-1],x[i-T0+1])));
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g02)), "r" ((int)ADD32(x[i-T0-2],x[i-T0+2])));
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g10)), "r" ((int)x2));
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g11)), "r" ((int)ADD32(x3,x1)));
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g12)), "r" ((int)ADD32(x4,x0)));
|
||||
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (res): "i" (15));
|
||||
|
||||
y[i] = x[i] + res;
|
||||
|
||||
x4=x3;
|
||||
x3=x2;
|
||||
x2=x1;
|
||||
x1=x0;
|
||||
}
|
||||
|
||||
x4 = x[i-T1-2];
|
||||
x3 = x[i-T1-1];
|
||||
x2 = x[i-T1];
|
||||
x1 = x[i-T1+1];
|
||||
|
||||
if (g1==0)
|
||||
{
|
||||
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
|
||||
if (x!=y)
|
||||
OPUS_MOVE(y+overlap, x+overlap, N-overlap);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=overlap;i<N;i++)
|
||||
{
|
||||
opus_val32 res;
|
||||
x0=x[i-T1+2];
|
||||
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)g10), "r" ((int)x2));
|
||||
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)g11), "r" ((int)ADD32(x3,x1)));
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)g12), "r" ((int)ADD32(x4,x0)));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (res): "i" (15));
|
||||
y[i] = x[i] + res;
|
||||
x4=x3;
|
||||
x3=x2;
|
||||
x2=x1;
|
||||
x1=x0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __CELT_MIPSR1_H__ */
|
@ -1,167 +0,0 @@
|
||||
/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.*/
|
||||
|
||||
#ifndef KISS_FFT_MIPSR1_H
|
||||
#define KISS_FFT_MIPSR1_H
|
||||
|
||||
#if !defined(KISS_FFT_GUTS_H)
|
||||
#error "This file should only be included from _kiss_fft_guts.h"
|
||||
#endif
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
|
||||
#define S_MUL_ADD(a, b, c, d) (S_MUL(a,b)+S_MUL(c,d))
|
||||
#define S_MUL_SUB(a, b, c, d) (S_MUL(a,b)-S_MUL(c,d))
|
||||
|
||||
#undef S_MUL_ADD
|
||||
static inline int S_MUL_ADD(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef S_MUL_SUB
|
||||
static inline int S_MUL_SUB(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef C_MUL
|
||||
# define C_MUL(m,a,b) (m=C_MUL_fun(a,b))
|
||||
static inline kiss_fft_cpx C_MUL_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) {
|
||||
kiss_fft_cpx m;
|
||||
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15));
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15));
|
||||
|
||||
return m;
|
||||
}
|
||||
#undef C_MULC
|
||||
# define C_MULC(m,a,b) (m=C_MULC_fun(a,b))
|
||||
static inline kiss_fft_cpx C_MULC_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) {
|
||||
kiss_fft_cpx m;
|
||||
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15));
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
#endif /* FIXED_POINT */
|
||||
|
||||
#define OVERRIDE_kf_bfly5
|
||||
static void kf_bfly5(
|
||||
kiss_fft_cpx * Fout,
|
||||
const size_t fstride,
|
||||
const kiss_fft_state *st,
|
||||
int m,
|
||||
int N,
|
||||
int mm
|
||||
)
|
||||
{
|
||||
kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
|
||||
int i, u;
|
||||
kiss_fft_cpx scratch[13];
|
||||
|
||||
const kiss_twiddle_cpx *tw;
|
||||
kiss_twiddle_cpx ya,yb;
|
||||
kiss_fft_cpx * Fout_beg = Fout;
|
||||
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
ya.r = 10126;
|
||||
ya.i = -31164;
|
||||
yb.r = -26510;
|
||||
yb.i = -19261;
|
||||
#else
|
||||
ya = st->twiddles[fstride*m];
|
||||
yb = st->twiddles[fstride*2*m];
|
||||
#endif
|
||||
|
||||
tw=st->twiddles;
|
||||
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
Fout = Fout_beg + i*mm;
|
||||
Fout0=Fout;
|
||||
Fout1=Fout0+m;
|
||||
Fout2=Fout0+2*m;
|
||||
Fout3=Fout0+3*m;
|
||||
Fout4=Fout0+4*m;
|
||||
|
||||
/* For non-custom modes, m is guaranteed to be a multiple of 4. */
|
||||
for ( u=0; u<m; ++u ) {
|
||||
scratch[0] = *Fout0;
|
||||
|
||||
|
||||
C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
|
||||
C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
|
||||
C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
|
||||
C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
|
||||
|
||||
C_ADD( scratch[7],scratch[1],scratch[4]);
|
||||
C_SUB( scratch[10],scratch[1],scratch[4]);
|
||||
C_ADD( scratch[8],scratch[2],scratch[3]);
|
||||
C_SUB( scratch[9],scratch[2],scratch[3]);
|
||||
|
||||
Fout0->r += scratch[7].r + scratch[8].r;
|
||||
Fout0->i += scratch[7].i + scratch[8].i;
|
||||
scratch[5].r = scratch[0].r + S_MUL_ADD(scratch[7].r,ya.r,scratch[8].r,yb.r);
|
||||
scratch[5].i = scratch[0].i + S_MUL_ADD(scratch[7].i,ya.r,scratch[8].i,yb.r);
|
||||
|
||||
scratch[6].r = S_MUL_ADD(scratch[10].i,ya.i,scratch[9].i,yb.i);
|
||||
scratch[6].i = -S_MUL_ADD(scratch[10].r,ya.i,scratch[9].r,yb.i);
|
||||
|
||||
C_SUB(*Fout1,scratch[5],scratch[6]);
|
||||
C_ADD(*Fout4,scratch[5],scratch[6]);
|
||||
|
||||
scratch[11].r = scratch[0].r + S_MUL_ADD(scratch[7].r,yb.r,scratch[8].r,ya.r);
|
||||
scratch[11].i = scratch[0].i + S_MUL_ADD(scratch[7].i,yb.r,scratch[8].i,ya.r);
|
||||
|
||||
scratch[12].r = S_MUL_SUB(scratch[9].i,ya.i,scratch[10].i,yb.i);
|
||||
scratch[12].i = S_MUL_SUB(scratch[10].r,yb.i,scratch[9].r,ya.i);
|
||||
|
||||
C_ADD(*Fout2,scratch[11],scratch[12]);
|
||||
C_SUB(*Fout3,scratch[11],scratch[12]);
|
||||
|
||||
++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* KISS_FFT_MIPSR1_H */
|
@ -1,286 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2008 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* This is a simple MDCT implementation that uses a N/4 complex FFT
|
||||
to do most of the work. It should be relatively straightforward to
|
||||
plug in pretty much and FFT here.
|
||||
|
||||
This replaces the Vorbis FFT (and uses the exact same API), which
|
||||
was a bit too messy and that was ending up duplicating code
|
||||
(might as well use the same FFT everywhere).
|
||||
|
||||
The algorithm is similar to (and inspired from) Fabrice Bellard's
|
||||
MDCT implementation in FFMPEG, but has differences in signs, ordering
|
||||
and scaling in many places.
|
||||
*/
|
||||
#ifndef __MDCT_MIPSR1_H__
|
||||
#define __MDCT_MIPSR1_H__
|
||||
|
||||
#ifndef SKIP_CONFIG_H
|
||||
#include "opus/opus_config.h"
|
||||
#endif
|
||||
|
||||
#include "opus/celt/mdct.h"
|
||||
#include "opus/celt/kiss_fft.h"
|
||||
#include "opus/celt/_kiss_fft_guts.h"
|
||||
#include <math.h>
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
|
||||
/* Forward MDCT trashes the input array */
|
||||
#define OVERRIDE_clt_mdct_forward
|
||||
void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 *window, int overlap, int shift, int stride, int arch)
|
||||
{
|
||||
int i;
|
||||
int N, N2, N4;
|
||||
VARDECL(kiss_fft_scalar, f);
|
||||
VARDECL(kiss_fft_cpx, f2);
|
||||
const kiss_fft_state *st = l->kfft[shift];
|
||||
const kiss_twiddle_scalar *trig;
|
||||
opus_val16 scale;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
/* Allows us to scale with MULT16_32_Q16(), which is faster than
|
||||
MULT16_32_Q15() on ARM. */
|
||||
int scale_shift = st->scale_shift-1;
|
||||
#endif
|
||||
|
||||
(void)arch;
|
||||
|
||||
SAVE_STACK;
|
||||
scale = st->scale;
|
||||
|
||||
N = l->n;
|
||||
trig = l->trig;
|
||||
for (i=0;i<shift;i++)
|
||||
{
|
||||
N >>= 1;
|
||||
trig += N;
|
||||
}
|
||||
N2 = N>>1;
|
||||
N4 = N>>2;
|
||||
|
||||
ALLOC(f, N2, kiss_fft_scalar);
|
||||
ALLOC(f2, N4, kiss_fft_cpx);
|
||||
|
||||
/* Consider the input to be composed of four blocks: [a, b, c, d] */
|
||||
/* Window, shuffle, fold */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
|
||||
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
|
||||
for(i=0;i<((overlap+3)>>2);i++)
|
||||
{
|
||||
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
|
||||
*yp++ = S_MUL_ADD(*wp2, xp1[N2],*wp1,*xp2);
|
||||
*yp++ = S_MUL_SUB(*wp1, *xp1,*wp2, xp2[-N2]);
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
wp1+=2;
|
||||
wp2-=2;
|
||||
}
|
||||
wp1 = window;
|
||||
wp2 = window+overlap-1;
|
||||
for(;i<N4-((overlap+3)>>2);i++)
|
||||
{
|
||||
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
||||
*yp++ = *xp2;
|
||||
*yp++ = *xp1;
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
}
|
||||
for(;i<N4;i++)
|
||||
{
|
||||
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
||||
*yp++ = S_MUL_SUB(*wp2, *xp2, *wp1, xp1[-N2]);
|
||||
*yp++ = S_MUL_ADD(*wp2, *xp1, *wp1, xp2[N2]);
|
||||
xp1+=2;
|
||||
xp2-=2;
|
||||
wp1+=2;
|
||||
wp2-=2;
|
||||
}
|
||||
}
|
||||
/* Pre-rotation */
|
||||
{
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
kiss_fft_cpx yc;
|
||||
kiss_twiddle_scalar t0, t1;
|
||||
kiss_fft_scalar re, im, yr, yi;
|
||||
t0 = t[i];
|
||||
t1 = t[N4+i];
|
||||
re = *yp++;
|
||||
im = *yp++;
|
||||
|
||||
yr = S_MUL_SUB(re,t0,im,t1);
|
||||
yi = S_MUL_ADD(im,t0,re,t1);
|
||||
|
||||
yc.r = yr;
|
||||
yc.i = yi;
|
||||
yc.r = PSHR32(MULT16_32_Q16(scale, yc.r), scale_shift);
|
||||
yc.i = PSHR32(MULT16_32_Q16(scale, yc.i), scale_shift);
|
||||
f2[st->bitrev[i]] = yc;
|
||||
}
|
||||
}
|
||||
|
||||
/* N/4 complex FFT, does not downscale anymore */
|
||||
opus_fft_impl(st, f2);
|
||||
|
||||
/* Post-rotate */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
kiss_fft_scalar yr, yi;
|
||||
yr = S_MUL_SUB(fp->i,t[N4+i] , fp->r,t[i]);
|
||||
yi = S_MUL_ADD(fp->r,t[N4+i] ,fp->i,t[i]);
|
||||
*yp1 = yr;
|
||||
*yp2 = yi;
|
||||
fp++;
|
||||
yp1 += 2*stride;
|
||||
yp2 -= 2*stride;
|
||||
}
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
#define OVERRIDE_clt_mdct_backward
|
||||
void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
|
||||
const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)
|
||||
{
|
||||
int i;
|
||||
int N, N2, N4;
|
||||
const kiss_twiddle_scalar *trig;
|
||||
|
||||
(void)arch;
|
||||
|
||||
N = l->n;
|
||||
trig = l->trig;
|
||||
for (i=0;i<shift;i++)
|
||||
{
|
||||
N >>= 1;
|
||||
trig += N;
|
||||
}
|
||||
N2 = N>>1;
|
||||
N4 = N>>2;
|
||||
|
||||
/* Pre-rotate */
|
||||
{
|
||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
|
||||
const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);
|
||||
const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
|
||||
const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;
|
||||
for(i=0;i<N4;i++)
|
||||
{
|
||||
int rev;
|
||||
kiss_fft_scalar yr, yi;
|
||||
rev = *bitrev++;
|
||||
yr = S_MUL_ADD(*xp2, t[i] , *xp1, t[N4+i]);
|
||||
yi = S_MUL_SUB(*xp1, t[i] , *xp2, t[N4+i]);
|
||||
/* We swap real and imag because we use an FFT instead of an IFFT. */
|
||||
yp[2*rev+1] = yr;
|
||||
yp[2*rev] = yi;
|
||||
/* Storing the pre-rotation directly in the bitrev order. */
|
||||
xp1+=2*stride;
|
||||
xp2-=2*stride;
|
||||
}
|
||||
}
|
||||
|
||||
opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)));
|
||||
|
||||
/* Post-rotate and de-shuffle from both ends of the buffer at once to make
|
||||
it in-place. */
|
||||
{
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1);
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2;
|
||||
const kiss_twiddle_scalar *t = &trig[0];
|
||||
/* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
|
||||
middle pair will be computed twice. */
|
||||
for(i=0;i<(N4+1)>>1;i++)
|
||||
{
|
||||
kiss_fft_scalar re, im, yr, yi;
|
||||
kiss_twiddle_scalar t0, t1;
|
||||
/* We swap real and imag because we're using an FFT instead of an IFFT. */
|
||||
re = yp0[1];
|
||||
im = yp0[0];
|
||||
t0 = t[i];
|
||||
t1 = t[N4+i];
|
||||
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||
yr = S_MUL_ADD(re,t0 , im,t1);
|
||||
yi = S_MUL_SUB(re,t1 , im,t0);
|
||||
/* We swap real and imag because we're using an FFT instead of an IFFT. */
|
||||
re = yp1[1];
|
||||
im = yp1[0];
|
||||
yp0[0] = yr;
|
||||
yp1[1] = yi;
|
||||
|
||||
t0 = t[(N4-i-1)];
|
||||
t1 = t[(N2-i-1)];
|
||||
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||
yr = S_MUL_ADD(re,t0,im,t1);
|
||||
yi = S_MUL_SUB(re,t1,im,t0);
|
||||
yp1[0] = yr;
|
||||
yp0[1] = yi;
|
||||
yp0 += 2;
|
||||
yp1 -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mirror on both sides for TDAC */
|
||||
{
|
||||
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
|
||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||
const opus_val16 * OPUS_RESTRICT wp1 = window;
|
||||
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
|
||||
|
||||
for(i = 0; i < overlap/2; i++)
|
||||
{
|
||||
kiss_fft_scalar x1, x2;
|
||||
x1 = *xp1;
|
||||
x2 = *yp1;
|
||||
*yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
|
||||
*xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
|
||||
wp1++;
|
||||
wp2--;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* __MDCT_MIPSR1_H__ */
|
@ -1,122 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __VQ_MIPSR1_H__
|
||||
#define __VQ_MIPSR1_H__
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/mathops.h"
|
||||
#include "opus/celt/arch.h"
|
||||
|
||||
static unsigned extract_collapse_mask(int *iy, int N, int B);
|
||||
static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X, int N, opus_val32 Ryy, opus_val16 gain);
|
||||
static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);
|
||||
static void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch);
|
||||
|
||||
#define OVERRIDE_vq_exp_rotation1
|
||||
static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
|
||||
{
|
||||
int i;
|
||||
opus_val16 ms;
|
||||
celt_norm *Xptr;
|
||||
Xptr = X;
|
||||
ms = NEG16(s);
|
||||
for (i=0;i<len-stride;i++)
|
||||
{
|
||||
celt_norm x1, x2;
|
||||
x1 = Xptr[0];
|
||||
x2 = Xptr[stride];
|
||||
Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15));
|
||||
*Xptr++ = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));
|
||||
}
|
||||
Xptr = &X[len-2*stride-1];
|
||||
for (i=len-2*stride-1;i>=0;i--)
|
||||
{
|
||||
celt_norm x1, x2;
|
||||
x1 = Xptr[0];
|
||||
x2 = Xptr[stride];
|
||||
Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15));
|
||||
*Xptr-- = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));
|
||||
}
|
||||
}
|
||||
|
||||
#define OVERRIDE_renormalise_vector
|
||||
|
||||
#define renormalise_vector(X, N, gain, arch) \
|
||||
(renormalise_vector_mips(X, N, gain, arch))
|
||||
|
||||
void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch)
|
||||
{
|
||||
int i;
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
int k;
|
||||
#endif
|
||||
opus_val32 E = EPSILON;
|
||||
opus_val16 g;
|
||||
opus_val32 t;
|
||||
celt_norm *xptr = X;
|
||||
int X0, X1;
|
||||
|
||||
(void)arch;
|
||||
|
||||
asm volatile("mult $ac1, $0, $0");
|
||||
asm volatile("MTLO %0, $ac1" : :"r" (E));
|
||||
/*if(N %4)
|
||||
printf("error");*/
|
||||
for (i=0;i<N-2;i+=2)
|
||||
{
|
||||
X0 = (int)*xptr++;
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" (X0), "r" (X0));
|
||||
|
||||
X1 = (int)*xptr++;
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" (X1), "r" (X1));
|
||||
}
|
||||
|
||||
for (;i<N;i++)
|
||||
{
|
||||
X0 = (int)*xptr++;
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" (X0), "r" (X0));
|
||||
}
|
||||
|
||||
asm volatile("MFLO %0, $ac1" : "=r" (E));
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
k = celt_ilog2(E)>>1;
|
||||
#endif
|
||||
t = VSHR32(E, 2*(k-7));
|
||||
g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
|
||||
|
||||
xptr = X;
|
||||
for (i=0;i<N;i++)
|
||||
{
|
||||
*xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1));
|
||||
xptr++;
|
||||
}
|
||||
/*return celt_sqrt(E);*/
|
||||
}
|
||||
|
||||
#endif /* __VQ_MIPSR1_H__ */
|
@ -1,439 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (c) 2008 Gregory Maxwell
|
||||
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "opus/opus_config.h"
|
||||
|
||||
#include "opus/celt/celt.h"
|
||||
#include "opus/celt/modes.h"
|
||||
#include "opus/celt/rate.h"
|
||||
#include "opus/celt/os_support.h"
|
||||
#include "opus/celt/stack_alloc.h"
|
||||
#include "opus/celt/quant_bands.h"
|
||||
#include "opus/celt/cpu_support.h"
|
||||
|
||||
static const opus_int16 eband5ms[] = {
|
||||
/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
|
||||
};
|
||||
|
||||
/* Alternate tuning (partially derived from Vorbis) */
|
||||
#define BITALLOC_SIZE 11
|
||||
/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
|
||||
static const unsigned char band_allocation[] = {
|
||||
/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0,
|
||||
118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0,
|
||||
126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0,
|
||||
134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1,
|
||||
144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
|
||||
152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1,
|
||||
162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1,
|
||||
172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,
|
||||
200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
|
||||
};
|
||||
|
||||
#ifndef CUSTOM_MODES_ONLY
|
||||
#ifdef OPUS_FIXED_POINT
|
||||
#include "opus/celt/static_modes_fixed.h"
|
||||
#else
|
||||
#include "opus/celt/static_modes_float.h"
|
||||
#endif
|
||||
#endif /* CUSTOM_MODES_ONLY */
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.141592653
|
||||
#endif
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
|
||||
/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
|
||||
Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
|
||||
#define BARK_BANDS 25
|
||||
static const opus_int16 bark_freq[BARK_BANDS+1] = {
|
||||
0, 100, 200, 300, 400,
|
||||
510, 630, 770, 920, 1080,
|
||||
1270, 1480, 1720, 2000, 2320,
|
||||
2700, 3150, 3700, 4400, 5300,
|
||||
6400, 7700, 9500, 12000, 15500,
|
||||
20000};
|
||||
|
||||
static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands)
|
||||
{
|
||||
opus_int16 *eBands;
|
||||
int i, j, lin, low, high, nBark, offset=0;
|
||||
|
||||
/* All modes that have 2.5 ms short blocks use the same definition */
|
||||
if (Fs == 400*(opus_int32)frame_size)
|
||||
{
|
||||
*nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
|
||||
eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1));
|
||||
for (i=0;i<*nbEBands+1;i++)
|
||||
eBands[i] = eband5ms[i];
|
||||
return eBands;
|
||||
}
|
||||
/* Find the number of critical bands supported by our sampling rate */
|
||||
for (nBark=1;nBark<BARK_BANDS;nBark++)
|
||||
if (bark_freq[nBark+1]*2 >= Fs)
|
||||
break;
|
||||
|
||||
/* Find where the linear part ends (i.e. where the spacing is more than min_width */
|
||||
for (lin=0;lin<nBark;lin++)
|
||||
if (bark_freq[lin+1]-bark_freq[lin] >= res)
|
||||
break;
|
||||
|
||||
low = (bark_freq[lin]+res/2)/res;
|
||||
high = nBark-lin;
|
||||
*nbEBands = low+high;
|
||||
eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2));
|
||||
|
||||
if (eBands==NULL)
|
||||
return NULL;
|
||||
|
||||
/* Linear spacing (min_width) */
|
||||
for (i=0;i<low;i++)
|
||||
eBands[i] = i;
|
||||
if (low>0)
|
||||
offset = eBands[low-1]*res - bark_freq[lin-1];
|
||||
/* Spacing follows critical bands */
|
||||
for (i=0;i<high;i++)
|
||||
{
|
||||
int target = bark_freq[lin+i];
|
||||
/* Round to an even value */
|
||||
eBands[i+low] = (target+offset/2+res)/(2*res)*2;
|
||||
offset = eBands[i+low]*res - target;
|
||||
}
|
||||
/* Enforce the minimum spacing at the boundary */
|
||||
for (i=0;i<*nbEBands;i++)
|
||||
if (eBands[i] < i)
|
||||
eBands[i] = i;
|
||||
/* Round to an even value */
|
||||
eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
|
||||
if (eBands[*nbEBands] > frame_size)
|
||||
eBands[*nbEBands] = frame_size;
|
||||
for (i=1;i<*nbEBands-1;i++)
|
||||
{
|
||||
if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
|
||||
{
|
||||
eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
|
||||
}
|
||||
}
|
||||
/* Remove any empty bands. */
|
||||
for (i=j=0;i<*nbEBands;i++)
|
||||
if(eBands[i+1]>eBands[j])
|
||||
eBands[++j]=eBands[i+1];
|
||||
*nbEBands=j;
|
||||
|
||||
for (i=1;i<*nbEBands;i++)
|
||||
{
|
||||
/* Every band must be smaller than the last band. */
|
||||
celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
|
||||
/* Each band must be no larger than twice the size of the previous one. */
|
||||
celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
|
||||
}
|
||||
|
||||
return eBands;
|
||||
}
|
||||
|
||||
static void compute_allocation_table(CELTMode *mode)
|
||||
{
|
||||
int i, j;
|
||||
unsigned char *allocVectors;
|
||||
int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
|
||||
|
||||
mode->nbAllocVectors = BITALLOC_SIZE;
|
||||
allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
|
||||
if (allocVectors==NULL)
|
||||
return;
|
||||
|
||||
/* Check for standard mode */
|
||||
if (mode->Fs == 400*(opus_int32)mode->shortMdctSize)
|
||||
{
|
||||
for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
|
||||
allocVectors[i] = band_allocation[i];
|
||||
mode->allocVectors = allocVectors;
|
||||
return;
|
||||
}
|
||||
/* If not the standard mode, interpolate */
|
||||
/* Compute per-codec-band allocation from per-critical-band matrix */
|
||||
for (i=0;i<BITALLOC_SIZE;i++)
|
||||
{
|
||||
for (j=0;j<mode->nbEBands;j++)
|
||||
{
|
||||
int k;
|
||||
for (k=0;k<maxBands;k++)
|
||||
{
|
||||
if (400*(opus_int32)eband5ms[k] > mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize)
|
||||
break;
|
||||
}
|
||||
if (k>maxBands-1)
|
||||
allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
|
||||
else {
|
||||
opus_int32 a0, a1;
|
||||
a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1];
|
||||
a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize;
|
||||
allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
|
||||
+ a1*band_allocation[i*maxBands+k])/(a0+a1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*printf ("\n");
|
||||
for (i=0;i<BITALLOC_SIZE;i++)
|
||||
{
|
||||
for (j=0;j<mode->nbEBands;j++)
|
||||
printf ("%d ", allocVectors[i*mode->nbEBands+j]);
|
||||
printf ("\n");
|
||||
}
|
||||
exit(0);*/
|
||||
|
||||
mode->allocVectors = allocVectors;
|
||||
}
|
||||
|
||||
#endif /* CUSTOM_MODES */
|
||||
|
||||
CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
|
||||
{
|
||||
int i;
|
||||
#ifdef CUSTOM_MODES
|
||||
CELTMode *mode=NULL;
|
||||
int res;
|
||||
opus_val16 *window;
|
||||
opus_int16 *logN;
|
||||
int LM;
|
||||
int arch = opus_select_arch();
|
||||
ALLOC_STACK;
|
||||
#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
|
||||
if (global_stack==NULL)
|
||||
goto failure;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CUSTOM_MODES_ONLY
|
||||
for (i=0;i<TOTAL_MODES;i++)
|
||||
{
|
||||
int j;
|
||||
for (j=0;j<4;j++)
|
||||
{
|
||||
if (Fs == static_mode_list[i]->Fs &&
|
||||
(frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
|
||||
{
|
||||
if (error)
|
||||
*error = OPUS_OK;
|
||||
return (CELTMode*)static_mode_list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CUSTOM_MODES_ONLY */
|
||||
|
||||
#ifndef CUSTOM_MODES
|
||||
if (error)
|
||||
*error = OPUS_BAD_ARG;
|
||||
return NULL;
|
||||
#else
|
||||
|
||||
/* The good thing here is that permutation of the arguments will automatically be invalid */
|
||||
|
||||
if (Fs < 8000 || Fs > 96000)
|
||||
{
|
||||
if (error)
|
||||
*error = OPUS_BAD_ARG;
|
||||
return NULL;
|
||||
}
|
||||
if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
|
||||
{
|
||||
if (error)
|
||||
*error = OPUS_BAD_ARG;
|
||||
return NULL;
|
||||
}
|
||||
/* Frames of less than 1ms are not supported. */
|
||||
if ((opus_int32)frame_size*1000 < Fs)
|
||||
{
|
||||
if (error)
|
||||
*error = OPUS_BAD_ARG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0)
|
||||
{
|
||||
LM = 3;
|
||||
} else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0)
|
||||
{
|
||||
LM = 2;
|
||||
} else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0)
|
||||
{
|
||||
LM = 1;
|
||||
} else
|
||||
{
|
||||
LM = 0;
|
||||
}
|
||||
|
||||
/* Shorts longer than 3.3ms are not supported. */
|
||||
if ((opus_int32)(frame_size>>LM)*300 > Fs)
|
||||
{
|
||||
if (error)
|
||||
*error = OPUS_BAD_ARG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mode = opus_alloc(sizeof(CELTMode));
|
||||
if (mode==NULL)
|
||||
goto failure;
|
||||
mode->Fs = Fs;
|
||||
|
||||
/* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
|
||||
is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
|
||||
approximate that. */
|
||||
if(Fs < 12000) /* 8 kHz */
|
||||
{
|
||||
mode->preemph[0] = QCONST16(0.3500061035f, 15);
|
||||
mode->preemph[1] = -QCONST16(0.1799926758f, 15);
|
||||
mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
|
||||
mode->preemph[3] = QCONST16(3.6765136719f, 13);
|
||||
} else if(Fs < 24000) /* 16 kHz */
|
||||
{
|
||||
mode->preemph[0] = QCONST16(0.6000061035f, 15);
|
||||
mode->preemph[1] = -QCONST16(0.1799926758f, 15);
|
||||
mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
|
||||
mode->preemph[3] = QCONST16(2.2598876953f, 13);
|
||||
} else if(Fs < 40000) /* 32 kHz */
|
||||
{
|
||||
mode->preemph[0] = QCONST16(0.7799987793f, 15);
|
||||
mode->preemph[1] = -QCONST16(0.1000061035f, 15);
|
||||
mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
|
||||
mode->preemph[3] = QCONST16(1.3333740234f, 13);
|
||||
} else /* 48 kHz */
|
||||
{
|
||||
mode->preemph[0] = QCONST16(0.8500061035f, 15);
|
||||
mode->preemph[1] = QCONST16(0.0f, 15);
|
||||
mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
|
||||
mode->preemph[3] = QCONST16(1.f, 13);
|
||||
}
|
||||
|
||||
mode->maxLM = LM;
|
||||
mode->nbShortMdcts = 1<<LM;
|
||||
mode->shortMdctSize = frame_size/mode->nbShortMdcts;
|
||||
res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
|
||||
|
||||
mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
|
||||
if (mode->eBands==NULL)
|
||||
goto failure;
|
||||
#if !defined(SMALL_FOOTPRINT)
|
||||
/* Make sure we don't allocate a band larger than our PVQ table.
|
||||
208 should be enough, but let's be paranoid. */
|
||||
if ((mode->eBands[mode->nbEBands] - mode->eBands[mode->nbEBands-1])<<LM >
|
||||
208) {
|
||||
goto failure;
|
||||
}
|
||||
#endif
|
||||
|
||||
mode->effEBands = mode->nbEBands;
|
||||
while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
|
||||
mode->effEBands--;
|
||||
|
||||
/* Overlap must be divisible by 4 */
|
||||
mode->overlap = ((mode->shortMdctSize>>2)<<2);
|
||||
|
||||
compute_allocation_table(mode);
|
||||
if (mode->allocVectors==NULL)
|
||||
goto failure;
|
||||
|
||||
window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));
|
||||
if (window==NULL)
|
||||
goto failure;
|
||||
|
||||
#ifndef OPUS_FIXED_POINT
|
||||
for (i=0;i<mode->overlap;i++)
|
||||
window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
|
||||
#else
|
||||
for (i=0;i<mode->overlap;i++)
|
||||
window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap))));
|
||||
#endif
|
||||
mode->window = window;
|
||||
|
||||
logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16));
|
||||
if (logN==NULL)
|
||||
goto failure;
|
||||
|
||||
for (i=0;i<mode->nbEBands;i++)
|
||||
logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
|
||||
mode->logN = logN;
|
||||
|
||||
compute_pulse_cache(mode, mode->maxLM);
|
||||
|
||||
if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,
|
||||
mode->maxLM, arch) == 0)
|
||||
goto failure;
|
||||
|
||||
if (error)
|
||||
*error = OPUS_OK;
|
||||
|
||||
return mode;
|
||||
failure:
|
||||
if (error)
|
||||
*error = OPUS_ALLOC_FAIL;
|
||||
if (mode!=NULL)
|
||||
opus_custom_mode_destroy(mode);
|
||||
return NULL;
|
||||
#endif /* !CUSTOM_MODES */
|
||||
}
|
||||
|
||||
#ifdef CUSTOM_MODES
|
||||
void opus_custom_mode_destroy(CELTMode *mode)
|
||||
{
|
||||
int arch = opus_select_arch();
|
||||
|
||||
if (mode == NULL)
|
||||
return;
|
||||
#ifndef CUSTOM_MODES_ONLY
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<TOTAL_MODES;i++)
|
||||
{
|
||||
if (mode == static_mode_list[i])
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CUSTOM_MODES_ONLY */
|
||||
opus_free((opus_int16*)mode->eBands);
|
||||
opus_free((opus_int16*)mode->allocVectors);
|
||||
|
||||
opus_free((opus_val16*)mode->window);
|
||||
opus_free((opus_int16*)mode->logN);
|
||||
|
||||
opus_free((opus_int16*)mode->cache.index);
|
||||
opus_free((unsigned char*)mode->cache.bits);
|
||||
opus_free((unsigned char*)mode->cache.caps);
|
||||
clt_mdct_clear(&mode->mdct, arch);
|
||||
|
||||
opus_free((CELTMode *)mode);
|
||||
}
|
||||
#endif
|
@ -1,75 +0,0 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (c) 2008 Gregory Maxwell
|
||||
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef MODES_H
|
||||
#define MODES_H
|
||||
|
||||
#include "opus/opus_types.h"
|
||||
#include "opus/celt/celt.h"
|
||||
#include "opus/celt/arch.h"
|
||||
#include "opus/celt/mdct.h"
|
||||
#include "opus/celt/entenc.h"
|
||||
#include "opus/celt/entdec.h"
|
||||
|
||||
#define MAX_PERIOD 1024
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
const opus_int16 *index;
|
||||
const unsigned char *bits;
|
||||
const unsigned char *caps;
|
||||
} PulseCache;
|
||||
|
||||
/** Mode definition (opaque)
|
||||
@brief Mode definition
|
||||
*/
|
||||
struct OpusCustomMode {
|
||||
opus_int32 Fs;
|
||||
int overlap;
|
||||
|
||||
int nbEBands;
|
||||
int effEBands;
|
||||
opus_val16 preemph[4];
|
||||
const opus_int16 *eBands; /**< Definition for each "pseudo-critical band" */
|
||||
|
||||
int maxLM;
|
||||
int nbShortMdcts;
|
||||
int shortMdctSize;
|
||||
|
||||
int nbAllocVectors; /**< Number of lines in the matrix below */
|
||||
const unsigned char *allocVectors; /**< Number of bits in each band for several rates */
|
||||
const opus_int16 *logN;
|
||||
|
||||
const opus_val16 *window;
|
||||
mdct_lookup mdct;
|
||||
PulseCache cache;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user