o(K,A))M[B]=K,M[Y]=A,B=Y;else break e}}return L}function o(M,L){var A=M.sortIndex-L.sortIndex;return A!==0?A:M.id-L.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;e.unstable_now=function(){return i.now()}}else{var a=Date,l=a.now();e.unstable_now=function(){return a.now()-l}}var s=[],c=[],u=1,d=null,v=3,h=!1,g=!1,p=!1,b=typeof setTimeout=="function"?setTimeout:null,m=typeof clearTimeout=="function"?clearTimeout:null,y=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(M){for(var L=n(c);L!==null;){if(L.callback===null)r(c);else if(L.startTime<=M)r(c),L.sortIndex=L.expirationTime,t(s,L);else break;L=n(c)}}function x(M){if(p=!1,S(M),!g)if(n(s)!==null)g=!0,_($);else{var L=n(c);L!==null&&O(x,L.startTime-M)}}function $(M,L){g=!1,p&&(p=!1,m(R),R=-1),h=!0;var A=v;try{for(S(L),d=n(s);d!==null&&(!(d.expirationTime>L)||M&&!I());){var B=d.callback;if(typeof B=="function"){d.callback=null,v=d.priorityLevel;var k=B(d.expirationTime<=L);L=e.unstable_now(),typeof k=="function"?d.callback=k:d===n(s)&&r(s),S(L)}else r(s);d=n(s)}if(d!==null)var j=!0;else{var H=n(c);H!==null&&O(x,H.startTime-L),j=!1}return j}finally{d=null,v=A,h=!1}}var E=!1,w=null,R=-1,P=5,N=-1;function I(){return!(e.unstable_now()-NM||125B?(M.sortIndex=A,t(c,M),n(s)===null&&M===n(c)&&(p?(m(R),R=-1):p=!0,O(x,A-B))):(M.sortIndex=k,t(s,M),g||h||(g=!0,_($))),M},e.unstable_shouldYield=I,e.unstable_wrapCallback=function(M){var L=v;return function(){var A=v;v=L;try{return M.apply(this,arguments)}finally{v=A}}}})(A1);(function(e){e.exports=A1})(_1);/**
+ * @license React
+ * react-dom.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var D1=f.exports,or=_1.exports;function me(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Nv=Object.prototype.hasOwnProperty,xE=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Wm={},Vm={};function wE(e){return Nv.call(Vm,e)?!0:Nv.call(Wm,e)?!1:xE.test(e)?Vm[e]=!0:(Wm[e]=!0,!1)}function $E(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function EE(e,t,n,r){if(t===null||typeof t>"u"||$E(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function Ln(e,t,n,r,o,i,a){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=a}var Sn={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){Sn[e]=new Ln(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];Sn[t]=new Ln(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){Sn[e]=new Ln(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){Sn[e]=new Ln(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){Sn[e]=new Ln(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){Sn[e]=new Ln(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){Sn[e]=new Ln(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){Sn[e]=new Ln(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){Sn[e]=new Ln(e,5,!1,e.toLowerCase(),null,!1,!1)});var Fg=/[\-:]([a-z])/g;function kg(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Fg,kg);Sn[t]=new Ln(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Fg,kg);Sn[t]=new Ln(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Fg,kg);Sn[t]=new Ln(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){Sn[e]=new Ln(e,1,!1,e.toLowerCase(),null,!1,!1)});Sn.xlinkHref=new Ln("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){Sn[e]=new Ln(e,1,!1,e.toLowerCase(),null,!0,!0)});function Bg(e,t,n,r){var o=Sn.hasOwnProperty(t)?Sn[t]:null;(o!==null?o.type!==0:r||!(2l||o[a]!==i[l]){var s=`
+`+o[a].replace(" at new "," at ");return e.displayName&&s.includes("")&&(s=s.replace("",e.displayName)),s}while(1<=a&&0<=l);break}}}finally{Ef=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Rl(e):""}function ME(e){switch(e.tag){case 5:return Rl(e.type);case 16:return Rl("Lazy");case 13:return Rl("Suspense");case 19:return Rl("SuspenseList");case 0:case 2:case 15:return e=Mf(e.type,!1),e;case 11:return e=Mf(e.type.render,!1),e;case 1:return e=Mf(e.type,!0),e;default:return""}}function Lv(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case ca:return"Fragment";case sa:return"Portal";case _v:return"Profiler";case jg:return"StrictMode";case Av:return"Suspense";case Dv:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case F1:return(e.displayName||"Context")+".Consumer";case z1:return(e._context.displayName||"Context")+".Provider";case Hg:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Wg:return t=e.displayName||null,t!==null?t:Lv(e.type)||"Memo";case Ro:t=e._payload,e=e._init;try{return Lv(e(t))}catch{}}return null}function OE(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Lv(t);case 8:return t===jg?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function Ko(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function B1(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function RE(e){var t=B1(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var o=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(a){r=""+a,i.call(this,a)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(a){r=""+a},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function ac(e){e._valueTracker||(e._valueTracker=RE(e))}function j1(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=B1(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function vu(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function zv(e,t){var n=t.checked;return Wt({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n!=null?n:e._wrapperState.initialChecked})}function Ym(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=Ko(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function H1(e,t){t=t.checked,t!=null&&Bg(e,"checked",t,!1)}function Fv(e,t){H1(e,t);var n=Ko(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?kv(e,t.type,n):t.hasOwnProperty("defaultValue")&&kv(e,t.type,Ko(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function Gm(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function kv(e,t,n){(t!=="number"||vu(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var Il=Array.isArray;function Ma(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o"+t.valueOf().toString()+"",t=lc.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function ns(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Ll={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},IE=["Webkit","ms","Moz","O"];Object.keys(Ll).forEach(function(e){IE.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Ll[t]=Ll[e]})});function Y1(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||Ll.hasOwnProperty(e)&&Ll[e]?(""+t).trim():t+"px"}function G1(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,o=Y1(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}var PE=Wt({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Hv(e,t){if(t){if(PE[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(me(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(me(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(me(61))}if(t.style!=null&&typeof t.style!="object")throw Error(me(62))}}function Wv(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Vv=null;function Vg(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Uv=null,Oa=null,Ra=null;function Xm(e){if(e=zs(e)){if(typeof Uv!="function")throw Error(me(280));var t=e.stateNode;t&&(t=gd(t),Uv(e.stateNode,e.type,t))}}function K1(e){Oa?Ra?Ra.push(e):Ra=[e]:Oa=e}function q1(){if(Oa){var e=Oa,t=Ra;if(Ra=Oa=null,Xm(e),t)for(e=0;e>>=0,e===0?32:31-(jE(e)/HE|0)|0}var sc=64,cc=4194304;function Pl(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function mu(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,o=e.suspendedLanes,i=e.pingedLanes,a=n&268435455;if(a!==0){var l=a&~o;l!==0?r=Pl(l):(i&=a,i!==0&&(r=Pl(i)))}else a=n&~o,a!==0?r=Pl(a):i!==0&&(r=Pl(i));if(r===0)return 0;if(t!==0&&t!==r&&(t&o)===0&&(o=r&-r,i=t&-t,o>=i||o===16&&(i&4194240)!==0))return t;if((r&4)!==0&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Ds(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-Ar(t),e[t]=n}function YE(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=Fl),i0=String.fromCharCode(32),a0=!1;function gS(e,t){switch(e){case"keyup":return SM.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function hS(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var ua=!1;function xM(e,t){switch(e){case"compositionend":return hS(t);case"keypress":return t.which!==32?null:(a0=!0,i0);case"textInput":return e=t.data,e===i0&&a0?null:e;default:return null}}function wM(e,t){if(ua)return e==="compositionend"||!Zg&&gS(e,t)?(e=vS(),Vc=qg=No=null,ua=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=u0(n)}}function SS(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?SS(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function CS(){for(var e=window,t=vu();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=vu(e.document)}return t}function Jg(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function NM(e){var t=CS(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&SS(n.ownerDocument.documentElement,n)){if(r!==null&&Jg(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var o=n.textContent.length,i=Math.min(r.start,o);r=r.end===void 0?i:Math.min(r.end,o),!e.extend&&i>r&&(o=r,r=i,i=o),o=d0(n,i);var a=d0(n,r);o&&a&&(e.rangeCount!==1||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==a.node||e.focusOffset!==a.offset)&&(t=t.createRange(),t.setStart(o.node,o.offset),e.removeAllRanges(),i>r?(e.addRange(t),e.extend(a.node,a.offset)):(t.setEnd(a.node,a.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,da=null,Qv=null,Bl=null,Zv=!1;function f0(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Zv||da==null||da!==vu(r)||(r=da,"selectionStart"in r&&Jg(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Bl&&ss(Bl,r)||(Bl=r,r=Su(Qv,"onSelect"),0pa||(e.current=op[pa],op[pa]=null,pa--)}function _t(e,t){pa++,op[pa]=e.current,e.current=t}var qo={},On=oi(qo),Vn=oi(!1),Ri=qo;function Fa(e,t){var n=e.type.contextTypes;if(!n)return qo;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o={},i;for(i in n)o[i]=t[i];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function Un(e){return e=e.childContextTypes,e!=null}function xu(){zt(Vn),zt(On)}function b0(e,t,n){if(On.current!==qo)throw Error(me(168));_t(On,t),_t(Vn,n)}function PS(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var o in r)if(!(o in t))throw Error(me(108,OE(e)||"Unknown",o));return Wt({},n,r)}function wu(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||qo,Ri=On.current,_t(On,e),_t(Vn,Vn.current),!0}function S0(e,t,n){var r=e.stateNode;if(!r)throw Error(me(169));n?(e=PS(e,t,Ri),r.__reactInternalMemoizedMergedChildContext=e,zt(Vn),zt(On),_t(On,e)):zt(Vn),_t(Vn,n)}var lo=null,hd=!1,Bf=!1;function TS(e){lo===null?lo=[e]:lo.push(e)}function VM(e){hd=!0,TS(e)}function ii(){if(!Bf&&lo!==null){Bf=!0;var e=0,t=Ot;try{var n=lo;for(Ot=1;e>=a,o-=a,uo=1<<32-Ar(t)+o|n<R?(P=w,w=null):P=w.sibling;var N=v(m,w,S[R],x);if(N===null){w===null&&(w=P);break}e&&w&&N.alternate===null&&t(m,w),y=i(N,y,R),E===null?$=N:E.sibling=N,E=N,w=P}if(R===S.length)return n(m,w),Ft&&ui(m,R),$;if(w===null){for(;RR?(P=w,w=null):P=w.sibling;var I=v(m,w,N.value,x);if(I===null){w===null&&(w=P);break}e&&w&&I.alternate===null&&t(m,w),y=i(I,y,R),E===null?$=I:E.sibling=I,E=I,w=P}if(N.done)return n(m,w),Ft&&ui(m,R),$;if(w===null){for(;!N.done;R++,N=S.next())N=d(m,N.value,x),N!==null&&(y=i(N,y,R),E===null?$=N:E.sibling=N,E=N);return Ft&&ui(m,R),$}for(w=r(m,w);!N.done;R++,N=S.next())N=h(w,m,R,N.value,x),N!==null&&(e&&N.alternate!==null&&w.delete(N.key===null?R:N.key),y=i(N,y,R),E===null?$=N:E.sibling=N,E=N);return e&&w.forEach(function(z){return t(m,z)}),Ft&&ui(m,R),$}function b(m,y,S,x){if(typeof S=="object"&&S!==null&&S.type===ca&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case ic:e:{for(var $=S.key,E=y;E!==null;){if(E.key===$){if($=S.type,$===ca){if(E.tag===7){n(m,E.sibling),y=o(E,S.props.children),y.return=m,m=y;break e}}else if(E.elementType===$||typeof $=="object"&&$!==null&&$.$$typeof===Ro&&O0($)===E.type){n(m,E.sibling),y=o(E,S.props),y.ref=hl(m,E,S),y.return=m,m=y;break e}n(m,E);break}else t(m,E);E=E.sibling}S.type===ca?(y=$i(S.props.children,m.mode,x,S.key),y.return=m,m=y):(x=Zc(S.type,S.key,S.props,null,m.mode,x),x.ref=hl(m,y,S),x.return=m,m=x)}return a(m);case sa:e:{for(E=S.key;y!==null;){if(y.key===E)if(y.tag===4&&y.stateNode.containerInfo===S.containerInfo&&y.stateNode.implementation===S.implementation){n(m,y.sibling),y=o(y,S.children||[]),y.return=m,m=y;break e}else{n(m,y);break}else t(m,y);y=y.sibling}y=Kf(S,m.mode,x),y.return=m,m=y}return a(m);case Ro:return E=S._init,b(m,y,E(S._payload),x)}if(Il(S))return g(m,y,S,x);if(dl(S))return p(m,y,S,x);hc(m,S)}return typeof S=="string"&&S!==""||typeof S=="number"?(S=""+S,y!==null&&y.tag===6?(n(m,y.sibling),y=o(y,S),y.return=m,m=y):(n(m,y),y=Gf(S,m.mode,x),y.return=m,m=y),a(m)):n(m,y)}return b}var Ba=kS(!0),BS=kS(!1),Fs={},Qr=oi(Fs),fs=oi(Fs),vs=oi(Fs);function yi(e){if(e===Fs)throw Error(me(174));return e}function sh(e,t){switch(_t(vs,t),_t(fs,e),_t(Qr,Fs),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:jv(null,"");break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=jv(t,e)}zt(Qr),_t(Qr,t)}function ja(){zt(Qr),zt(fs),zt(vs)}function jS(e){yi(vs.current);var t=yi(Qr.current),n=jv(t,e.type);t!==n&&(_t(fs,e),_t(Qr,n))}function ch(e){fs.current===e&&(zt(Qr),zt(fs))}var jt=oi(0);function Iu(e){for(var t=e;t!==null;){if(t.tag===13){var n=t.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data==="$?"||n.data==="$!"))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if((t.flags&128)!==0)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var jf=[];function uh(){for(var e=0;en?n:4,e(!0);var r=Hf.transition;Hf.transition={};try{e(!1),t()}finally{Ot=n,Hf.transition=r}}function rC(){return br().memoizedState}function KM(e,t,n){var r=Vo(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},oC(e))iC(t,n);else if(n=DS(e,t,n,r),n!==null){var o=_n();Dr(n,e,r,o),aC(n,t,r)}}function qM(e,t,n){var r=Vo(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(oC(e))iC(t,o);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var a=t.lastRenderedState,l=i(a,n);if(o.hasEagerState=!0,o.eagerState=l,Br(l,a)){var s=t.interleaved;s===null?(o.next=o,ah(t)):(o.next=s.next,s.next=o),t.interleaved=o;return}}catch{}finally{}n=DS(e,t,o,r),n!==null&&(o=_n(),Dr(n,e,r,o),aC(n,t,r))}}function oC(e){var t=e.alternate;return e===Ht||t!==null&&t===Ht}function iC(e,t){jl=Pu=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function aC(e,t,n){if((n&4194240)!==0){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Yg(e,n)}}var Tu={readContext:yr,useCallback:Cn,useContext:Cn,useEffect:Cn,useImperativeHandle:Cn,useInsertionEffect:Cn,useLayoutEffect:Cn,useMemo:Cn,useReducer:Cn,useRef:Cn,useState:Cn,useDebugValue:Cn,useDeferredValue:Cn,useTransition:Cn,useMutableSource:Cn,useSyncExternalStore:Cn,useId:Cn,unstable_isNewReconciler:!1},XM={readContext:yr,useCallback:function(e,t){return Gr().memoizedState=[e,t===void 0?null:t],e},useContext:yr,useEffect:I0,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,Kc(4194308,4,ZS.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Kc(4194308,4,e,t)},useInsertionEffect:function(e,t){return Kc(4,2,e,t)},useMemo:function(e,t){var n=Gr();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Gr();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=KM.bind(null,Ht,e),[r.memoizedState,e]},useRef:function(e){var t=Gr();return e={current:e},t.memoizedState=e},useState:R0,useDebugValue:gh,useDeferredValue:function(e){return Gr().memoizedState=e},useTransition:function(){var e=R0(!1),t=e[0];return e=GM.bind(null,e[1]),Gr().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=Ht,o=Gr();if(Ft){if(n===void 0)throw Error(me(407));n=n()}else{if(n=t(),fn===null)throw Error(me(349));(Pi&30)!==0||VS(r,t,n)}o.memoizedState=n;var i={value:n,getSnapshot:t};return o.queue=i,I0(YS.bind(null,r,i,e),[e]),r.flags|=2048,hs(9,US.bind(null,r,i,n,t),void 0,null),n},useId:function(){var e=Gr(),t=fn.identifierPrefix;if(Ft){var n=fo,r=uo;n=(r&~(1<<32-Ar(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=ps++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=a.createElement(n,{is:r.is}):(e=a.createElement(n),n==="select"&&(a=e,r.multiple?a.multiple=!0:r.size&&(a.size=r.size))):e=a.createElementNS(e,n),e[Kr]=t,e[ds]=r,gC(e,t,!1,!1),t.stateNode=e;e:{switch(a=Wv(n,r),n){case"dialog":Dt("cancel",e),Dt("close",e),o=r;break;case"iframe":case"object":case"embed":Dt("load",e),o=r;break;case"video":case"audio":for(o=0;oWa&&(t.flags|=128,r=!0,ml(i,!1),t.lanes=4194304)}else{if(!r)if(e=Iu(a),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),ml(i,!0),i.tail===null&&i.tailMode==="hidden"&&!a.alternate&&!Ft)return xn(t),null}else 2*Xt()-i.renderingStartTime>Wa&&n!==1073741824&&(t.flags|=128,r=!0,ml(i,!1),t.lanes=4194304);i.isBackwards?(a.sibling=t.child,t.child=a):(n=i.last,n!==null?n.sibling=a:t.child=a,i.last=a)}return i.tail!==null?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=Xt(),t.sibling=null,n=jt.current,_t(jt,r?n&1|2:n&1),t):(xn(t),null);case 22:case 23:return Ch(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&(t.mode&1)!==0?(er&1073741824)!==0&&(xn(t),t.subtreeFlags&6&&(t.flags|=8192)):xn(t),null;case 24:return null;case 25:return null}throw Error(me(156,t.tag))}function oO(e,t){switch(th(t),t.tag){case 1:return Un(t.type)&&xu(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ja(),zt(Vn),zt(On),uh(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return ch(t),null;case 13:if(zt(jt),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(me(340));ka()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return zt(jt),null;case 4:return ja(),null;case 10:return ih(t.type._context),null;case 22:case 23:return Ch(),null;case 24:return null;default:return null}}var yc=!1,En=!1,iO=typeof WeakSet=="function"?WeakSet:Set,De=null;function ya(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){Yt(e,t,r)}else n.current=null}function hp(e,t,n){try{n()}catch(r){Yt(e,t,r)}}var F0=!1;function aO(e,t){if(Jv=yu,e=CS(),Jg(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var o=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch{n=null;break e}var a=0,l=-1,s=-1,c=0,u=0,d=e,v=null;t:for(;;){for(var h;d!==n||o!==0&&d.nodeType!==3||(l=a+o),d!==i||r!==0&&d.nodeType!==3||(s=a+r),d.nodeType===3&&(a+=d.nodeValue.length),(h=d.firstChild)!==null;)v=d,d=h;for(;;){if(d===e)break t;if(v===n&&++c===o&&(l=a),v===i&&++u===r&&(s=a),(h=d.nextSibling)!==null)break;d=v,v=d.parentNode}d=h}n=l===-1||s===-1?null:{start:l,end:s}}else n=null}n=n||{start:0,end:0}}else n=null;for(ep={focusedElem:e,selectionRange:n},yu=!1,De=t;De!==null;)if(t=De,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,De=e;else for(;De!==null;){t=De;try{var g=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(g!==null){var p=g.memoizedProps,b=g.memoizedState,m=t.stateNode,y=m.getSnapshotBeforeUpdate(t.elementType===t.type?p:Rr(t.type,p),b);m.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var S=t.stateNode.containerInfo;S.nodeType===1?S.textContent="":S.nodeType===9&&S.documentElement&&S.removeChild(S.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(me(163))}}catch(x){Yt(t,t.return,x)}if(e=t.sibling,e!==null){e.return=t.return,De=e;break}De=t.return}return g=F0,F0=!1,g}function Hl(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var o=r=r.next;do{if((o.tag&e)===e){var i=o.destroy;o.destroy=void 0,i!==void 0&&hp(t,n,i)}o=o.next}while(o!==r)}}function bd(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function mp(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function yC(e){var t=e.alternate;t!==null&&(e.alternate=null,yC(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Kr],delete t[ds],delete t[rp],delete t[HM],delete t[WM])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function bC(e){return e.tag===5||e.tag===3||e.tag===4}function k0(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||bC(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function yp(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Cu));else if(r!==4&&(e=e.child,e!==null))for(yp(e,t,n),e=e.sibling;e!==null;)yp(e,t,n),e=e.sibling}function bp(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(bp(e,t,n),e=e.sibling;e!==null;)bp(e,t,n),e=e.sibling}var gn=null,Pr=!1;function Eo(e,t,n){for(n=n.child;n!==null;)SC(e,t,n),n=n.sibling}function SC(e,t,n){if(Xr&&typeof Xr.onCommitFiberUnmount=="function")try{Xr.onCommitFiberUnmount(dd,n)}catch{}switch(n.tag){case 5:En||ya(n,t);case 6:var r=gn,o=Pr;gn=null,Eo(e,t,n),gn=r,Pr=o,gn!==null&&(Pr?(e=gn,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):gn.removeChild(n.stateNode));break;case 18:gn!==null&&(Pr?(e=gn,n=n.stateNode,e.nodeType===8?kf(e.parentNode,n):e.nodeType===1&&kf(e,n),as(e)):kf(gn,n.stateNode));break;case 4:r=gn,o=Pr,gn=n.stateNode.containerInfo,Pr=!0,Eo(e,t,n),gn=r,Pr=o;break;case 0:case 11:case 14:case 15:if(!En&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){o=r=r.next;do{var i=o,a=i.destroy;i=i.tag,a!==void 0&&((i&2)!==0||(i&4)!==0)&&hp(n,t,a),o=o.next}while(o!==r)}Eo(e,t,n);break;case 1:if(!En&&(ya(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(l){Yt(n,t,l)}Eo(e,t,n);break;case 21:Eo(e,t,n);break;case 22:n.mode&1?(En=(r=En)||n.memoizedState!==null,Eo(e,t,n),En=r):Eo(e,t,n);break;default:Eo(e,t,n)}}function B0(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new iO),t.forEach(function(r){var o=gO.bind(null,e,r);n.has(r)||(n.add(r),r.then(o,o))})}}function Mr(e,t){var n=t.deletions;if(n!==null)for(var r=0;ro&&(o=a),r&=~i}if(r=o,r=Xt()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*sO(r/1960))-r,10e?16:e,_o===null)var r=!1;else{if(e=_o,_o=null,Au=0,(wt&6)!==0)throw Error(me(331));var o=wt;for(wt|=4,De=e.current;De!==null;){var i=De,a=i.child;if((De.flags&16)!==0){var l=i.deletions;if(l!==null){for(var s=0;sXt()-bh?wi(e,0):yh|=n),Yn(e,t)}function RC(e,t){t===0&&((e.mode&1)===0?t=1:(t=cc,cc<<=1,(cc&130023424)===0&&(cc=4194304)));var n=_n();e=ho(e,t),e!==null&&(Ds(e,t,n),Yn(e,n))}function pO(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),RC(e,n)}function gO(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;o!==null&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(me(314))}r!==null&&r.delete(t),RC(e,n)}var IC;IC=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||Vn.current)Wn=!0;else{if((e.lanes&n)===0&&(t.flags&128)===0)return Wn=!1,nO(e,t,n);Wn=(e.flags&131072)!==0}else Wn=!1,Ft&&(t.flags&1048576)!==0&&NS(t,Eu,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;qc(e,t),e=t.pendingProps;var o=Fa(t,On.current);Pa(t,n),o=fh(null,t,r,e,o,n);var i=vh();return t.flags|=1,typeof o=="object"&&o!==null&&typeof o.render=="function"&&o.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Un(r)?(i=!0,wu(t)):i=!1,t.memoizedState=o.state!==null&&o.state!==void 0?o.state:null,lh(t),o.updater=md,t.stateNode=o,o._reactInternals=t,cp(t,r,e,n),t=fp(null,t,r,!0,i,n)):(t.tag=0,Ft&&i&&eh(t),Nn(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(qc(e,t),e=t.pendingProps,o=r._init,r=o(r._payload),t.type=r,o=t.tag=mO(r),e=Rr(r,e),o){case 0:t=dp(null,t,r,e,n);break e;case 1:t=D0(null,t,r,e,n);break e;case 11:t=_0(null,t,r,e,n);break e;case 14:t=A0(null,t,r,Rr(r.type,e),n);break e}throw Error(me(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Rr(r,o),dp(e,t,r,o,n);case 1:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Rr(r,o),D0(e,t,r,o,n);case 3:e:{if(fC(t),e===null)throw Error(me(387));r=t.pendingProps,i=t.memoizedState,o=i.element,LS(e,t),Ru(t,r,null,n);var a=t.memoizedState;if(r=a.element,i.isDehydrated)if(i={element:r,isDehydrated:!1,cache:a.cache,pendingSuspenseBoundaries:a.pendingSuspenseBoundaries,transitions:a.transitions},t.updateQueue.baseState=i,t.memoizedState=i,t.flags&256){o=Ha(Error(me(423)),t),t=L0(e,t,r,n,o);break e}else if(r!==o){o=Ha(Error(me(424)),t),t=L0(e,t,r,n,o);break e}else for(tr=jo(t.stateNode.containerInfo.firstChild),rr=t,Ft=!0,_r=null,n=BS(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(ka(),r===o){t=mo(e,t,n);break e}Nn(e,t,r,n)}t=t.child}return t;case 5:return jS(t),e===null&&ap(t),r=t.type,o=t.pendingProps,i=e!==null?e.memoizedProps:null,a=o.children,tp(r,o)?a=null:i!==null&&tp(r,i)&&(t.flags|=32),dC(e,t),Nn(e,t,a,n),t.child;case 6:return e===null&&ap(t),null;case 13:return vC(e,t,n);case 4:return sh(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=Ba(t,null,r,n):Nn(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Rr(r,o),_0(e,t,r,o,n);case 7:return Nn(e,t,t.pendingProps,n),t.child;case 8:return Nn(e,t,t.pendingProps.children,n),t.child;case 12:return Nn(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,i=t.memoizedProps,a=o.value,_t(Mu,r._currentValue),r._currentValue=a,i!==null)if(Br(i.value,a)){if(i.children===o.children&&!Vn.current){t=mo(e,t,n);break e}}else for(i=t.child,i!==null&&(i.return=t);i!==null;){var l=i.dependencies;if(l!==null){a=i.child;for(var s=l.firstContext;s!==null;){if(s.context===r){if(i.tag===1){s=vo(-1,n&-n),s.tag=2;var c=i.updateQueue;if(c!==null){c=c.shared;var u=c.pending;u===null?s.next=s:(s.next=u.next,u.next=s),c.pending=s}}i.lanes|=n,s=i.alternate,s!==null&&(s.lanes|=n),lp(i.return,n,t),l.lanes|=n;break}s=s.next}}else if(i.tag===10)a=i.type===t.type?null:i.child;else if(i.tag===18){if(a=i.return,a===null)throw Error(me(341));a.lanes|=n,l=a.alternate,l!==null&&(l.lanes|=n),lp(a,n,t),a=i.sibling}else a=i.child;if(a!==null)a.return=i;else for(a=i;a!==null;){if(a===t){a=null;break}if(i=a.sibling,i!==null){i.return=a.return,a=i;break}a=a.return}i=a}Nn(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,Pa(t,n),o=yr(o),r=r(o),t.flags|=1,Nn(e,t,r,n),t.child;case 14:return r=t.type,o=Rr(r,t.pendingProps),o=Rr(r.type,o),A0(e,t,r,o,n);case 15:return cC(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:Rr(r,o),qc(e,t),t.tag=1,Un(r)?(e=!0,wu(t)):e=!1,Pa(t,n),FS(t,r,o),cp(t,r,o,n),fp(null,t,r,!0,e,n);case 19:return pC(e,t,n);case 22:return uC(e,t,n)}throw Error(me(156,t.tag))};function PC(e,t){return nS(e,t)}function hO(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function gr(e,t,n,r){return new hO(e,t,n,r)}function wh(e){return e=e.prototype,!(!e||!e.isReactComponent)}function mO(e){if(typeof e=="function")return wh(e)?1:0;if(e!=null){if(e=e.$$typeof,e===Hg)return 11;if(e===Wg)return 14}return 2}function Uo(e,t){var n=e.alternate;return n===null?(n=gr(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Zc(e,t,n,r,o,i){var a=2;if(r=e,typeof e=="function")wh(e)&&(a=1);else if(typeof e=="string")a=5;else e:switch(e){case ca:return $i(n.children,o,i,t);case jg:a=8,o|=8;break;case _v:return e=gr(12,n,t,o|2),e.elementType=_v,e.lanes=i,e;case Av:return e=gr(13,n,t,o),e.elementType=Av,e.lanes=i,e;case Dv:return e=gr(19,n,t,o),e.elementType=Dv,e.lanes=i,e;case k1:return Cd(n,o,i,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case z1:a=10;break e;case F1:a=9;break e;case Hg:a=11;break e;case Wg:a=14;break e;case Ro:a=16,r=null;break e}throw Error(me(130,e==null?e:typeof e,""))}return t=gr(a,n,t,o),t.elementType=e,t.type=r,t.lanes=i,t}function $i(e,t,n,r){return e=gr(7,e,r,t),e.lanes=n,e}function Cd(e,t,n,r){return e=gr(22,e,r,t),e.elementType=k1,e.lanes=n,e.stateNode={isHidden:!1},e}function Gf(e,t,n){return e=gr(6,e,null,t),e.lanes=n,e}function Kf(e,t,n){return t=gr(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function yO(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Rf(0),this.expirationTimes=Rf(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Rf(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function $h(e,t,n,r,o,i,a,l,s){return e=new yO(e,t,n,l,s),t===1?(t=1,i===!0&&(t|=8)):t=0,i=gr(3,null,null,t),e.current=i,i.stateNode=e,i.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},lh(i),e}function bO(e,t,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(n){console.error(n)}}t(),e.exports=ir})(Gn);const zu=ud(Gn.exports),$O=E1({__proto__:null,default:zu},[Gn.exports]);var AC,K0=Gn.exports;AC=K0.createRoot,K0.hydrateRoot;var $p={exports:{}},_i={},Rh={exports:{}},EO="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED",MO=EO,OO=MO;function DC(){}function LC(){}LC.resetWarningCache=DC;var RO=function(){function e(r,o,i,a,l,s){if(s!==OO){var c=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw c.name="Invariant Violation",c}}e.isRequired=e;function t(){return e}var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:LC,resetWarningCache:DC};return n.PropTypes=n,n};Rh.exports=RO();var Ep={exports:{}},Wr={},Fu={exports:{}};(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=u;/*!
+ * Adapted from jQuery UI core
+ *
+ * http://jqueryui.com
+ *
+ * Copyright 2014 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/category/ui-core/
+ */var n="none",r="contents",o=/input|select|textarea|button|object|iframe/;function i(d,v){return v.getPropertyValue("overflow")!=="visible"||d.scrollWidth<=0&&d.scrollHeight<=0}function a(d){var v=d.offsetWidth<=0&&d.offsetHeight<=0;if(v&&!d.innerHTML)return!0;try{var h=window.getComputedStyle(d),g=h.getPropertyValue("display");return v?g!==r&&i(d,h):g===n}catch{return console.warn("Failed to inspect element style"),!1}}function l(d){for(var v=d,h=d.getRootNode&&d.getRootNode();v&&v!==document.body;){if(h&&v===h&&(v=h.host.parentNode),a(v))return!1;v=v.parentNode}return!0}function s(d,v){var h=d.nodeName.toLowerCase(),g=o.test(h)&&!d.disabled||h==="a"&&d.href||v;return g&&l(d)}function c(d){var v=d.getAttribute("tabindex");v===null&&(v=void 0);var h=isNaN(v);return(h||v>=0)&&s(d,!h)}function u(d){var v=[].slice.call(d.querySelectorAll("*"),0).reduce(function(h,g){return h.concat(g.shadowRoot?u(g.shadowRoot):[g])},[]);return v.filter(c)}e.exports=t.default})(Fu,Fu.exports);Object.defineProperty(Wr,"__esModule",{value:!0});Wr.resetState=NO;Wr.log=_O;Wr.handleBlur=ys;Wr.handleFocus=bs;Wr.markForFocusLater=AO;Wr.returnFocus=DO;Wr.popWithoutFocus=LO;Wr.setupScopedFocus=zO;Wr.teardownScopedFocus=FO;var IO=Fu.exports,PO=TO(IO);function TO(e){return e&&e.__esModule?e:{default:e}}var Va=[],Sa=null,Mp=!1;function NO(){Va=[]}function _O(){}function ys(){Mp=!0}function bs(){if(Mp){if(Mp=!1,!Sa)return;setTimeout(function(){if(!Sa.contains(document.activeElement)){var e=(0,PO.default)(Sa)[0]||Sa;e.focus()}},0)}}function AO(){Va.push(document.activeElement)}function DO(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,t=null;try{Va.length!==0&&(t=Va.pop(),t.focus({preventScroll:e}));return}catch{console.warn(["You tried to return focus to",t,"but it is not in the DOM anymore"].join(" "))}}function LO(){Va.length>0&&Va.pop()}function zO(e){Sa=e,window.addEventListener?(window.addEventListener("blur",ys,!1),document.addEventListener("focus",bs,!0)):(window.attachEvent("onBlur",ys),document.attachEvent("onFocus",bs))}function FO(){Sa=null,window.addEventListener?(window.removeEventListener("blur",ys),document.removeEventListener("focus",bs)):(window.detachEvent("onBlur",ys),document.detachEvent("onFocus",bs))}var Op={exports:{}};(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var n=Fu.exports,r=o(n);function o(l){return l&&l.__esModule?l:{default:l}}function i(){var l=arguments.length>0&&arguments[0]!==void 0?arguments[0]:document;return l.activeElement.shadowRoot?i(l.activeElement.shadowRoot):l.activeElement}function a(l,s){var c=(0,r.default)(l);if(!c.length){s.preventDefault();return}var u=void 0,d=s.shiftKey,v=c[0],h=c[c.length-1],g=i();if(l===g){if(!d)return;u=h}if(h===g&&!d&&(u=v),v===g&&d&&(u=h),u){s.preventDefault(),u.focus();return}var p=/(\bChrome\b|\bSafari\b)\//.exec(navigator.userAgent),b=p!=null&&p[1]!="Chrome"&&/\biPod\b|\biPad\b/g.exec(navigator.userAgent)==null;if(!!b){var m=c.indexOf(g);if(m>-1&&(m+=d?-1:1),u=c[m],typeof u>"u"){s.preventDefault(),u=d?h:v,u.focus();return}s.preventDefault(),u.focus()}}e.exports=t.default})(Op,Op.exports);var Vr={},kO=function(){},BO=kO,Lr={},zC={exports:{}};/*!
+ Copyright (c) 2015 Jed Watson.
+ Based on code that is Copyright 2013-2015, Facebook, Inc.
+ All rights reserved.
+*/(function(e){(function(){var t=!!(typeof window<"u"&&window.document&&window.document.createElement),n={canUseDOM:t,canUseWorkers:typeof Worker<"u",canUseEventListeners:t&&!!(window.addEventListener||window.attachEvent),canUseViewport:t&&!!window.screen};e.exports?e.exports=n:window.ExecutionEnvironment=n})()})(zC);Object.defineProperty(Lr,"__esModule",{value:!0});Lr.canUseDOM=Lr.SafeNodeList=Lr.SafeHTMLCollection=void 0;var jO=zC.exports,HO=WO(jO);function WO(e){return e&&e.__esModule?e:{default:e}}var Md=HO.default,VO=Md.canUseDOM?window.HTMLElement:{};Lr.SafeHTMLCollection=Md.canUseDOM?window.HTMLCollection:{};Lr.SafeNodeList=Md.canUseDOM?window.NodeList:{};Lr.canUseDOM=Md.canUseDOM;Lr.default=VO;Object.defineProperty(Vr,"__esModule",{value:!0});Vr.resetState=qO;Vr.log=XO;Vr.assertNodeList=FC;Vr.setElement=QO;Vr.validateElement=Ih;Vr.hide=ZO;Vr.show=JO;Vr.documentNotReadyOrSSRTesting=eR;var UO=BO,YO=KO(UO),GO=Lr;function KO(e){return e&&e.__esModule?e:{default:e}}var fr=null;function qO(){fr&&(fr.removeAttribute?fr.removeAttribute("aria-hidden"):fr.length!=null?fr.forEach(function(e){return e.removeAttribute("aria-hidden")}):document.querySelectorAll(fr).forEach(function(e){return e.removeAttribute("aria-hidden")})),fr=null}function XO(){}function FC(e,t){if(!e||!e.length)throw new Error("react-modal: No elements were found for selector "+t+".")}function QO(e){var t=e;if(typeof t=="string"&&GO.canUseDOM){var n=document.querySelectorAll(t);FC(n,t),t=n}return fr=t||fr,fr}function Ih(e){var t=e||fr;return t?Array.isArray(t)||t instanceof HTMLCollection||t instanceof NodeList?t:[t]:((0,YO.default)(!1,["react-modal: App element is not defined.","Please use `Modal.setAppElement(el)` or set `appElement={el}`.","This is needed so screen readers don't see main content","when modal is opened. It is not recommended, but you can opt-out","by setting `ariaHideApp={false}`."].join(" ")),[])}function ZO(e){var t=!0,n=!1,r=void 0;try{for(var o=Ih(e)[Symbol.iterator](),i;!(t=(i=o.next()).done);t=!0){var a=i.value;a.setAttribute("aria-hidden","true")}}catch(l){n=!0,r=l}finally{try{!t&&o.return&&o.return()}finally{if(n)throw r}}}function JO(e){var t=!0,n=!1,r=void 0;try{for(var o=Ih(e)[Symbol.iterator](),i;!(t=(i=o.next()).done);t=!0){var a=i.value;a.removeAttribute("aria-hidden")}}catch(l){n=!0,r=l}finally{try{!t&&o.return&&o.return()}finally{if(n)throw r}}}function eR(){fr=null}var el={};Object.defineProperty(el,"__esModule",{value:!0});el.resetState=tR;el.log=nR;var Ul={},Yl={};function q0(e,t){e.classList.remove(t)}function tR(){var e=document.getElementsByTagName("html")[0];for(var t in Ul)q0(e,Ul[t]);var n=document.body;for(var r in Yl)q0(n,Yl[r]);Ul={},Yl={}}function nR(){}var rR=function(t,n){return t[n]||(t[n]=0),t[n]+=1,n},oR=function(t,n){return t[n]&&(t[n]-=1),n},iR=function(t,n,r){r.forEach(function(o){rR(n,o),t.add(o)})},aR=function(t,n,r){r.forEach(function(o){oR(n,o),n[o]===0&&t.remove(o)})};el.add=function(t,n){return iR(t.classList,t.nodeName.toLowerCase()=="html"?Ul:Yl,n.split(" "))};el.remove=function(t,n){return aR(t.classList,t.nodeName.toLowerCase()=="html"?Ul:Yl,n.split(" "))};var tl={};Object.defineProperty(tl,"__esModule",{value:!0});tl.log=sR;tl.resetState=cR;function lR(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var kC=function e(){var t=this;lR(this,e),this.register=function(n){t.openInstances.indexOf(n)===-1&&(t.openInstances.push(n),t.emit("register"))},this.deregister=function(n){var r=t.openInstances.indexOf(n);r!==-1&&(t.openInstances.splice(r,1),t.emit("deregister"))},this.subscribe=function(n){t.subscribers.push(n)},this.emit=function(n){t.subscribers.forEach(function(r){return r(n,t.openInstances.slice())})},this.openInstances=[],this.subscribers=[]},ku=new kC;function sR(){console.log("portalOpenInstances ----------"),console.log(ku.openInstances.length),ku.openInstances.forEach(function(e){return console.log(e)}),console.log("end portalOpenInstances ----------")}function cR(){ku=new kC}tl.default=ku;var Ph={};Object.defineProperty(Ph,"__esModule",{value:!0});Ph.resetState=vR;Ph.log=pR;var uR=tl,dR=fR(uR);function fR(e){return e&&e.__esModule?e:{default:e}}var wn=void 0,Ir=void 0,Ei=[];function vR(){for(var e=[wn,Ir],t=0;t0?(document.body.firstChild!==wn&&document.body.insertBefore(wn,document.body.firstChild),document.body.lastChild!==Ir&&document.body.appendChild(Ir)):(wn.parentElement&&wn.parentElement.removeChild(wn),Ir.parentElement&&Ir.parentElement.removeChild(Ir))}dR.default.subscribe(gR);(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=Object.assign||function(T){for(var D=1;D0&&(z-=1,z===0&&h.show(L)),O.props.shouldFocusAfterRender&&(O.props.shouldReturnFocusAfterClose?(c.returnFocus(O.props.preventScroll),c.teardownScopedFocus()):c.popWithoutFocus()),O.props.onAfterClose&&O.props.onAfterClose(),S.default.deregister(O)},O.open=function(){O.beforeOpen(),O.state.afterOpen&&O.state.beforeClose?(clearTimeout(O.closeTimer),O.setState({beforeClose:!1})):(O.props.shouldFocusAfterRender&&(c.setupScopedFocus(O.node),c.markForFocusLater()),O.setState({isOpen:!0},function(){O.openAnimationFrame=requestAnimationFrame(function(){O.setState({afterOpen:!0}),O.props.isOpen&&O.props.onAfterOpen&&O.props.onAfterOpen({overlayEl:O.overlay,contentEl:O.content})})}))},O.close=function(){O.props.closeTimeoutMS>0?O.closeWithTimeout():O.closeWithoutTimeout()},O.focusContent=function(){return O.content&&!O.contentHasFocus()&&O.content.focus({preventScroll:!0})},O.closeWithTimeout=function(){var M=Date.now()+O.props.closeTimeoutMS;O.setState({beforeClose:!0,closesAt:M},function(){O.closeTimer=setTimeout(O.closeWithoutTimeout,O.state.closesAt-Date.now())})},O.closeWithoutTimeout=function(){O.setState({beforeClose:!1,isOpen:!1,afterOpen:!1,closesAt:null},O.afterClose)},O.handleKeyDown=function(M){N(M)&&(0,d.default)(O.content,M),O.props.shouldCloseOnEsc&&I(M)&&(M.stopPropagation(),O.requestClose(M))},O.handleOverlayOnClick=function(M){O.shouldClose===null&&(O.shouldClose=!0),O.shouldClose&&O.props.shouldCloseOnOverlayClick&&(O.ownerHandlesClose()?O.requestClose(M):O.focusContent()),O.shouldClose=null},O.handleContentOnMouseUp=function(){O.shouldClose=!1},O.handleOverlayOnMouseDown=function(M){!O.props.shouldCloseOnOverlayClick&&M.target==O.overlay&&M.preventDefault()},O.handleContentOnClick=function(){O.shouldClose=!1},O.handleContentOnMouseDown=function(){O.shouldClose=!1},O.requestClose=function(M){return O.ownerHandlesClose()&&O.props.onRequestClose(M)},O.ownerHandlesClose=function(){return O.props.onRequestClose},O.shouldBeClosed=function(){return!O.state.isOpen&&!O.state.beforeClose},O.contentHasFocus=function(){return document.activeElement===O.content||O.content.contains(document.activeElement)},O.buildClassName=function(M,L){var A=(typeof L>"u"?"undefined":r(L))==="object"?L:{base:P[M],afterOpen:P[M]+"--after-open",beforeClose:P[M]+"--before-close"},B=A.base;return O.state.afterOpen&&(B=B+" "+A.afterOpen),O.state.beforeClose&&(B=B+" "+A.beforeClose),typeof L=="string"&&L?B+" "+L:B},O.attributesFromObject=function(M,L){return Object.keys(L).reduce(function(A,B){return A[M+"-"+B]=L[B],A},{})},O.state={afterOpen:!1,beforeClose:!1},O.shouldClose=null,O.moveFromContentToOverlay=null,O}return o(D,[{key:"componentDidMount",value:function(){this.props.isOpen&&this.open()}},{key:"componentDidUpdate",value:function(O,M){this.props.isOpen&&!O.isOpen?this.open():!this.props.isOpen&&O.isOpen&&this.close(),this.props.shouldFocusAfterRender&&this.state.isOpen&&!M.isOpen&&this.focusContent()}},{key:"componentWillUnmount",value:function(){this.state.isOpen&&this.afterClose(),clearTimeout(this.closeTimer),cancelAnimationFrame(this.openAnimationFrame)}},{key:"beforeOpen",value:function(){var O=this.props,M=O.appElement,L=O.ariaHideApp,A=O.htmlOpenClassName,B=O.bodyOpenClassName,k=O.parentSelector,j=k&&k().ownerDocument||document;B&&p.add(j.body,B),A&&p.add(j.getElementsByTagName("html")[0],A),L&&(z+=1,h.hide(M)),S.default.register(this)}},{key:"render",value:function(){var O=this.props,M=O.id,L=O.className,A=O.overlayClassName,B=O.defaultStyles,k=O.children,j=L?{}:B.content,H=A?{}:B.overlay;if(this.shouldBeClosed())return null;var W={ref:this.setOverlayRef,className:this.buildClassName("overlay",A),style:n({},H,this.props.style.overlay),onClick:this.handleOverlayOnClick,onMouseDown:this.handleOverlayOnMouseDown},Y=n({id:M,ref:this.setContentRef,style:n({},j,this.props.style.content),className:this.buildClassName("content",L),tabIndex:"-1",onKeyDown:this.handleKeyDown,onMouseDown:this.handleContentOnMouseDown,onMouseUp:this.handleContentOnMouseUp,onClick:this.handleContentOnClick,role:this.props.role,"aria-label":this.props.contentLabel},this.attributesFromObject("aria",n({modal:!0},this.props.aria)),this.attributesFromObject("data",this.props.data||{}),{"data-testid":this.props.testId}),K=this.props.contentElement(Y,k);return this.props.overlayElement(W,K)}}]),D}(i.Component);F.defaultProps={style:{overlay:{},content:{}},defaultStyles:{}},F.propTypes={isOpen:l.default.bool.isRequired,defaultStyles:l.default.shape({content:l.default.object,overlay:l.default.object}),style:l.default.shape({content:l.default.object,overlay:l.default.object}),className:l.default.oneOfType([l.default.string,l.default.object]),overlayClassName:l.default.oneOfType([l.default.string,l.default.object]),parentSelector:l.default.func,bodyOpenClassName:l.default.string,htmlOpenClassName:l.default.string,ariaHideApp:l.default.bool,appElement:l.default.oneOfType([l.default.instanceOf(m.default),l.default.instanceOf(b.SafeHTMLCollection),l.default.instanceOf(b.SafeNodeList),l.default.arrayOf(l.default.instanceOf(m.default))]),onAfterOpen:l.default.func,onAfterClose:l.default.func,onRequestClose:l.default.func,closeTimeoutMS:l.default.number,shouldFocusAfterRender:l.default.bool,shouldCloseOnOverlayClick:l.default.bool,shouldReturnFocusAfterClose:l.default.bool,preventScroll:l.default.bool,role:l.default.string,contentLabel:l.default.string,aria:l.default.object,data:l.default.object,children:l.default.node,shouldCloseOnEsc:l.default.bool,overlayRef:l.default.func,contentRef:l.default.func,id:l.default.string,overlayElement:l.default.func,contentElement:l.default.func,testId:l.default.string},t.default=F,e.exports=t.default})(Ep,Ep.exports);function BC(){var e=this.constructor.getDerivedStateFromProps(this.props,this.state);e!=null&&this.setState(e)}function jC(e){function t(n){var r=this.constructor.getDerivedStateFromProps(e,n);return r!=null?r:null}this.setState(t.bind(this))}function HC(e,t){try{var n=this.props,r=this.state;this.props=e,this.state=t,this.__reactInternalSnapshotFlag=!0,this.__reactInternalSnapshot=this.getSnapshotBeforeUpdate(n,r)}finally{this.props=n,this.state=r}}BC.__suppressDeprecationWarning=!0;jC.__suppressDeprecationWarning=!0;HC.__suppressDeprecationWarning=!0;function hR(e){var t=e.prototype;if(!t||!t.isReactComponent)throw new Error("Can only polyfill class components");if(typeof e.getDerivedStateFromProps!="function"&&typeof t.getSnapshotBeforeUpdate!="function")return e;var n=null,r=null,o=null;if(typeof t.componentWillMount=="function"?n="componentWillMount":typeof t.UNSAFE_componentWillMount=="function"&&(n="UNSAFE_componentWillMount"),typeof t.componentWillReceiveProps=="function"?r="componentWillReceiveProps":typeof t.UNSAFE_componentWillReceiveProps=="function"&&(r="UNSAFE_componentWillReceiveProps"),typeof t.componentWillUpdate=="function"?o="componentWillUpdate":typeof t.UNSAFE_componentWillUpdate=="function"&&(o="UNSAFE_componentWillUpdate"),n!==null||r!==null||o!==null){var i=e.displayName||e.name,a=typeof e.getDerivedStateFromProps=="function"?"getDerivedStateFromProps()":"getSnapshotBeforeUpdate()";throw Error(`Unsafe legacy lifecycles will not be called for components using new component APIs.
+
+`+i+" uses "+a+" but also contains the following legacy lifecycles:"+(n!==null?`
+ `+n:"")+(r!==null?`
+ `+r:"")+(o!==null?`
+ `+o:"")+`
+
+The above lifecycles should be removed. Learn more about this warning here:
+https://fb.me/react-async-component-lifecycle-hooks`)}if(typeof e.getDerivedStateFromProps=="function"&&(t.componentWillMount=BC,t.componentWillReceiveProps=jC),typeof t.getSnapshotBeforeUpdate=="function"){if(typeof t.componentDidUpdate!="function")throw new Error("Cannot polyfill getSnapshotBeforeUpdate() for components that do not define componentDidUpdate() on the prototype");t.componentWillUpdate=HC;var l=t.componentDidUpdate;t.componentDidUpdate=function(c,u,d){var v=this.__reactInternalSnapshotFlag?this.__reactInternalSnapshot:d;l.call(this,c,u,v)}}return e}const mR=Object.freeze(Object.defineProperty({__proto__:null,polyfill:hR},Symbol.toStringTag,{value:"Module"})),yR=aE(mR);Object.defineProperty(_i,"__esModule",{value:!0});_i.bodyOpenClassName=_i.portalClassName=void 0;var Q0=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0)&&(n[o]=e[o]);return n}function Je(e,t){if(e==null)return{};var n=AR(e,t),r,o;if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0)&&(!Object.prototype.propertyIsEnumerable.call(e,r)||(n[r]=e[r]))}return n}var GC={exports:{}};/*!
+ Copyright (c) 2018 Jed Watson.
+ Licensed under the MIT License (MIT), see
+ http://jedwatson.github.io/classnames
+*/(function(e){(function(){var t={}.hasOwnProperty;function n(){for(var i="",a=0;a1)&&(e=1),e}function wc(e){return e<=1?"".concat(Number(e)*100,"%"):e}function bi(e){return e.length===1?"0"+e:String(e)}function zR(e,t,n){return{r:bn(e,255)*255,g:bn(t,255)*255,b:bn(n,255)*255}}function ry(e,t,n){e=bn(e,255),t=bn(t,255),n=bn(n,255);var r=Math.max(e,t,n),o=Math.min(e,t,n),i=0,a=0,l=(r+o)/2;if(r===o)a=0,i=0;else{var s=r-o;switch(a=l>.5?s/(2-r-o):s/(r+o),r){case e:i=(t-n)/s+(t1&&(n-=1),n<1/6?e+(t-e)*(6*n):n<1/2?t:n<2/3?e+(t-e)*(2/3-n)*6:e}function FR(e,t,n){var r,o,i;if(e=bn(e,360),t=bn(t,100),n=bn(n,100),t===0)o=n,i=n,r=n;else{var a=n<.5?n*(1+t):n+t-n*t,l=2*n-a;r=qf(l,a,e+1/3),o=qf(l,a,e),i=qf(l,a,e-1/3)}return{r:r*255,g:o*255,b:i*255}}function Ip(e,t,n){e=bn(e,255),t=bn(t,255),n=bn(n,255);var r=Math.max(e,t,n),o=Math.min(e,t,n),i=0,a=r,l=r-o,s=r===0?0:l/r;if(r===o)i=0;else{switch(r){case e:i=(t-n)/l+(t>16,g:(e&65280)>>8,b:e&255}}var Tp={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",goldenrod:"#daa520",gold:"#ffd700",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavenderblush:"#fff0f5",lavender:"#e6e6fa",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};function la(e){var t={r:0,g:0,b:0},n=1,r=null,o=null,i=null,a=!1,l=!1;return typeof e=="string"&&(e=UR(e)),typeof e=="object"&&(oo(e.r)&&oo(e.g)&&oo(e.b)?(t=zR(e.r,e.g,e.b),a=!0,l=String(e.r).substr(-1)==="%"?"prgb":"rgb"):oo(e.h)&&oo(e.s)&&oo(e.v)?(r=wc(e.s),o=wc(e.v),t=kR(e.h,r,o),a=!0,l="hsv"):oo(e.h)&&oo(e.s)&&oo(e.l)&&(r=wc(e.s),i=wc(e.l),t=FR(e.h,r,i),a=!0,l="hsl"),Object.prototype.hasOwnProperty.call(e,"a")&&(n=e.a)),n=KC(n),{ok:a,format:e.format||l,r:Math.min(255,Math.max(t.r,0)),g:Math.min(255,Math.max(t.g,0)),b:Math.min(255,Math.max(t.b,0)),a:n}}var WR="[-\\+]?\\d+%?",VR="[-\\+]?\\d*\\.\\d+%?",Do="(?:".concat(VR,")|(?:").concat(WR,")"),Xf="[\\s|\\(]+(".concat(Do,")[,|\\s]+(").concat(Do,")[,|\\s]+(").concat(Do,")\\s*\\)?"),Qf="[\\s|\\(]+(".concat(Do,")[,|\\s]+(").concat(Do,")[,|\\s]+(").concat(Do,")[,|\\s]+(").concat(Do,")\\s*\\)?"),Or={CSS_UNIT:new RegExp(Do),rgb:new RegExp("rgb"+Xf),rgba:new RegExp("rgba"+Qf),hsl:new RegExp("hsl"+Xf),hsla:new RegExp("hsla"+Qf),hsv:new RegExp("hsv"+Xf),hsva:new RegExp("hsva"+Qf),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/};function UR(e){if(e=e.trim().toLowerCase(),e.length===0)return!1;var t=!1;if(Tp[e])e=Tp[e],t=!0;else if(e==="transparent")return{r:0,g:0,b:0,a:0,format:"name"};var n=Or.rgb.exec(e);return n?{r:n[1],g:n[2],b:n[3]}:(n=Or.rgba.exec(e),n?{r:n[1],g:n[2],b:n[3],a:n[4]}:(n=Or.hsl.exec(e),n?{h:n[1],s:n[2],l:n[3]}:(n=Or.hsla.exec(e),n?{h:n[1],s:n[2],l:n[3],a:n[4]}:(n=Or.hsv.exec(e),n?{h:n[1],s:n[2],v:n[3]}:(n=Or.hsva.exec(e),n?{h:n[1],s:n[2],v:n[3],a:n[4]}:(n=Or.hex8.exec(e),n?{r:Jn(n[1]),g:Jn(n[2]),b:Jn(n[3]),a:oy(n[4]),format:t?"name":"hex8"}:(n=Or.hex6.exec(e),n?{r:Jn(n[1]),g:Jn(n[2]),b:Jn(n[3]),format:t?"name":"hex"}:(n=Or.hex4.exec(e),n?{r:Jn(n[1]+n[1]),g:Jn(n[2]+n[2]),b:Jn(n[3]+n[3]),a:oy(n[4]+n[4]),format:t?"name":"hex8"}:(n=Or.hex3.exec(e),n?{r:Jn(n[1]+n[1]),g:Jn(n[2]+n[2]),b:Jn(n[3]+n[3]),format:t?"name":"hex"}:!1)))))))))}function oo(e){return Boolean(Or.CSS_UNIT.exec(String(e)))}var Mt=function(){function e(t,n){t===void 0&&(t=""),n===void 0&&(n={});var r;if(t instanceof e)return t;typeof t=="number"&&(t=HR(t)),this.originalInput=t;var o=la(t);this.originalInput=t,this.r=o.r,this.g=o.g,this.b=o.b,this.a=o.a,this.roundA=Math.round(100*this.a)/100,this.format=(r=n.format)!==null&&r!==void 0?r:o.format,this.gradientType=n.gradientType,this.r<1&&(this.r=Math.round(this.r)),this.g<1&&(this.g=Math.round(this.g)),this.b<1&&(this.b=Math.round(this.b)),this.isValid=o.ok}return e.prototype.isDark=function(){return this.getBrightness()<128},e.prototype.isLight=function(){return!this.isDark()},e.prototype.getBrightness=function(){var t=this.toRgb();return(t.r*299+t.g*587+t.b*114)/1e3},e.prototype.getLuminance=function(){var t=this.toRgb(),n,r,o,i=t.r/255,a=t.g/255,l=t.b/255;return i<=.03928?n=i/12.92:n=Math.pow((i+.055)/1.055,2.4),a<=.03928?r=a/12.92:r=Math.pow((a+.055)/1.055,2.4),l<=.03928?o=l/12.92:o=Math.pow((l+.055)/1.055,2.4),.2126*n+.7152*r+.0722*o},e.prototype.getAlpha=function(){return this.a},e.prototype.setAlpha=function(t){return this.a=KC(t),this.roundA=Math.round(100*this.a)/100,this},e.prototype.isMonochrome=function(){var t=this.toHsl().s;return t===0},e.prototype.toHsv=function(){var t=Ip(this.r,this.g,this.b);return{h:t.h*360,s:t.s,v:t.v,a:this.a}},e.prototype.toHsvString=function(){var t=Ip(this.r,this.g,this.b),n=Math.round(t.h*360),r=Math.round(t.s*100),o=Math.round(t.v*100);return this.a===1?"hsv(".concat(n,", ").concat(r,"%, ").concat(o,"%)"):"hsva(".concat(n,", ").concat(r,"%, ").concat(o,"%, ").concat(this.roundA,")")},e.prototype.toHsl=function(){var t=ry(this.r,this.g,this.b);return{h:t.h*360,s:t.s,l:t.l,a:this.a}},e.prototype.toHslString=function(){var t=ry(this.r,this.g,this.b),n=Math.round(t.h*360),r=Math.round(t.s*100),o=Math.round(t.l*100);return this.a===1?"hsl(".concat(n,", ").concat(r,"%, ").concat(o,"%)"):"hsla(".concat(n,", ").concat(r,"%, ").concat(o,"%, ").concat(this.roundA,")")},e.prototype.toHex=function(t){return t===void 0&&(t=!1),Pp(this.r,this.g,this.b,t)},e.prototype.toHexString=function(t){return t===void 0&&(t=!1),"#"+this.toHex(t)},e.prototype.toHex8=function(t){return t===void 0&&(t=!1),BR(this.r,this.g,this.b,this.a,t)},e.prototype.toHex8String=function(t){return t===void 0&&(t=!1),"#"+this.toHex8(t)},e.prototype.toHexShortString=function(t){return t===void 0&&(t=!1),this.a===1?this.toHexString(t):this.toHex8String(t)},e.prototype.toRgb=function(){return{r:Math.round(this.r),g:Math.round(this.g),b:Math.round(this.b),a:this.a}},e.prototype.toRgbString=function(){var t=Math.round(this.r),n=Math.round(this.g),r=Math.round(this.b);return this.a===1?"rgb(".concat(t,", ").concat(n,", ").concat(r,")"):"rgba(".concat(t,", ").concat(n,", ").concat(r,", ").concat(this.roundA,")")},e.prototype.toPercentageRgb=function(){var t=function(n){return"".concat(Math.round(bn(n,255)*100),"%")};return{r:t(this.r),g:t(this.g),b:t(this.b),a:this.a}},e.prototype.toPercentageRgbString=function(){var t=function(n){return Math.round(bn(n,255)*100)};return this.a===1?"rgb(".concat(t(this.r),"%, ").concat(t(this.g),"%, ").concat(t(this.b),"%)"):"rgba(".concat(t(this.r),"%, ").concat(t(this.g),"%, ").concat(t(this.b),"%, ").concat(this.roundA,")")},e.prototype.toName=function(){if(this.a===0)return"transparent";if(this.a<1)return!1;for(var t="#"+Pp(this.r,this.g,this.b,!1),n=0,r=Object.entries(Tp);n=0,i=!n&&o&&(t.startsWith("hex")||t==="name");return i?t==="name"&&this.a===0?this.toName():this.toRgbString():(t==="rgb"&&(r=this.toRgbString()),t==="prgb"&&(r=this.toPercentageRgbString()),(t==="hex"||t==="hex6")&&(r=this.toHexString()),t==="hex3"&&(r=this.toHexString(!0)),t==="hex4"&&(r=this.toHex8String(!0)),t==="hex8"&&(r=this.toHex8String()),t==="name"&&(r=this.toName()),t==="hsl"&&(r=this.toHslString()),t==="hsv"&&(r=this.toHsvString()),r||this.toHexString())},e.prototype.toNumber=function(){return(Math.round(this.r)<<16)+(Math.round(this.g)<<8)+Math.round(this.b)},e.prototype.clone=function(){return new e(this.toString())},e.prototype.lighten=function(t){t===void 0&&(t=10);var n=this.toHsl();return n.l+=t/100,n.l=xc(n.l),new e(n)},e.prototype.brighten=function(t){t===void 0&&(t=10);var n=this.toRgb();return n.r=Math.max(0,Math.min(255,n.r-Math.round(255*-(t/100)))),n.g=Math.max(0,Math.min(255,n.g-Math.round(255*-(t/100)))),n.b=Math.max(0,Math.min(255,n.b-Math.round(255*-(t/100)))),new e(n)},e.prototype.darken=function(t){t===void 0&&(t=10);var n=this.toHsl();return n.l-=t/100,n.l=xc(n.l),new e(n)},e.prototype.tint=function(t){return t===void 0&&(t=10),this.mix("white",t)},e.prototype.shade=function(t){return t===void 0&&(t=10),this.mix("black",t)},e.prototype.desaturate=function(t){t===void 0&&(t=10);var n=this.toHsl();return n.s-=t/100,n.s=xc(n.s),new e(n)},e.prototype.saturate=function(t){t===void 0&&(t=10);var n=this.toHsl();return n.s+=t/100,n.s=xc(n.s),new e(n)},e.prototype.greyscale=function(){return this.desaturate(100)},e.prototype.spin=function(t){var n=this.toHsl(),r=(n.h+t)%360;return n.h=r<0?360+r:r,new e(n)},e.prototype.mix=function(t,n){n===void 0&&(n=50);var r=this.toRgb(),o=new e(t).toRgb(),i=n/100,a={r:(o.r-r.r)*i+r.r,g:(o.g-r.g)*i+r.g,b:(o.b-r.b)*i+r.b,a:(o.a-r.a)*i+r.a};return new e(a)},e.prototype.analogous=function(t,n){t===void 0&&(t=6),n===void 0&&(n=30);var r=this.toHsl(),o=360/n,i=[this];for(r.h=(r.h-(o*t>>1)+720)%360;--t;)r.h=(r.h+o)%360,i.push(new e(r));return i},e.prototype.complement=function(){var t=this.toHsl();return t.h=(t.h+180)%360,new e(t)},e.prototype.monochromatic=function(t){t===void 0&&(t=6);for(var n=this.toHsv(),r=n.h,o=n.s,i=n.v,a=[],l=1/t;t--;)a.push(new e({h:r,s:o,v:i})),i=(i+l)%1;return a},e.prototype.splitcomplement=function(){var t=this.toHsl(),n=t.h;return[this,new e({h:(n+72)%360,s:t.s,l:t.l}),new e({h:(n+216)%360,s:t.s,l:t.l})]},e.prototype.onBackground=function(t){var n=this.toRgb(),r=new e(t).toRgb(),o=n.a+r.a*(1-n.a);return new e({r:(n.r*n.a+r.r*r.a*(1-n.a))/o,g:(n.g*n.a+r.g*r.a*(1-n.a))/o,b:(n.b*n.a+r.b*r.a*(1-n.a))/o,a:o})},e.prototype.triad=function(){return this.polyad(3)},e.prototype.tetrad=function(){return this.polyad(4)},e.prototype.polyad=function(t){for(var n=this.toHsl(),r=n.h,o=[this],i=360/t,a=1;a=60&&Math.round(e.h)<=240?r=n?Math.round(e.h)-$c*t:Math.round(e.h)+$c*t:r=n?Math.round(e.h)+$c*t:Math.round(e.h)-$c*t,r<0?r+=360:r>=360&&(r-=360),r}function sy(e,t,n){if(e.h===0&&e.s===0)return e.s;var r;return n?r=e.s-iy*t:t===XC?r=e.s+iy:r=e.s+YR*t,r>1&&(r=1),n&&t===qC&&r>.1&&(r=.1),r<.06&&(r=.06),Number(r.toFixed(2))}function cy(e,t,n){var r;return n?r=e.v+GR*t:r=e.v-KR*t,r>1&&(r=1),Number(r.toFixed(2))}function Ai(e){for(var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=[],r=la(e),o=qC;o>0;o-=1){var i=ay(r),a=Ec(la({h:ly(i,o,!0),s:sy(i,o,!0),v:cy(i,o,!0)}));n.push(a)}n.push(Ec(r));for(var l=1;l<=XC;l+=1){var s=ay(r),c=Ec(la({h:ly(s,l),s:sy(s,l),v:cy(s,l)}));n.push(c)}return t.theme==="dark"?qR.map(function(u){var d=u.index,v=u.opacity,h=Ec(XR(la(t.backgroundColor||"#141414"),la(n[d]),v*100));return h}):n}var Na={red:"#F5222D",volcano:"#FA541C",orange:"#FA8C16",gold:"#FAAD14",yellow:"#FADB14",lime:"#A0D911",green:"#52C41A",cyan:"#13C2C2",blue:"#1677FF",geekblue:"#2F54EB",purple:"#722ED1",magenta:"#EB2F96",grey:"#666666"},Jc={},Zf={};Object.keys(Na).forEach(function(e){Jc[e]=Ai(Na[e]),Jc[e].primary=Jc[e][5],Zf[e]=Ai(Na[e],{theme:"dark",backgroundColor:"#141414"}),Zf[e].primary=Zf[e][5]});var QR=Jc.blue;function uy(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(o){return Object.getOwnPropertyDescriptor(e,o).enumerable})),n.push.apply(n,r)}return n}function U(e){for(var t=1;t0&&arguments[0]!==void 0?arguments[0]:{},t=e.mark;return t?t.startsWith("data-")?t:"data-".concat(t):ZR}function Od(e){if(e.attachTo)return e.attachTo;var t=document.querySelector("head");return t||document.body}function JR(e){return e==="queue"?"prependQueue":e?"prepend":"append"}function _h(e){return Array.from((_p.get(e)||e).children).filter(function(t){return t.tagName==="STYLE"})}function ZC(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!Rn())return null;var n=t.csp,r=t.prepend,o=t.priority,i=o===void 0?0:o,a=JR(r),l=a==="prependQueue",s=document.createElement("style");s.setAttribute(dy,a),l&&i&&s.setAttribute(fy,"".concat(i)),n!=null&&n.nonce&&(s.nonce=n==null?void 0:n.nonce),s.innerHTML=e;var c=Od(t),u=c.firstChild;if(r){if(l){var d=(t.styles||_h(c)).filter(function(v){if(!["prepend","prependQueue"].includes(v.getAttribute(dy)))return!1;var h=Number(v.getAttribute(fy)||0);return i>=h});if(d.length)return c.insertBefore(s,d[d.length-1].nextSibling),s}c.insertBefore(s,u)}else c.appendChild(s);return s}function JC(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=Od(t);return(t.styles||_h(n)).find(function(r){return r.getAttribute(QC(t))===e})}function Ss(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=JC(e,t);if(n){var r=Od(t);r.removeChild(n)}}function eI(e,t){var n=_p.get(e);if(!n||!Np(document,n)){var r=ZC("",t),o=r.parentNode;_p.set(e,o),e.removeChild(r)}}function Xo(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},r=Od(n),o=_h(r),i=U(U({},n),{},{styles:o});eI(r,i);var a=JC(t,i);if(a){var l,s;if((l=i.csp)!==null&&l!==void 0&&l.nonce&&a.nonce!==((s=i.csp)===null||s===void 0?void 0:s.nonce)){var c;a.nonce=(c=i.csp)===null||c===void 0?void 0:c.nonce}return a.innerHTML!==e&&(a.innerHTML=e),a}var u=ZC(e,i);return u.setAttribute(QC(i),t),u}function ex(e){var t;return e==null||(t=e.getRootNode)===null||t===void 0?void 0:t.call(e)}function tI(e){return ex(e)instanceof ShadowRoot}function Hu(e){return tI(e)?ex(e):null}var Ap={},nI=function(t){};function rI(e,t){}function oI(e,t){}function iI(){Ap={}}function tx(e,t,n){!t&&!Ap[n]&&(e(!1,n),Ap[n]=!0)}function Mn(e,t){tx(rI,e,t)}function nx(e,t){tx(oI,e,t)}Mn.preMessage=nI;Mn.resetWarned=iI;Mn.noteOnce=nx;function aI(e){return e.replace(/-(.)/g,function(t,n){return n.toUpperCase()})}function lI(e,t){Mn(e,"[@ant-design/icons] ".concat(t))}function vy(e){return Qe(e)==="object"&&typeof e.name=="string"&&typeof e.theme=="string"&&(Qe(e.icon)==="object"||typeof e.icon=="function")}function py(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return Object.keys(e).reduce(function(t,n){var r=e[n];switch(n){case"class":t.className=r,delete t.class;break;default:delete t[n],t[aI(n)]=r}return t},{})}function Dp(e,t,n){return n?lt.createElement(e.tag,U(U({key:t},py(e.attrs)),n),(e.children||[]).map(function(r,o){return Dp(r,"".concat(t,"-").concat(e.tag,"-").concat(o))})):lt.createElement(e.tag,U({key:t},py(e.attrs)),(e.children||[]).map(function(r,o){return Dp(r,"".concat(t,"-").concat(e.tag,"-").concat(o))}))}function rx(e){return Ai(e)[0]}function ox(e){return e?Array.isArray(e)?e:[e]:[]}var sI=`
+.anticon {
+ display: inline-block;
+ color: inherit;
+ font-style: normal;
+ line-height: 0;
+ text-align: center;
+ text-transform: none;
+ vertical-align: -0.125em;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.anticon > * {
+ line-height: 1;
+}
+
+.anticon svg {
+ display: inline-block;
+}
+
+.anticon::before {
+ display: none;
+}
+
+.anticon .anticon-icon {
+ display: block;
+}
+
+.anticon[tabindex] {
+ cursor: pointer;
+}
+
+.anticon-spin::before,
+.anticon-spin {
+ display: inline-block;
+ -webkit-animation: loadingCircle 1s infinite linear;
+ animation: loadingCircle 1s infinite linear;
+}
+
+@-webkit-keyframes loadingCircle {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes loadingCircle {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+`,cI=function(t){var n=f.exports.useContext(Th),r=n.csp,o=n.prefixCls,i=sI;o&&(i=i.replace(/anticon/g,o)),f.exports.useEffect(function(){var a=t.current,l=Hu(a);Xo(i,"@ant-design-icons",{prepend:!0,csp:r,attachTo:l})},[])},uI=["icon","className","onClick","style","primaryColor","secondaryColor"],Gl={primaryColor:"#333",secondaryColor:"#E6E6E6",calculated:!1};function dI(e){var t=e.primaryColor,n=e.secondaryColor;Gl.primaryColor=t,Gl.secondaryColor=n||rx(t),Gl.calculated=!!n}function fI(){return U({},Gl)}var Rd=function(t){var n=t.icon,r=t.className,o=t.onClick,i=t.style,a=t.primaryColor,l=t.secondaryColor,s=Je(t,uI),c=f.exports.useRef(),u=Gl;if(a&&(u={primaryColor:a,secondaryColor:l||rx(a)}),cI(c),lI(vy(n),"icon should be icon definiton, but got ".concat(n)),!vy(n))return null;var d=n;return d&&typeof d.icon=="function"&&(d=U(U({},d),{},{icon:d.icon(u.primaryColor,u.secondaryColor)})),Dp(d.icon,"svg-".concat(d.name),U(U({className:r,onClick:o,style:i,"data-icon":d.name,width:"1em",height:"1em",fill:"currentColor","aria-hidden":"true"},s),{},{ref:c}))};Rd.displayName="IconReact";Rd.getTwoToneColors=fI;Rd.setTwoToneColors=dI;const Ah=Rd;function ix(e){var t=ox(e),n=G(t,2),r=n[0],o=n[1];return Ah.setTwoToneColors({primaryColor:r,secondaryColor:o})}function vI(){var e=Ah.getTwoToneColors();return e.calculated?[e.primaryColor,e.secondaryColor]:e.primaryColor}var Id={exports:{}},Pd={};/**
+ * @license React
+ * react-jsx-runtime.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var pI=f.exports,gI=Symbol.for("react.element"),hI=Symbol.for("react.fragment"),mI=Object.prototype.hasOwnProperty,yI=pI.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,bI={key:!0,ref:!0,__self:!0,__source:!0};function ax(e,t,n){var r,o={},i=null,a=null;n!==void 0&&(i=""+n),t.key!==void 0&&(i=""+t.key),t.ref!==void 0&&(a=t.ref);for(r in t)mI.call(t,r)&&!bI.hasOwnProperty(r)&&(o[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps,t)o[r]===void 0&&(o[r]=t[r]);return{$$typeof:gI,type:e,key:i,ref:a,props:o,_owner:yI.current}}Pd.Fragment=hI;Pd.jsx=ax;Pd.jsxs=ax;(function(e){e.exports=Pd})(Id);const Tt=Id.exports.Fragment,C=Id.exports.jsx,ie=Id.exports.jsxs;var SI=["className","icon","spin","rotate","tabIndex","onClick","twoToneColor"];ix(QR.primary);var Td=f.exports.forwardRef(function(e,t){var n=e.className,r=e.icon,o=e.spin,i=e.rotate,a=e.tabIndex,l=e.onClick,s=e.twoToneColor,c=Je(e,SI),u=f.exports.useContext(Th),d=u.prefixCls,v=d===void 0?"anticon":d,h=u.rootClassName,g=te(h,v,V(V({},"".concat(v,"-").concat(r.name),!!r.name),"".concat(v,"-spin"),!!o||r.name==="loading"),n),p=a;p===void 0&&l&&(p=-1);var b=i?{msTransform:"rotate(".concat(i,"deg)"),transform:"rotate(".concat(i,"deg)")}:void 0,m=ox(s),y=G(m,2),S=y[0],x=y[1];return C("span",{role:"img","aria-label":r.name,...c,ref:t,tabIndex:p,onClick:l,className:g,children:C(Ah,{icon:r,primaryColor:S,secondaryColor:x,style:b})})});Td.displayName="AntdIcon";Td.getTwoToneColor=vI;Td.setTwoToneColor=ix;const Et=Td;var CI={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M464 144H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H212V212h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16zm-52 268H612V212h200v200zM464 544H160c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H212V612h200v200zm452-268H560c-8.8 0-16 7.2-16 16v304c0 8.8 7.2 16 16 16h304c8.8 0 16-7.2 16-16V560c0-8.8-7.2-16-16-16zm-52 268H612V612h200v200z"}}]},name:"appstore",theme:"outlined"};const xI=CI;var wI=function(t,n){return C(Et,{...t,ref:n,icon:xI})};const $I=f.exports.forwardRef(wI);var EI={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M842 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 140.3-113.7 254-254 254S258 594.3 258 454c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8 0 168.7 126.6 307.9 290 327.6V884H326.7c-13.7 0-24.7 14.3-24.7 32v36c0 4.4 2.8 8 6.2 8h407.6c3.4 0 6.2-3.6 6.2-8v-36c0-17.7-11-32-24.7-32H548V782.1c165.3-18 294-158 294-328.1zM512 624c93.9 0 170-75.2 170-168V232c0-92.8-76.1-168-170-168s-170 75.2-170 168v224c0 92.8 76.1 168 170 168zm-94-392c0-50.6 41.9-92 94-92s94 41.4 94 92v224c0 50.6-41.9 92-94 92s-94-41.4-94-92V232z"}}]},name:"audio",theme:"outlined"};const MI=EI;var OI=function(t,n){return C(Et,{...t,ref:n,icon:MI})};const RI=f.exports.forwardRef(OI);var II={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"}}]},name:"check-circle",theme:"filled"};const PI=II;var TI=function(t,n){return C(Et,{...t,ref:n,icon:PI})};const NI=f.exports.forwardRef(TI);var _I={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 00-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"}}]},name:"check",theme:"outlined"};const AI=_I;var DI=function(t,n){return C(Et,{...t,ref:n,icon:AI})};const lx=f.exports.forwardRef(DI);var LI={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M512 64c247.4 0 448 200.6 448 448S759.4 960 512 960 64 759.4 64 512 264.6 64 512 64zm127.98 274.82h-.04l-.08.06L512 466.75 384.14 338.88c-.04-.05-.06-.06-.08-.06a.12.12 0 00-.07 0c-.03 0-.05.01-.09.05l-45.02 45.02a.2.2 0 00-.05.09.12.12 0 000 .07v.02a.27.27 0 00.06.06L466.75 512 338.88 639.86c-.05.04-.06.06-.06.08a.12.12 0 000 .07c0 .03.01.05.05.09l45.02 45.02a.2.2 0 00.09.05.12.12 0 00.07 0c.02 0 .04-.01.08-.05L512 557.25l127.86 127.87c.04.04.06.05.08.05a.12.12 0 00.07 0c.03 0 .05-.01.09-.05l45.02-45.02a.2.2 0 00.05-.09.12.12 0 000-.07v-.02a.27.27 0 00-.05-.06L557.25 512l127.87-127.86c.04-.04.05-.06.05-.08a.12.12 0 000-.07c0-.03-.01-.05-.05-.09l-45.02-45.02a.2.2 0 00-.09-.05.12.12 0 00-.07 0z"}}]},name:"close-circle",theme:"filled"};const zI=LI;var FI=function(t,n){return C(Et,{...t,ref:n,icon:zI})};const Nd=f.exports.forwardRef(FI);var kI={icon:{tag:"svg",attrs:{"fill-rule":"evenodd",viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"}}]},name:"close",theme:"outlined"};const BI=kI;var jI=function(t,n){return C(Et,{...t,ref:n,icon:BI})};const eo=f.exports.forwardRef(jI);var HI={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M888 792H200V168c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v688c0 4.4 3.6 8 8 8h752c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM288 604a64 64 0 10128 0 64 64 0 10-128 0zm118-224a48 48 0 1096 0 48 48 0 10-96 0zm158 228a96 96 0 10192 0 96 96 0 10-192 0zm148-314a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"dot-chart",theme:"outlined"};const WI=HI;var VI=function(t,n){return C(Et,{...t,ref:n,icon:WI})};const UI=f.exports.forwardRef(VI);var YI={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"}}]},name:"down",theme:"outlined"};const GI=YI;var KI=function(t,n){return C(Et,{...t,ref:n,icon:GI})};const qI=f.exports.forwardRef(KI);var XI={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"ellipsis",theme:"outlined"};const QI=XI;var ZI=function(t,n){return C(Et,{...t,ref:n,icon:QI})};const JI=f.exports.forwardRef(ZI);var eP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"}},{tag:"path",attrs:{d:"M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"}}]},name:"eye-invisible",theme:"outlined"};const tP=eP;var nP=function(t,n){return C(Et,{...t,ref:n,icon:tP})};const rP=f.exports.forwardRef(nP);var oP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"}}]},name:"eye",theme:"outlined"};const iP=oP;var aP=function(t,n){return C(Et,{...t,ref:n,icon:iP})};const sx=f.exports.forwardRef(aP);var lP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z"}}]},name:"file",theme:"outlined"};const sP=lP;var cP=function(t,n){return C(Et,{...t,ref:n,icon:sP})};const cx=f.exports.forwardRef(cP);var uP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"}}]},name:"left",theme:"outlined"};const dP=uP;var fP=function(t,n){return C(Et,{...t,ref:n,icon:dP})};const vP=f.exports.forwardRef(fP);var pP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M574 665.4a8.03 8.03 0 00-11.3 0L446.5 781.6c-53.8 53.8-144.6 59.5-204 0-59.5-59.5-53.8-150.2 0-204l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3l-39.8-39.8a8.03 8.03 0 00-11.3 0L191.4 526.5c-84.6 84.6-84.6 221.5 0 306s221.5 84.6 306 0l116.2-116.2c3.1-3.1 3.1-8.2 0-11.3L574 665.4zm258.6-474c-84.6-84.6-221.5-84.6-306 0L410.3 307.6a8.03 8.03 0 000 11.3l39.7 39.7c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c53.8-53.8 144.6-59.5 204 0 59.5 59.5 53.8 150.2 0 204L665.3 562.6a8.03 8.03 0 000 11.3l39.8 39.8c3.1 3.1 8.2 3.1 11.3 0l116.2-116.2c84.5-84.6 84.5-221.5 0-306.1zM610.1 372.3a8.03 8.03 0 00-11.3 0L372.3 598.7a8.03 8.03 0 000 11.3l39.6 39.6c3.1 3.1 8.2 3.1 11.3 0l226.4-226.4c3.1-3.1 3.1-8.2 0-11.3l-39.5-39.6z"}}]},name:"link",theme:"outlined"};const gP=pP;var hP=function(t,n){return C(Et,{...t,ref:n,icon:gP})};const mP=f.exports.forwardRef(hP);var yP={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"}}]},name:"loading",theme:"outlined"};const bP=yP;var SP=function(t,n){return C(Et,{...t,ref:n,icon:bP})};const ux=f.exports.forwardRef(SP);var CP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M464 512a48 48 0 1096 0 48 48 0 10-96 0zm200 0a48 48 0 1096 0 48 48 0 10-96 0zm-400 0a48 48 0 1096 0 48 48 0 10-96 0zm661.2-173.6c-22.6-53.7-55-101.9-96.3-143.3a444.35 444.35 0 00-143.3-96.3C630.6 75.7 572.2 64 512 64h-2c-60.6.3-119.3 12.3-174.5 35.9a445.35 445.35 0 00-142 96.5c-40.9 41.3-73 89.3-95.2 142.8-23 55.4-34.6 114.3-34.3 174.9A449.4 449.4 0 00112 714v152a46 46 0 0046 46h152.1A449.4 449.4 0 00510 960h2.1c59.9 0 118-11.6 172.7-34.3a444.48 444.48 0 00142.8-95.2c41.3-40.9 73.8-88.7 96.5-142 23.6-55.2 35.6-113.9 35.9-174.5.3-60.9-11.5-120-34.8-175.6zm-151.1 438C704 845.8 611 884 512 884h-1.7c-60.3-.3-120.2-15.3-173.1-43.5l-8.4-4.5H188V695.2l-4.5-8.4C155.3 633.9 140.3 574 140 513.7c-.4-99.7 37.7-193.3 107.6-263.8 69.8-70.5 163.1-109.5 262.8-109.9h1.7c50 0 98.5 9.7 144.2 28.9 44.6 18.7 84.6 45.6 119 80 34.3 34.3 61.3 74.4 80 119 19.4 46.2 29.1 95.2 28.9 145.8-.6 99.6-39.7 192.9-110.1 262.7z"}}]},name:"message",theme:"outlined"};const xP=CP;var wP=function(t,n){return C(Et,{...t,ref:n,icon:xP})};const $P=f.exports.forwardRef(wP);var EP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M872 474H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h720c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"minus",theme:"outlined"};const MP=EP;var OP=function(t,n){return C(Et,{...t,ref:n,icon:MP})};const RP=f.exports.forwardRef(OP);var IP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M328 544h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"}},{tag:"path",attrs:{d:"M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"}}]},name:"minus-square",theme:"outlined"};const PP=IP;var TP=function(t,n){return C(Et,{...t,ref:n,icon:PP})};const NP=f.exports.forwardRef(TP);var _P={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 632H136v-39.9l138.5-164.3 150.1 178L658.1 489 888 761.6V792zm0-129.8L664.2 396.8c-3.2-3.8-9-3.8-12.2 0L424.6 666.4l-144-170.7c-3.2-3.8-9-3.8-12.2 0L136 652.7V232h752v430.2zM304 456a88 88 0 100-176 88 88 0 000 176zm0-116c15.5 0 28 12.5 28 28s-12.5 28-28 28-28-12.5-28-28 12.5-28 28-28z"}}]},name:"picture",theme:"outlined"};const AP=_P;var DP=function(t,n){return C(Et,{...t,ref:n,icon:AP})};const LP=f.exports.forwardRef(DP);var zP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"}},{tag:"path",attrs:{d:"M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z"}}]},name:"plus",theme:"outlined"};const FP=zP;var kP=function(t,n){return C(Et,{...t,ref:n,icon:FP})};const BP=f.exports.forwardRef(kP);var jP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M328 544h152v152c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V544h152c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H544V328c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v152H328c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"}},{tag:"path",attrs:{d:"M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z"}}]},name:"plus-square",theme:"outlined"};const HP=jP;var WP=function(t,n){return C(Et,{...t,ref:n,icon:HP})};const VP=f.exports.forwardRef(WP);var UP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"};const YP=UP;var GP=function(t,n){return C(Et,{...t,ref:n,icon:YP})};const KP=f.exports.forwardRef(GP);var qP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"defs",attrs:{},children:[{tag:"style",attrs:{}}]},{tag:"path",attrs:{d:"M672 418H144c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32zm-44 402H188V494h440v326z"}},{tag:"path",attrs:{d:"M819.3 328.5c-78.8-100.7-196-153.6-314.6-154.2l-.2-64c0-6.5-7.6-10.1-12.6-6.1l-128 101c-4 3.1-3.9 9.1 0 12.3L492 318.6c5.1 4 12.7.4 12.6-6.1v-63.9c12.9.1 25.9.9 38.8 2.5 42.1 5.2 82.1 18.2 119 38.7 38.1 21.2 71.2 49.7 98.4 84.3 27.1 34.7 46.7 73.7 58.1 115.8a325.95 325.95 0 016.5 140.9h74.9c14.8-103.6-11.3-213-81-302.3z"}}]},name:"rotate-left",theme:"outlined"};const XP=qP;var QP=function(t,n){return C(Et,{...t,ref:n,icon:XP})};const ZP=f.exports.forwardRef(QP);var JP={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"defs",attrs:{},children:[{tag:"style",attrs:{}}]},{tag:"path",attrs:{d:"M480.5 251.2c13-1.6 25.9-2.4 38.8-2.5v63.9c0 6.5 7.5 10.1 12.6 6.1L660 217.6c4-3.2 4-9.2 0-12.3l-128-101c-5.1-4-12.6-.4-12.6 6.1l-.2 64c-118.6.5-235.8 53.4-314.6 154.2A399.75 399.75 0 00123.5 631h74.9c-.9-5.3-1.7-10.7-2.4-16.1-5.1-42.1-2.1-84.1 8.9-124.8 11.4-42.2 31-81.1 58.1-115.8 27.2-34.7 60.3-63.2 98.4-84.3 37-20.6 76.9-33.6 119.1-38.8z"}},{tag:"path",attrs:{d:"M880 418H352c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32zm-44 402H396V494h440v326z"}}]},name:"rotate-right",theme:"outlined"};const e4=JP;var t4=function(t,n){return C(Et,{...t,ref:n,icon:e4})};const n4=f.exports.forwardRef(t4);var r4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"}}]},name:"search",theme:"outlined"};const o4=r4;var i4=function(t,n){return C(Et,{...t,ref:n,icon:o4})};const _d=f.exports.forwardRef(i4);var a4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"}}]},name:"setting",theme:"outlined"};const l4=a4;var s4=function(t,n){return C(Et,{...t,ref:n,icon:l4})};const c4=f.exports.forwardRef(s4);var u4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"}}]},name:"smile",theme:"outlined"};const d4=u4;var f4=function(t,n){return C(Et,{...t,ref:n,icon:d4})};const v4=f.exports.forwardRef(f4);var p4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M847.9 592H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h605.2L612.9 851c-4.1 5.2-.4 13 6.3 13h72.5c4.9 0 9.5-2.2 12.6-6.1l168.8-214.1c16.5-21 1.6-51.8-25.2-51.8zM872 356H266.8l144.3-183c4.1-5.2.4-13-6.3-13h-72.5c-4.9 0-9.5 2.2-12.6 6.1L150.9 380.2c-16.5 21-1.6 51.8 25.1 51.8h696c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"}}]},name:"swap",theme:"outlined"};const g4=p4;var h4=function(t,n){return C(Et,{...t,ref:n,icon:g4})};const gy=f.exports.forwardRef(h4);var m4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M912 302.3L784 376V224c0-35.3-28.7-64-64-64H128c-35.3 0-64 28.7-64 64v576c0 35.3 28.7 64 64 64h592c35.3 0 64-28.7 64-64V648l128 73.7c21.3 12.3 48-3.1 48-27.6V330c0-24.6-26.7-40-48-27.7zM712 792H136V232h576v560zm176-167l-104-59.8V458.9L888 399v226zM208 360h112c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H208c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8z"}}]},name:"video-camera",theme:"outlined"};const y4=m4;var b4=function(t,n){return C(Et,{...t,ref:n,icon:y4})};const S4=f.exports.forwardRef(b4);var C4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M690.1 377.4c5.9 0 11.8.2 17.6.5-24.4-128.7-158.3-227.1-319.9-227.1C209 150.8 64 271.4 64 420.2c0 81.1 43.6 154.2 111.9 203.6a21.5 21.5 0 019.1 17.6c0 2.4-.5 4.6-1.1 6.9-5.5 20.3-14.2 52.8-14.6 54.3-.7 2.6-1.7 5.2-1.7 7.9 0 5.9 4.8 10.8 10.8 10.8 2.3 0 4.2-.9 6.2-2l70.9-40.9c5.3-3.1 11-5 17.2-5 3.2 0 6.4.5 9.5 1.4 33.1 9.5 68.8 14.8 105.7 14.8 6 0 11.9-.1 17.8-.4-7.1-21-10.9-43.1-10.9-66 0-135.8 132.2-245.8 295.3-245.8zm-194.3-86.5c23.8 0 43.2 19.3 43.2 43.1s-19.3 43.1-43.2 43.1c-23.8 0-43.2-19.3-43.2-43.1s19.4-43.1 43.2-43.1zm-215.9 86.2c-23.8 0-43.2-19.3-43.2-43.1s19.3-43.1 43.2-43.1 43.2 19.3 43.2 43.1-19.4 43.1-43.2 43.1zm586.8 415.6c56.9-41.2 93.2-102 93.2-169.7 0-124-120.8-224.5-269.9-224.5-149 0-269.9 100.5-269.9 224.5S540.9 847.5 690 847.5c30.8 0 60.6-4.4 88.1-12.3 2.6-.8 5.2-1.2 7.9-1.2 5.2 0 9.9 1.6 14.3 4.1l59.1 34c1.7 1 3.3 1.7 5.2 1.7a9 9 0 006.4-2.6 9 9 0 002.6-6.4c0-2.2-.9-4.4-1.4-6.6-.3-1.2-7.6-28.3-12.2-45.3-.5-1.9-.9-3.8-.9-5.7.1-5.9 3.1-11.2 7.6-14.5zM600.2 587.2c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c0 19.8-16.2 35.9-36 35.9zm179.9 0c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9a36.08 36.08 0 01-36 35.9z"}}]},name:"wechat",theme:"outlined"};const x4=C4;var w4=function(t,n){return C(Et,{...t,ref:n,icon:x4})};const $4=f.exports.forwardRef(w4);var E4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M637 443H519V309c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v134H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h118v134c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V519h118c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zm284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z"}}]},name:"zoom-in",theme:"outlined"};const M4=E4;var O4=function(t,n){return C(Et,{...t,ref:n,icon:M4})};const R4=f.exports.forwardRef(O4);var I4={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M637 443H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h312c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zm284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z"}}]},name:"zoom-out",theme:"outlined"};const P4=I4;var T4=function(t,n){return C(Et,{...t,ref:n,icon:P4})};const N4=f.exports.forwardRef(T4);var Kl={exports:{}},Rt={};/**
+ * @license React
+ * react-is.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */var Dh=Symbol.for("react.element"),Lh=Symbol.for("react.portal"),Ad=Symbol.for("react.fragment"),Dd=Symbol.for("react.strict_mode"),Ld=Symbol.for("react.profiler"),zd=Symbol.for("react.provider"),Fd=Symbol.for("react.context"),_4=Symbol.for("react.server_context"),kd=Symbol.for("react.forward_ref"),Bd=Symbol.for("react.suspense"),jd=Symbol.for("react.suspense_list"),Hd=Symbol.for("react.memo"),Wd=Symbol.for("react.lazy"),A4=Symbol.for("react.offscreen"),dx;dx=Symbol.for("react.module.reference");function Cr(e){if(typeof e=="object"&&e!==null){var t=e.$$typeof;switch(t){case Dh:switch(e=e.type,e){case Ad:case Ld:case Dd:case Bd:case jd:return e;default:switch(e=e&&e.$$typeof,e){case _4:case Fd:case kd:case Wd:case Hd:case zd:return e;default:return t}}case Lh:return t}}}Rt.ContextConsumer=Fd;Rt.ContextProvider=zd;Rt.Element=Dh;Rt.ForwardRef=kd;Rt.Fragment=Ad;Rt.Lazy=Wd;Rt.Memo=Hd;Rt.Portal=Lh;Rt.Profiler=Ld;Rt.StrictMode=Dd;Rt.Suspense=Bd;Rt.SuspenseList=jd;Rt.isAsyncMode=function(){return!1};Rt.isConcurrentMode=function(){return!1};Rt.isContextConsumer=function(e){return Cr(e)===Fd};Rt.isContextProvider=function(e){return Cr(e)===zd};Rt.isElement=function(e){return typeof e=="object"&&e!==null&&e.$$typeof===Dh};Rt.isForwardRef=function(e){return Cr(e)===kd};Rt.isFragment=function(e){return Cr(e)===Ad};Rt.isLazy=function(e){return Cr(e)===Wd};Rt.isMemo=function(e){return Cr(e)===Hd};Rt.isPortal=function(e){return Cr(e)===Lh};Rt.isProfiler=function(e){return Cr(e)===Ld};Rt.isStrictMode=function(e){return Cr(e)===Dd};Rt.isSuspense=function(e){return Cr(e)===Bd};Rt.isSuspenseList=function(e){return Cr(e)===jd};Rt.isValidElementType=function(e){return typeof e=="string"||typeof e=="function"||e===Ad||e===Ld||e===Dd||e===Bd||e===jd||e===A4||typeof e=="object"&&e!==null&&(e.$$typeof===Wd||e.$$typeof===Hd||e.$$typeof===zd||e.$$typeof===Fd||e.$$typeof===kd||e.$$typeof===dx||e.getModuleId!==void 0)};Rt.typeOf=Cr;(function(e){e.exports=Rt})(Kl);function Hs(e,t,n){var r=f.exports.useRef({});return(!("value"in r.current)||n(r.current.condition,t))&&(r.current.value=e(),r.current.condition=t),r.current.value}function zh(e,t){typeof e=="function"?e(t):Qe(e)==="object"&&e&&"current"in e&&(e.current=t)}function xr(){for(var e=arguments.length,t=new Array(e),n=0;n1&&arguments[1]!==void 0?arguments[1]:{},n=[];return lt.Children.forEach(e,function(r){r==null&&!t.keepEmpty||(Array.isArray(r)?n=n.concat(Qo(r)):Kl.exports.isFragment(r)&&r.props?n=n.concat(Qo(r.props.children,t)):n.push(r))}),n}function Wu(e){return e instanceof HTMLElement||e instanceof SVGElement}function ql(e){return Wu(e)?e:e instanceof lt.Component?zu.findDOMNode(e):null}var Lp=f.exports.createContext(null);function D4(e){var t=e.children,n=e.onBatchResize,r=f.exports.useRef(0),o=f.exports.useRef([]),i=f.exports.useContext(Lp),a=f.exports.useCallback(function(l,s,c){r.current+=1;var u=r.current;o.current.push({size:l,element:s,data:c}),Promise.resolve().then(function(){u===r.current&&(n==null||n(o.current),o.current=[])}),i==null||i(l,s,c)},[n,i]);return C(Lp.Provider,{value:a,children:t})}var fx=function(){if(typeof Map<"u")return Map;function e(t,n){var r=-1;return t.some(function(o,i){return o[0]===n?(r=i,!0):!1}),r}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(n){var r=e(this.__entries__,n),o=this.__entries__[r];return o&&o[1]},t.prototype.set=function(n,r){var o=e(this.__entries__,n);~o?this.__entries__[o][1]=r:this.__entries__.push([n,r])},t.prototype.delete=function(n){var r=this.__entries__,o=e(r,n);~o&&r.splice(o,1)},t.prototype.has=function(n){return!!~e(this.__entries__,n)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(n,r){r===void 0&&(r=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!zp||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),j4?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!zp||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var n=t.propertyName,r=n===void 0?"":n,o=B4.some(function(i){return!!~r.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),vx=function(e,t){for(var n=0,r=Object.keys(t);n"u"||!(Element instanceof Object))){if(!(t instanceof Ua(t).Element))throw new TypeError('parameter 1 is not of type "Element".');var n=this.observations_;n.has(t)||(n.set(t,new X4(t)),this.controller_.addObserver(this),this.controller_.refresh())}},e.prototype.unobserve=function(t){if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");if(!(typeof Element>"u"||!(Element instanceof Object))){if(!(t instanceof Ua(t).Element))throw new TypeError('parameter 1 is not of type "Element".');var n=this.observations_;!n.has(t)||(n.delete(t),n.size||this.controller_.removeObserver(this))}},e.prototype.disconnect=function(){this.clearActive(),this.observations_.clear(),this.controller_.removeObserver(this)},e.prototype.gatherActive=function(){var t=this;this.clearActive(),this.observations_.forEach(function(n){n.isActive()&&t.activeObservations_.push(n)})},e.prototype.broadcastActive=function(){if(!!this.hasActive()){var t=this.callbackCtx_,n=this.activeObservations_.map(function(r){return new Q4(r.target,r.broadcastRect())});this.callback_.call(t,n,t),this.clearActive()}},e.prototype.clearActive=function(){this.activeObservations_.splice(0)},e.prototype.hasActive=function(){return this.activeObservations_.length>0},e}(),gx=typeof WeakMap<"u"?new WeakMap:new fx,hx=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var n=H4.getInstance(),r=new Z4(t,n,this);gx.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){hx.prototype[e]=function(){var t;return(t=gx.get(this))[e].apply(t,arguments)}});var J4=function(){return typeof Vu.ResizeObserver<"u"?Vu.ResizeObserver:hx}(),Lo=new Map;function eT(e){e.forEach(function(t){var n,r=t.target;(n=Lo.get(r))===null||n===void 0||n.forEach(function(o){return o(r)})})}var mx=new J4(eT);function tT(e,t){Lo.has(e)||(Lo.set(e,new Set),mx.observe(e)),Lo.get(e).add(t)}function nT(e,t){Lo.has(e)&&(Lo.get(e).delete(t),Lo.get(e).size||(mx.unobserve(e),Lo.delete(e)))}function zn(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function my(e,t){for(var n=0;n1&&arguments[1]!==void 0?arguments[1]:1;yy+=1;var r=yy;function o(i){if(i===0)Cx(r),t();else{var a=bx(function(){o(i-1)});kh.set(r,a)}}return o(n),r};St.cancel=function(e){var t=kh.get(e);return Cx(e),Sx(t)};function Yu(e){for(var t=0,n,r=0,o=e.length;o>=4;++r,o-=4)n=e.charCodeAt(r)&255|(e.charCodeAt(++r)&255)<<8|(e.charCodeAt(++r)&255)<<16|(e.charCodeAt(++r)&255)<<24,n=(n&65535)*1540483477+((n>>>16)*59797<<16),n^=n>>>24,t=(n&65535)*1540483477+((n>>>16)*59797<<16)^(t&65535)*1540483477+((t>>>16)*59797<<16);switch(o){case 3:t^=(e.charCodeAt(r+2)&255)<<16;case 2:t^=(e.charCodeAt(r+1)&255)<<8;case 1:t^=e.charCodeAt(r)&255,t=(t&65535)*1540483477+((t>>>16)*59797<<16)}return t^=t>>>13,t=(t&65535)*1540483477+((t>>>16)*59797<<16),((t^t>>>15)>>>0).toString(36)}function Vs(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1,r=new Set;function o(i,a){var l=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,s=r.has(i);if(Mn(!s,"Warning: There may be circular references"),s)return!1;if(i===a)return!0;if(n&&l>1)return!1;r.add(i);var c=l+1;if(Array.isArray(i)){if(!Array.isArray(a)||i.length!==a.length)return!1;for(var u=0;u1&&arguments[1]!==void 0?arguments[1]:!1,a={map:this.cache};return n.forEach(function(l){if(!a)a=void 0;else{var s;a=(s=a)===null||s===void 0||(s=s.map)===null||s===void 0?void 0:s.get(l)}}),(r=a)!==null&&r!==void 0&&r.value&&i&&(a.value[1]=this.cacheCallTimes++),(o=a)===null||o===void 0?void 0:o.value}},{key:"get",value:function(n){var r;return(r=this.internalGet(n,!0))===null||r===void 0?void 0:r[0]}},{key:"has",value:function(n){return!!this.internalGet(n)}},{key:"set",value:function(n,r){var o=this;if(!this.has(n)){if(this.size()+1>e.MAX_CACHE_SIZE+e.MAX_CACHE_OFFSET){var i=this.keys.reduce(function(c,u){var d=G(c,2),v=d[1];return o.internalGet(u)[1]0,void 0),by+=1}return Fn(e,[{key:"getDerivativeToken",value:function(n){return this.derivatives.reduce(function(r,o){return o(n,r)},void 0)}}]),e}(),Jf=new Bh;function Bp(e){var t=Array.isArray(e)?e:[e];return Jf.has(t)||Jf.set(t,new xx(t)),Jf.get(t)}var pT=new WeakMap,ev={};function gT(e,t){for(var n=pT,r=0;r3&&arguments[3]!==void 0?arguments[3]:{},i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!1;if(i)return e;var a=U(U({},o),{},(r={},V(r,Ya,t),V(r,zr,n),r)),l=Object.keys(a).map(function(s){var c=a[s];return c?"".concat(s,'="').concat(c,'"'):null}).filter(function(s){return s}).join(" ");return"")}var $x=function(t){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"";return"--".concat(n?"".concat(n,"-"):"").concat(t).replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z]+)([A-Z][a-z0-9]+)/g,"$1-$2").replace(/([a-z])([A-Z0-9])/g,"$1-$2").toLowerCase()},yT=function(t,n,r){return Object.keys(t).length?".".concat(n).concat(r!=null&&r.scope?".".concat(r.scope):"","{").concat(Object.entries(t).map(function(o){var i=G(o,2),a=i[0],l=i[1];return"".concat(a,":").concat(l,";")}).join(""),"}"):""},Ex=function(t,n,r){var o={},i={};return Object.entries(t).forEach(function(a){var l,s,c=G(a,2),u=c[0],d=c[1];if(r!=null&&(l=r.preserve)!==null&&l!==void 0&&l[u])i[u]=d;else if((typeof d=="string"||typeof d=="number")&&!(r!=null&&(s=r.ignore)!==null&&s!==void 0&&s[u])){var v,h=$x(u,r==null?void 0:r.prefix);o[h]=typeof d=="number"&&!(r!=null&&(v=r.unitless)!==null&&v!==void 0&&v[u])?"".concat(d,"px"):String(d),i[u]="var(".concat(h,")")}}),[i,yT(o,n,{scope:r==null?void 0:r.scope})]},xy=Rn()?f.exports.useLayoutEffect:f.exports.useEffect,Nt=function(t,n){var r=f.exports.useRef(!0);xy(function(){return t(r.current)},n),xy(function(){return r.current=!1,function(){r.current=!0}},[])},Hp=function(t,n){Nt(function(r){if(!r)return t()},n)},bT=U({},As),wy=bT.useInsertionEffect,ST=function(t,n,r){f.exports.useMemo(t,r),Nt(function(){return n(!0)},r)},CT=wy?function(e,t,n){return wy(function(){return e(),t()},n)}:ST,xT=U({},As),wT=xT.useInsertionEffect,$T=function(t){var n=[],r=!1;function o(i){r||n.push(i)}return f.exports.useEffect(function(){return r=!1,function(){r=!0,n.length&&n.forEach(function(i){return i()})}},t),o},ET=function(){return function(t){t()}},MT=typeof wT<"u"?$T:ET;function jh(e,t,n,r,o){var i=f.exports.useContext(Yd),a=i.cache,l=[e].concat(Oe(t)),s=kp(l),c=MT([s]),u=function(g){a.opUpdate(s,function(p){var b=p||[void 0,void 0],m=G(b,2),y=m[0],S=y===void 0?0:y,x=m[1],$=x,E=$||n(),w=[S,E];return g?g(w):w})};f.exports.useMemo(function(){u()},[s]);var d=a.opGet(s),v=d[1];return CT(function(){o==null||o(v)},function(h){return u(function(g){var p=G(g,2),b=p[0],m=p[1];return h&&b===0&&(o==null||o(v)),[b+1,m]}),function(){a.opUpdate(s,function(g){var p=g||[],b=G(p,2),m=b[0],y=m===void 0?0:m,S=b[1],x=y-1;return x===0?(c(function(){(h||!a.opGet(s))&&(r==null||r(S,!1))}),null):[y-1,S]})}},[s]),v}var OT={},RT="css",gi=new Map;function IT(e){gi.set(e,(gi.get(e)||0)+1)}function PT(e,t){if(typeof document<"u"){var n=document.querySelectorAll("style[".concat(Ya,'="').concat(e,'"]'));n.forEach(function(r){if(r[zo]===t){var o;(o=r.parentNode)===null||o===void 0||o.removeChild(r)}})}}var TT=0;function NT(e,t){gi.set(e,(gi.get(e)||0)-1);var n=Array.from(gi.keys()),r=n.filter(function(o){var i=gi.get(o)||0;return i<=0});n.length-r.length>TT&&r.forEach(function(o){PT(o,t),gi.delete(o)})}var _T=function(t,n,r,o){var i=r.getDerivativeToken(t),a=U(U({},i),n);return o&&(a=o(a)),a},Mx="token";function AT(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{},r=f.exports.useContext(Yd),o=r.cache.instanceId,i=r.container,a=n.salt,l=a===void 0?"":a,s=n.override,c=s===void 0?OT:s,u=n.formatToken,d=n.getComputedToken,v=n.cssVar,h=gT(function(){return Object.assign.apply(Object,[{}].concat(Oe(t)))},t),g=Xl(h),p=Xl(c),b=v?Xl(v):"",m=jh(Mx,[l,e.id,g,p,b],function(){var y,S=d?d(h,c,e):_T(h,c,e,u),x=U({},S),$="";if(v){var E=Ex(S,v.key,{prefix:v.prefix,ignore:v.ignore,unitless:v.unitless,preserve:v.preserve}),w=G(E,2);S=w[0],$=w[1]}var R=Cy(S,l);S._tokenKey=R,x._tokenKey=Cy(x,l);var P=(y=v==null?void 0:v.key)!==null&&y!==void 0?y:R;S._themeKey=P,IT(P);var N="".concat(RT,"-").concat(Yu(R));return S._hashId=N,[S,N,x,$,(v==null?void 0:v.key)||""]},function(y){NT(y[0]._themeKey,o)},function(y){var S=G(y,4),x=S[0],$=S[3];if(v&&$){var E=Xo($,Yu("css-variables-".concat(x._themeKey)),{mark:zr,prepend:"queue",attachTo:i,priority:-999});E[zo]=o,E.setAttribute(Ya,x._themeKey)}});return m}var DT=function(t,n,r){var o=G(t,5),i=o[2],a=o[3],l=o[4],s=r||{},c=s.plain;if(!a)return null;var u=i._tokenKey,d=-999,v={"data-rc-order":"prependQueue","data-rc-priority":"".concat(d)},h=Gu(a,l,u,v,c);return[d,u,h]},LT={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},Ox="comm",Rx="rule",Ix="decl",zT="@import",FT="@keyframes",kT="@layer",Px=Math.abs,Hh=String.fromCharCode;function Tx(e){return e.trim()}function eu(e,t,n){return e.replace(t,n)}function BT(e,t,n){return e.indexOf(t,n)}function Cs(e,t){return e.charCodeAt(t)|0}function xs(e,t,n){return e.slice(t,n)}function so(e){return e.length}function jT(e){return e.length}function Mc(e,t){return t.push(e),e}var Gd=1,Ga=1,Nx=0,Sr=0,en=0,nl="";function Wh(e,t,n,r,o,i,a,l){return{value:e,root:t,parent:n,type:r,props:o,children:i,line:Gd,column:Ga,length:a,return:"",siblings:l}}function HT(){return en}function WT(){return en=Sr>0?Cs(nl,--Sr):0,Ga--,en===10&&(Ga=1,Gd--),en}function Fr(){return en=Sr2||Wp(en)>3?"":" "}function GT(e,t){for(;--t&&Fr()&&!(en<48||en>102||en>57&&en<65||en>70&&en<97););return Kd(e,tu()+(t<6&&Mi()==32&&Fr()==32))}function Vp(e){for(;Fr();)switch(en){case e:return Sr;case 34:case 39:e!==34&&e!==39&&Vp(en);break;case 40:e===41&&Vp(e);break;case 92:Fr();break}return Sr}function KT(e,t){for(;Fr()&&e+en!==47+10;)if(e+en===42+42&&Mi()===47)break;return"/*"+Kd(t,Sr-1)+"*"+Hh(e===47?e:Fr())}function qT(e){for(;!Wp(Mi());)Fr();return Kd(e,Sr)}function XT(e){return UT(nu("",null,null,null,[""],e=VT(e),0,[0],e))}function nu(e,t,n,r,o,i,a,l,s){for(var c=0,u=0,d=a,v=0,h=0,g=0,p=1,b=1,m=1,y=0,S="",x=o,$=i,E=r,w=S;b;)switch(g=y,y=Fr()){case 40:if(g!=108&&Cs(w,d-1)==58){BT(w+=eu(nv(y),"&","&\f"),"&\f",Px(c?l[c-1]:0))!=-1&&(m=-1);break}case 34:case 39:case 91:w+=nv(y);break;case 9:case 10:case 13:case 32:w+=YT(g);break;case 92:w+=GT(tu()-1,7);continue;case 47:switch(Mi()){case 42:case 47:Mc(QT(KT(Fr(),tu()),t,n,s),s);break;default:w+="/"}break;case 123*p:l[c++]=so(w)*m;case 125*p:case 59:case 0:switch(y){case 0:case 125:b=0;case 59+u:m==-1&&(w=eu(w,/\f/g,"")),h>0&&so(w)-d&&Mc(h>32?Ey(w+";",r,n,d-1,s):Ey(eu(w," ","")+";",r,n,d-2,s),s);break;case 59:w+=";";default:if(Mc(E=$y(w,t,n,c,u,o,l,S,x=[],$=[],d,i),i),y===123)if(u===0)nu(w,t,E,E,x,i,d,l,$);else switch(v===99&&Cs(w,3)===110?100:v){case 100:case 108:case 109:case 115:nu(e,E,E,r&&Mc($y(e,E,E,0,0,o,l,S,o,x=[],d,$),$),o,$,d,l,r?x:$);break;default:nu(w,E,E,E,[""],$,0,l,$)}}c=u=h=0,p=m=1,S=w="",d=a;break;case 58:d=1+so(w),h=g;default:if(p<1){if(y==123)--p;else if(y==125&&p++==0&&WT()==125)continue}switch(w+=Hh(y),y*p){case 38:m=u>0?1:(w+="\f",-1);break;case 44:l[c++]=(so(w)-1)*m,m=1;break;case 64:Mi()===45&&(w+=nv(Fr())),v=Mi(),u=d=so(S=w+=qT(tu())),y++;break;case 45:g===45&&so(w)==2&&(p=0)}}return i}function $y(e,t,n,r,o,i,a,l,s,c,u,d){for(var v=o-1,h=o===0?i:[""],g=jT(h),p=0,b=0,m=0;p0?h[y]+" "+S:eu(S,/&\f/g,h[y])))&&(s[m++]=x);return Wh(e,t,n,o===0?Rx:l,s,c,u,d)}function QT(e,t,n,r){return Wh(e,t,n,Ox,Hh(HT()),xs(e,2,-2),0,r)}function Ey(e,t,n,r,o){return Wh(e,t,n,Ix,xs(e,0,r),xs(e,r+1,-1),r,o)}function Up(e,t){for(var n="",r=0;r1&&arguments[1]!==void 0?arguments[1]:{},r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{root:!0,parentSelectors:[]},o=r.root,i=r.injectHash,a=r.parentSelectors,l=n.hashId,s=n.layer;n.path;var c=n.hashPriority,u=n.transformers,d=u===void 0?[]:u;n.linters;var v="",h={};function g(S){var x=S.getName(l);if(!h[x]){var $=e(S.style,n,{root:!1,parentSelectors:a}),E=G($,1),w=E[0];h[x]="@keyframes ".concat(S.getName(l)).concat(w)}}function p(S){var x=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[];return S.forEach(function($){Array.isArray($)?p($,x):$&&x.push($)}),x}var b=p(Array.isArray(t)?t:[t]);if(b.forEach(function(S){var x=typeof S=="string"&&!o?{}:S;if(typeof x=="string")v+="".concat(x,`
+`);else if(x._keyframe)g(x);else{var $=d.reduce(function(E,w){var R;return(w==null||(R=w.visit)===null||R===void 0?void 0:R.call(w,E))||E},x);Object.keys($).forEach(function(E){var w=$[E];if(Qe(w)==="object"&&w&&(E!=="animationName"||!w._keyframe)&&!r3(w)){var R=!1,P=E.trim(),N=!1;(o||i)&&l?P.startsWith("@")?R=!0:P=o3(E,l,c):o&&!l&&(P==="&"||P==="")&&(P="",N=!0);var I=e(w,n,{root:N,injectHash:R,parentSelectors:[].concat(Oe(a),[P])}),z=G(I,2),F=z[0],T=z[1];h=U(U({},h),T),v+="".concat(P).concat(F)}else{let M=function(L,A){var B=L.replace(/[A-Z]/g,function(j){return"-".concat(j.toLowerCase())}),k=A;!LT[L]&&typeof k=="number"&&k!==0&&(k="".concat(k,"px")),L==="animationName"&&A!==null&&A!==void 0&&A._keyframe&&(g(A),k=A.getName(l)),v+="".concat(B,":").concat(k,";")};var O=M,D,_=(D=w==null?void 0:w.value)!==null&&D!==void 0?D:w;Qe(w)==="object"&&w!==null&&w!==void 0&&w[Dx]&&Array.isArray(_)?_.forEach(function(L){M(E,L)}):M(E,_)}})}}),!o)v="{".concat(v,"}");else if(s&&mT()){var m=s.split(","),y=m[m.length-1].trim();v="@layer ".concat(y," {").concat(v,"}"),m.length>1&&(v="@layer ".concat(s,"{%%%:%}").concat(v))}return[v,h]};function Lx(e,t){return Yu("".concat(e.join("%")).concat(t))}function a3(){return null}var zx="style";function Gp(e,t){var n=e.token,r=e.path,o=e.hashId,i=e.layer,a=e.nonce,l=e.clientOnly,s=e.order,c=s===void 0?0:s,u=f.exports.useContext(Yd),d=u.autoClear;u.mock;var v=u.defaultCache,h=u.hashPriority,g=u.container,p=u.ssrInline,b=u.transformers,m=u.linters,y=u.cache,S=n._tokenKey,x=[S].concat(Oe(r)),$=jp,E=jh(zx,x,function(){var I=x.join("|");if(e3(I)){var z=t3(I),F=G(z,2),T=F[0],D=F[1];if(T)return[T,S,D,{},l,c]}var _=t(),O=i3(_,{hashId:o,hashPriority:h,layer:i,path:r.join("-"),transformers:b,linters:m}),M=G(O,2),L=M[0],A=M[1],B=Yp(L),k=Lx(x,B);return[B,S,k,A,l,c]},function(I,z){var F=G(I,3),T=F[2];(z||d)&&jp&&Ss(T,{mark:zr})},function(I){var z=G(I,4),F=z[0];z[1];var T=z[2],D=z[3];if($&&F!==_x){var _={mark:zr,prepend:"queue",attachTo:g,priority:c},O=typeof a=="function"?a():a;O&&(_.csp={nonce:O});var M=Xo(F,T,_);M[zo]=y.instanceId,M.setAttribute(Ya,S),Object.keys(D).forEach(function(L){Xo(Yp(D[L]),"_effect-".concat(L),_)})}}),w=G(E,3),R=w[0],P=w[1],N=w[2];return function(I){var z;if(!p||$||!v)z=C(a3,{});else{var F;z=C("style",{...(F={},V(F,Ya,P),V(F,zr,N),F),dangerouslySetInnerHTML:{__html:R}})}return ie(Tt,{children:[z,I]})}}var l3=function(t,n,r){var o=G(t,6),i=o[0],a=o[1],l=o[2],s=o[3],c=o[4],u=o[5],d=r||{},v=d.plain;if(c)return null;var h=i,g={"data-rc-order":"prependQueue","data-rc-priority":"".concat(u)};return h=Gu(i,a,l,g,v),s&&Object.keys(s).forEach(function(p){if(!n[p]){n[p]=!0;var b=Yp(s[p]);h+=Gu(b,a,"_effect-".concat(p),g,v)}}),[u,l,h]},Fx="cssVar",s3=function(t,n){var r=t.key,o=t.prefix,i=t.unitless,a=t.ignore,l=t.token,s=t.scope,c=s===void 0?"":s,u=f.exports.useContext(Yd),d=u.cache.instanceId,v=u.container,h=l._tokenKey,g=[].concat(Oe(t.path),[r,c,h]),p=jh(Fx,g,function(){var b=n(),m=Ex(b,r,{prefix:o,unitless:i,ignore:a,scope:c}),y=G(m,2),S=y[0],x=y[1],$=Lx(g,x);return[S,x,$,r]},function(b){var m=G(b,3),y=m[2];jp&&Ss(y,{mark:zr})},function(b){var m=G(b,3),y=m[1],S=m[2];if(!!y){var x=Xo(y,S,{mark:zr,prepend:"queue",attachTo:v,priority:-999});x[zo]=d,x.setAttribute(Ya,r)}});return p},c3=function(t,n,r){var o=G(t,4),i=o[1],a=o[2],l=o[3],s=r||{},c=s.plain;if(!i)return null;var u=-999,d={"data-rc-order":"prependQueue","data-rc-priority":"".concat(u)},v=Gu(i,l,a,d,c);return[u,a,v]},bl;bl={},V(bl,zx,l3),V(bl,Mx,DT),V(bl,Fx,c3);var Ct=function(){function e(t,n){zn(this,e),V(this,"name",void 0),V(this,"style",void 0),V(this,"_keyframe",!0),this.name=t,this.style=n}return Fn(e,[{key:"getName",value:function(){var n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"";return n?"".concat(n,"-").concat(this.name):this.name}}]),e}();function Yi(e){return e.notSplit=!0,e}Yi(["borderTop","borderBottom"]),Yi(["borderTop"]),Yi(["borderBottom"]),Yi(["borderLeft","borderRight"]),Yi(["borderLeft"]),Yi(["borderRight"]);function kx(e){return VC(e)||yx(e)||Nh(e)||UC()}function qr(e,t){for(var n=e,r=0;r3&&arguments[3]!==void 0?arguments[3]:!1;return t.length&&r&&n===void 0&&!qr(e,t.slice(0,-1))?e:Bx(e,t,n,r)}function u3(e){return Qe(e)==="object"&&e!==null&&Object.getPrototypeOf(e)===Object.prototype}function Oy(e){return Array.isArray(e)?[]:{}}var d3=typeof Reflect>"u"?Object.keys:Reflect.ownKeys;function Ca(){for(var e=arguments.length,t=new Array(e),n=0;n{const e=()=>{};return e.deprecated=f3,e},p3=f.exports.createContext(void 0);var g3={items_per_page:"/ page",jump_to:"Go to",jump_to_confirm:"confirm",page:"Page",prev_page:"Previous Page",next_page:"Next Page",prev_5:"Previous 5 Pages",next_5:"Next 5 Pages",prev_3:"Previous 3 Pages",next_3:"Next 3 Pages",page_size:"Page Size"},h3={locale:"en_US",today:"Today",now:"Now",backToToday:"Back to today",ok:"OK",clear:"Clear",month:"Month",year:"Year",timeSelect:"select time",dateSelect:"select date",weekSelect:"Choose a week",monthSelect:"Choose a month",yearSelect:"Choose a year",decadeSelect:"Choose a decade",yearFormat:"YYYY",dateFormat:"M/D/YYYY",dayFormat:"D",dateTimeFormat:"M/D/YYYY HH:mm:ss",monthBeforeYear:!0,previousMonth:"Previous month (PageUp)",nextMonth:"Next month (PageDown)",previousYear:"Last year (Control + left)",nextYear:"Next year (Control + right)",previousDecade:"Last decade",nextDecade:"Next decade",previousCentury:"Last century",nextCentury:"Next century"};const m3={placeholder:"Select time",rangePlaceholder:["Start time","End time"]},Hx=m3,y3={lang:Object.assign({placeholder:"Select date",yearPlaceholder:"Select year",quarterPlaceholder:"Select quarter",monthPlaceholder:"Select month",weekPlaceholder:"Select week",rangePlaceholder:["Start date","End date"],rangeYearPlaceholder:["Start year","End year"],rangeQuarterPlaceholder:["Start quarter","End quarter"],rangeMonthPlaceholder:["Start month","End month"],rangeWeekPlaceholder:["Start week","End week"]},h3),timePickerLocale:Object.assign({},Hx)},Kp=y3,Qn="${label} is not a valid ${type}",b3={locale:"en",Pagination:g3,DatePicker:Kp,TimePicker:Hx,Calendar:Kp,global:{placeholder:"Please select"},Table:{filterTitle:"Filter menu",filterConfirm:"OK",filterReset:"Reset",filterEmptyText:"No filters",filterCheckall:"Select all items",filterSearchPlaceholder:"Search in filters",emptyText:"No data",selectAll:"Select current page",selectInvert:"Invert current page",selectNone:"Clear all data",selectionAll:"Select all data",sortTitle:"Sort",expand:"Expand row",collapse:"Collapse row",triggerDesc:"Click to sort descending",triggerAsc:"Click to sort ascending",cancelSort:"Click to cancel sorting"},Tour:{Next:"Next",Previous:"Previous",Finish:"Finish"},Modal:{okText:"OK",cancelText:"Cancel",justOkText:"OK"},Popconfirm:{okText:"OK",cancelText:"Cancel"},Transfer:{titles:["",""],searchPlaceholder:"Search here",itemUnit:"item",itemsUnit:"items",remove:"Remove",selectCurrent:"Select current page",removeCurrent:"Remove current page",selectAll:"Select all data",removeAll:"Remove all data",selectInvert:"Invert current page"},Upload:{uploading:"Uploading...",removeFile:"Remove file",uploadError:"Upload error",previewFile:"Preview file",downloadFile:"Download file"},Empty:{description:"No data"},Icon:{icon:"icon"},Text:{edit:"Edit",copy:"Copy",copied:"Copied",expand:"Expand"},Form:{optional:"(optional)",defaultValidateMessages:{default:"Field validation error for ${label}",required:"Please enter ${label}",enum:"${label} must be one of [${enum}]",whitespace:"${label} cannot be a blank character",date:{format:"${label} date format is invalid",parse:"${label} cannot be converted to a date",invalid:"${label} is an invalid date"},types:{string:Qn,method:Qn,array:Qn,object:Qn,number:Qn,date:Qn,boolean:Qn,integer:Qn,float:Qn,regexp:Qn,email:Qn,url:Qn,hex:Qn},string:{len:"${label} must be ${len} characters",min:"${label} must be at least ${min} characters",max:"${label} must be up to ${max} characters",range:"${label} must be between ${min}-${max} characters"},number:{len:"${label} must be equal to ${len}",min:"${label} must be minimum ${min}",max:"${label} must be maximum ${max}",range:"${label} must be between ${min}-${max}"},array:{len:"Must be ${len} ${label}",min:"At least ${min} ${label}",max:"At most ${max} ${label}",range:"The amount of ${label} must be between ${min}-${max}"},pattern:{mismatch:"${label} does not match the pattern ${pattern}"}}},Image:{preview:"Preview"},QRCode:{expired:"QR code expired",refresh:"Refresh",scanned:"Scanned"},ColorPicker:{presetEmpty:"Empty"}},Jo=b3;Object.assign({},Jo.Modal);let ru=[];const Ry=()=>ru.reduce((e,t)=>Object.assign(Object.assign({},e),t),Jo.Modal);function S3(e){if(e){const t=Object.assign({},e);return ru.push(t),Ry(),()=>{ru=ru.filter(n=>n!==t),Ry()}}Object.assign({},Jo.Modal)}const C3=f.exports.createContext(void 0),Vh=C3,x3=(e,t)=>{const n=f.exports.useContext(Vh),r=f.exports.useMemo(()=>{var i;const a=t||Jo[e],l=(i=n==null?void 0:n[e])!==null&&i!==void 0?i:{};return Object.assign(Object.assign({},typeof a=="function"?a():a),l||{})},[e,t,n]),o=f.exports.useMemo(()=>{const i=n==null?void 0:n.locale;return(n==null?void 0:n.exist)&&!i?Jo.locale:i},[n]);return[r,o]},Wx=x3,w3="internalMark",$3=e=>{const{locale:t={},children:n,_ANT_MARK__:r}=e;f.exports.useEffect(()=>S3(t&&t.Modal),[t]);const o=f.exports.useMemo(()=>Object.assign(Object.assign({},t),{exist:!0}),[t]);return C(Vh.Provider,{value:o,children:n})},E3=$3,M3=e=>{const{controlHeight:t}=e;return{controlHeightSM:t*.75,controlHeightXS:t*.5,controlHeightLG:t*1.25}},O3=M3;function R3(e){const{sizeUnit:t,sizeStep:n}=e;return{sizeXXL:t*(n+8),sizeXL:t*(n+4),sizeLG:t*(n+2),sizeMD:t*(n+1),sizeMS:t*n,size:t*n,sizeSM:t*(n-1),sizeXS:t*(n-2),sizeXXS:t*(n-3)}}const Vx={blue:"#1677ff",purple:"#722ED1",cyan:"#13C2C2",green:"#52C41A",magenta:"#EB2F96",pink:"#eb2f96",red:"#F5222D",orange:"#FA8C16",yellow:"#FADB14",volcano:"#FA541C",geekblue:"#2F54EB",gold:"#FAAD14",lime:"#A0D911"},I3=Object.assign(Object.assign({},Vx),{colorPrimary:"#1677ff",colorSuccess:"#52c41a",colorWarning:"#faad14",colorError:"#ff4d4f",colorInfo:"#1677ff",colorLink:"",colorTextBase:"",colorBgBase:"",fontFamily:`-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
+'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
+'Noto Color Emoji'`,fontFamilyCode:"'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace",fontSize:14,lineWidth:1,lineType:"solid",motionUnit:.1,motionBase:0,motionEaseOutCirc:"cubic-bezier(0.08, 0.82, 0.17, 1)",motionEaseInOutCirc:"cubic-bezier(0.78, 0.14, 0.15, 0.86)",motionEaseOut:"cubic-bezier(0.215, 0.61, 0.355, 1)",motionEaseInOut:"cubic-bezier(0.645, 0.045, 0.355, 1)",motionEaseOutBack:"cubic-bezier(0.12, 0.4, 0.29, 1.46)",motionEaseInBack:"cubic-bezier(0.71, -0.46, 0.88, 0.6)",motionEaseInQuint:"cubic-bezier(0.755, 0.05, 0.855, 0.06)",motionEaseOutQuint:"cubic-bezier(0.23, 1, 0.32, 1)",borderRadius:6,sizeUnit:4,sizeStep:4,sizePopupArrow:16,controlHeight:32,zIndexBase:0,zIndexPopupBase:1e3,opacityImage:1,wireframe:!1,motion:!0}),ws=I3;function P3(e,t){let{generateColorPalettes:n,generateNeutralColorPalettes:r}=t;const{colorSuccess:o,colorWarning:i,colorError:a,colorInfo:l,colorPrimary:s,colorBgBase:c,colorTextBase:u}=e,d=n(s),v=n(o),h=n(i),g=n(a),p=n(l),b=r(c,u),m=e.colorLink||e.colorInfo,y=n(m);return Object.assign(Object.assign({},b),{colorPrimaryBg:d[1],colorPrimaryBgHover:d[2],colorPrimaryBorder:d[3],colorPrimaryBorderHover:d[4],colorPrimaryHover:d[5],colorPrimary:d[6],colorPrimaryActive:d[7],colorPrimaryTextHover:d[8],colorPrimaryText:d[9],colorPrimaryTextActive:d[10],colorSuccessBg:v[1],colorSuccessBgHover:v[2],colorSuccessBorder:v[3],colorSuccessBorderHover:v[4],colorSuccessHover:v[4],colorSuccess:v[6],colorSuccessActive:v[7],colorSuccessTextHover:v[8],colorSuccessText:v[9],colorSuccessTextActive:v[10],colorErrorBg:g[1],colorErrorBgHover:g[2],colorErrorBorder:g[3],colorErrorBorderHover:g[4],colorErrorHover:g[5],colorError:g[6],colorErrorActive:g[7],colorErrorTextHover:g[8],colorErrorText:g[9],colorErrorTextActive:g[10],colorWarningBg:h[1],colorWarningBgHover:h[2],colorWarningBorder:h[3],colorWarningBorderHover:h[4],colorWarningHover:h[4],colorWarning:h[6],colorWarningActive:h[7],colorWarningTextHover:h[8],colorWarningText:h[9],colorWarningTextActive:h[10],colorInfoBg:p[1],colorInfoBgHover:p[2],colorInfoBorder:p[3],colorInfoBorderHover:p[4],colorInfoHover:p[4],colorInfo:p[6],colorInfoActive:p[7],colorInfoTextHover:p[8],colorInfoText:p[9],colorInfoTextActive:p[10],colorLinkHover:y[4],colorLink:y[6],colorLinkActive:y[7],colorBgMask:new Mt("#000").setAlpha(.45).toRgbString(),colorWhite:"#fff"})}const T3=e=>{let t=e,n=e,r=e,o=e;return e<6&&e>=5?t=e+1:e<16&&e>=6?t=e+2:e>=16&&(t=16),e<7&&e>=5?n=4:e<8&&e>=7?n=5:e<14&&e>=8?n=6:e<16&&e>=14?n=7:e>=16&&(n=8),e<6&&e>=2?r=1:e>=6&&(r=2),e>4&&e<8?o=4:e>=8&&(o=6),{borderRadius:e,borderRadiusXS:r,borderRadiusSM:n,borderRadiusLG:t,borderRadiusOuter:o}},N3=T3;function _3(e){const{motionUnit:t,motionBase:n,borderRadius:r,lineWidth:o}=e;return Object.assign({motionDurationFast:`${(n+t).toFixed(1)}s`,motionDurationMid:`${(n+t*2).toFixed(1)}s`,motionDurationSlow:`${(n+t*3).toFixed(1)}s`,lineWidthBold:o+1},N3(r))}const io=(e,t)=>new Mt(e).setAlpha(t).toRgbString(),Sl=(e,t)=>new Mt(e).darken(t).toHexString(),A3=e=>{const t=Ai(e);return{1:t[0],2:t[1],3:t[2],4:t[3],5:t[4],6:t[5],7:t[6],8:t[4],9:t[5],10:t[6]}},D3=(e,t)=>{const n=e||"#fff",r=t||"#000";return{colorBgBase:n,colorTextBase:r,colorText:io(r,.88),colorTextSecondary:io(r,.65),colorTextTertiary:io(r,.45),colorTextQuaternary:io(r,.25),colorFill:io(r,.15),colorFillSecondary:io(r,.06),colorFillTertiary:io(r,.04),colorFillQuaternary:io(r,.02),colorBgLayout:Sl(n,4),colorBgContainer:Sl(n,0),colorBgElevated:Sl(n,0),colorBgSpotlight:io(r,.85),colorBgBlur:"transparent",colorBorder:Sl(n,15),colorBorderSecondary:Sl(n,6)}};function ou(e){return(e+8)/e}function L3(e){const t=new Array(10).fill(null).map((n,r)=>{const o=r-1,i=e*Math.pow(2.71828,o/5),a=r>1?Math.floor(i):Math.ceil(i);return Math.floor(a/2)*2});return t[1]=e,t.map(n=>({size:n,lineHeight:ou(n)}))}const z3=e=>{const t=L3(e),n=t.map(u=>u.size),r=t.map(u=>u.lineHeight),o=n[1],i=n[0],a=n[2],l=r[1],s=r[0],c=r[2];return{fontSizeSM:i,fontSize:o,fontSizeLG:a,fontSizeXL:n[3],fontSizeHeading1:n[6],fontSizeHeading2:n[5],fontSizeHeading3:n[4],fontSizeHeading4:n[3],fontSizeHeading5:n[2],lineHeight:l,lineHeightLG:c,lineHeightSM:s,fontHeight:Math.round(l*o),fontHeightLG:Math.round(c*a),fontHeightSM:Math.round(s*i),lineHeightHeading1:r[6],lineHeightHeading2:r[5],lineHeightHeading3:r[4],lineHeightHeading4:r[3],lineHeightHeading5:r[2]}},F3=z3;function k3(e){const t=Object.keys(Vx).map(n=>{const r=Ai(e[n]);return new Array(10).fill(1).reduce((o,i,a)=>(o[`${n}-${a+1}`]=r[a],o[`${n}${a+1}`]=r[a],o),{})}).reduce((n,r)=>(n=Object.assign(Object.assign({},n),r),n),{});return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},e),t),P3(e,{generateColorPalettes:A3,generateNeutralColorPalettes:D3})),F3(e.fontSize)),R3(e)),O3(e)),_3(e))}const Ux=Bp(k3),qp={token:ws,override:{override:ws},hashed:!0},Yx=lt.createContext(qp),Gx="anticon",B3=(e,t)=>t||(e?`ant-${e}`:"ant"),ot=f.exports.createContext({getPrefixCls:B3,iconPrefixCls:Gx}),j3=`-ant-${Date.now()}-${Math.random()}`;function H3(e,t){const n={},r=(a,l)=>{let s=a.clone();return s=(l==null?void 0:l(s))||s,s.toRgbString()},o=(a,l)=>{const s=new Mt(a),c=Ai(s.toRgbString());n[`${l}-color`]=r(s),n[`${l}-color-disabled`]=c[1],n[`${l}-color-hover`]=c[4],n[`${l}-color-active`]=c[6],n[`${l}-color-outline`]=s.clone().setAlpha(.2).toRgbString(),n[`${l}-color-deprecated-bg`]=c[0],n[`${l}-color-deprecated-border`]=c[2]};if(t.primaryColor){o(t.primaryColor,"primary");const a=new Mt(t.primaryColor),l=Ai(a.toRgbString());l.forEach((c,u)=>{n[`primary-${u+1}`]=c}),n["primary-color-deprecated-l-35"]=r(a,c=>c.lighten(35)),n["primary-color-deprecated-l-20"]=r(a,c=>c.lighten(20)),n["primary-color-deprecated-t-20"]=r(a,c=>c.tint(20)),n["primary-color-deprecated-t-50"]=r(a,c=>c.tint(50)),n["primary-color-deprecated-f-12"]=r(a,c=>c.setAlpha(c.getAlpha()*.12));const s=new Mt(l[0]);n["primary-color-active-deprecated-f-30"]=r(s,c=>c.setAlpha(c.getAlpha()*.3)),n["primary-color-active-deprecated-d-02"]=r(s,c=>c.darken(2))}return t.successColor&&o(t.successColor,"success"),t.warningColor&&o(t.warningColor,"warning"),t.errorColor&&o(t.errorColor,"error"),t.infoColor&&o(t.infoColor,"info"),`
+ :root {
+ ${Object.keys(n).map(a=>`--${e}-${a}: ${n[a]};`).join(`
+`)}
+ }
+ `.trim()}function W3(e,t){const n=H3(e,t);Rn()&&Xo(n,`${j3}-dynamic-theme`)}const Xp=f.exports.createContext(!1),V3=e=>{let{children:t,disabled:n}=e;const r=f.exports.useContext(Xp);return C(Xp.Provider,{value:n!=null?n:r,children:t})},rl=Xp,Qp=f.exports.createContext(void 0),U3=e=>{let{children:t,size:n}=e;const r=f.exports.useContext(Qp);return C(Qp.Provider,{value:n||r,children:t})},qd=Qp;function Y3(){const e=f.exports.useContext(rl),t=f.exports.useContext(qd);return{componentDisabled:e,componentSize:t}}const $s=["blue","purple","cyan","green","magenta","pink","red","orange","yellow","volcano","geekblue","lime","gold"],G3="5.14.2";function rv(e){return e>=0&&e<=255}function Oc(e,t){const{r:n,g:r,b:o,a:i}=new Mt(e).toRgb();if(i<1)return e;const{r:a,g:l,b:s}=new Mt(t).toRgb();for(let c=.01;c<=1;c+=.01){const u=Math.round((n-a*(1-c))/c),d=Math.round((r-l*(1-c))/c),v=Math.round((o-s*(1-c))/c);if(rv(u)&&rv(d)&&rv(v))return new Mt({r:u,g:d,b:v,a:Math.round(c*100)/100}).toRgbString()}return new Mt({r:n,g:r,b:o,a:1}).toRgbString()}var K3=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{delete r[v]});const o=Object.assign(Object.assign({},n),r),i=480,a=576,l=768,s=992,c=1200,u=1600;if(o.motion===!1){const v="0s";o.motionDurationFast=v,o.motionDurationMid=v,o.motionDurationSlow=v}return Object.assign(Object.assign(Object.assign({},o),{colorFillContent:o.colorFillSecondary,colorFillContentHover:o.colorFill,colorFillAlter:o.colorFillQuaternary,colorBgContainerDisabled:o.colorFillTertiary,colorBorderBg:o.colorBgContainer,colorSplit:Oc(o.colorBorderSecondary,o.colorBgContainer),colorTextPlaceholder:o.colorTextQuaternary,colorTextDisabled:o.colorTextQuaternary,colorTextHeading:o.colorText,colorTextLabel:o.colorTextSecondary,colorTextDescription:o.colorTextTertiary,colorTextLightSolid:o.colorWhite,colorHighlight:o.colorError,colorBgTextHover:o.colorFillSecondary,colorBgTextActive:o.colorFill,colorIcon:o.colorTextTertiary,colorIconHover:o.colorText,colorErrorOutline:Oc(o.colorErrorBg,o.colorBgContainer),colorWarningOutline:Oc(o.colorWarningBg,o.colorBgContainer),fontSizeIcon:o.fontSizeSM,lineWidthFocus:o.lineWidth*4,lineWidth:o.lineWidth,controlOutlineWidth:o.lineWidth*2,controlInteractiveSize:o.controlHeight/2,controlItemBgHover:o.colorFillTertiary,controlItemBgActive:o.colorPrimaryBg,controlItemBgActiveHover:o.colorPrimaryBgHover,controlItemBgActiveDisabled:o.colorFill,controlTmpOutline:o.colorFillQuaternary,controlOutline:Oc(o.colorPrimaryBg,o.colorBgContainer),lineType:o.lineType,borderRadius:o.borderRadius,borderRadiusXS:o.borderRadiusXS,borderRadiusSM:o.borderRadiusSM,borderRadiusLG:o.borderRadiusLG,fontWeightStrong:600,opacityLoading:.65,linkDecoration:"none",linkHoverDecoration:"none",linkFocusDecoration:"none",controlPaddingHorizontal:12,controlPaddingHorizontalSM:8,paddingXXS:o.sizeXXS,paddingXS:o.sizeXS,paddingSM:o.sizeSM,padding:o.size,paddingMD:o.sizeMD,paddingLG:o.sizeLG,paddingXL:o.sizeXL,paddingContentHorizontalLG:o.sizeLG,paddingContentVerticalLG:o.sizeMS,paddingContentHorizontal:o.sizeMS,paddingContentVertical:o.sizeSM,paddingContentHorizontalSM:o.size,paddingContentVerticalSM:o.sizeXS,marginXXS:o.sizeXXS,marginXS:o.sizeXS,marginSM:o.sizeSM,margin:o.size,marginMD:o.sizeMD,marginLG:o.sizeLG,marginXL:o.sizeXL,marginXXL:o.sizeXXL,boxShadow:`
+ 0 6px 16px 0 rgba(0, 0, 0, 0.08),
+ 0 3px 6px -4px rgba(0, 0, 0, 0.12),
+ 0 9px 28px 8px rgba(0, 0, 0, 0.05)
+ `,boxShadowSecondary:`
+ 0 6px 16px 0 rgba(0, 0, 0, 0.08),
+ 0 3px 6px -4px rgba(0, 0, 0, 0.12),
+ 0 9px 28px 8px rgba(0, 0, 0, 0.05)
+ `,boxShadowTertiary:`
+ 0 1px 2px 0 rgba(0, 0, 0, 0.03),
+ 0 1px 6px -1px rgba(0, 0, 0, 0.02),
+ 0 2px 4px 0 rgba(0, 0, 0, 0.02)
+ `,screenXS:i,screenXSMin:i,screenXSMax:a-1,screenSM:a,screenSMMin:a,screenSMMax:l-1,screenMD:l,screenMDMin:l,screenMDMax:s-1,screenLG:s,screenLGMin:s,screenLGMax:c-1,screenXL:c,screenXLMin:c,screenXLMax:u-1,screenXXL:u,screenXXLMin:u,boxShadowPopoverArrow:"2px 2px 5px rgba(0, 0, 0, 0.05)",boxShadowCard:`
+ 0 1px 2px -2px ${new Mt("rgba(0, 0, 0, 0.16)").toRgbString()},
+ 0 3px 6px 0 ${new Mt("rgba(0, 0, 0, 0.12)").toRgbString()},
+ 0 5px 12px 4px ${new Mt("rgba(0, 0, 0, 0.09)").toRgbString()}
+ `,boxShadowDrawerRight:`
+ -6px 0 16px 0 rgba(0, 0, 0, 0.08),
+ -3px 0 6px -4px rgba(0, 0, 0, 0.12),
+ -9px 0 28px 8px rgba(0, 0, 0, 0.05)
+ `,boxShadowDrawerLeft:`
+ 6px 0 16px 0 rgba(0, 0, 0, 0.08),
+ 3px 0 6px -4px rgba(0, 0, 0, 0.12),
+ 9px 0 28px 8px rgba(0, 0, 0, 0.05)
+ `,boxShadowDrawerUp:`
+ 0 6px 16px 0 rgba(0, 0, 0, 0.08),
+ 0 3px 6px -4px rgba(0, 0, 0, 0.12),
+ 0 9px 28px 8px rgba(0, 0, 0, 0.05)
+ `,boxShadowDrawerDown:`
+ 0 -6px 16px 0 rgba(0, 0, 0, 0.08),
+ 0 -3px 6px -4px rgba(0, 0, 0, 0.12),
+ 0 -9px 28px 8px rgba(0, 0, 0, 0.05)
+ `,boxShadowTabsOverflowLeft:"inset 10px 0 8px -8px rgba(0, 0, 0, 0.08)",boxShadowTabsOverflowRight:"inset -10px 0 8px -8px rgba(0, 0, 0, 0.08)",boxShadowTabsOverflowTop:"inset 0 10px 8px -8px rgba(0, 0, 0, 0.08)",boxShadowTabsOverflowBottom:"inset 0 -10px 8px -8px rgba(0, 0, 0, 0.08)"}),r)}var Iy=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const r=n.getDerivativeToken(e),{override:o}=t,i=Iy(t,["override"]);let a=Object.assign(Object.assign({},r),{override:o});return a=Kx(a),i&&Object.entries(i).forEach(l=>{let[s,c]=l;const{theme:u}=c,d=Iy(c,["theme"]);let v=d;u&&(v=Qx(Object.assign(Object.assign({},a),d),{override:d},u)),a[s]=v}),a};function Kn(){const{token:e,hashed:t,theme:n,override:r,cssVar:o}=lt.useContext(Yx),i=`${G3}-${t||""}`,a=n||Ux,[l,s,c]=AT(a,[ws,e],{salt:i,override:r,getComputedToken:Qx,formatToken:Kx,cssVar:o&&{prefix:o.prefix,key:o.key,unitless:qx,ignore:Xx,preserve:q3}});return[a,c,t?s:"",l,o]}function hn(e){var t=f.exports.useRef();t.current=e;var n=f.exports.useCallback(function(){for(var r,o=arguments.length,i=new Array(o),a=0;a1&&arguments[1]!==void 0?arguments[1]:!1;return{boxSizing:"border-box",margin:0,padding:0,color:e.colorText,fontSize:e.fontSize,lineHeight:e.lineHeight,listStyle:"none",fontFamily:t?"inherit":e.fontFamily}},Uh=()=>({display:"inline-flex",alignItems:"center",color:"inherit",fontStyle:"normal",lineHeight:0,textAlign:"center",textTransform:"none",verticalAlign:"-0.125em",textRendering:"optimizeLegibility","-webkit-font-smoothing":"antialiased","-moz-osx-font-smoothing":"grayscale","> *":{lineHeight:1},svg:{display:"inline-block"}}),Us=()=>({"&::before":{display:"table",content:'""'},"&::after":{display:"table",clear:"both",content:'""'}}),X3=e=>({a:{color:e.colorLink,textDecoration:e.linkDecoration,backgroundColor:"transparent",outline:"none",cursor:"pointer",transition:`color ${e.motionDurationSlow}`,"-webkit-text-decoration-skip":"objects","&:hover":{color:e.colorLinkHover},"&:active":{color:e.colorLinkActive},[`&:active,
+ &:hover`]:{textDecoration:e.linkHoverDecoration,outline:0},"&:focus":{textDecoration:e.linkFocusDecoration,outline:0},"&[disabled]":{color:e.colorTextDisabled,cursor:"not-allowed"}}}),Q3=(e,t,n)=>{const{fontFamily:r,fontSize:o}=e,i=`[class^="${t}"], [class*=" ${t}"]`;return{[n?`.${n}`:i]:{fontFamily:r,fontSize:o,boxSizing:"border-box","&::before, &::after":{boxSizing:"border-box"},[i]:{boxSizing:"border-box","&::before, &::after":{boxSizing:"border-box"}}}}},Yh=e=>({outline:`${X(e.lineWidthFocus)} solid ${e.colorPrimaryBorder}`,outlineOffset:1,transition:"outline-offset 0s, outline 0s"}),Xd=e=>({"&:focus-visible":Object.assign({},Yh(e))});let Z3=Fn(function e(){zn(this,e)});const Zx=Z3;function J3(e,t,n){return t=Zo(t),Fh(e,Ud()?Reflect.construct(t,n||[],Zo(e).constructor):t.apply(e,n))}let e5=function(e){Bi(t,e);function t(n){var r;return zn(this,t),r=J3(this,t),r.result=0,n instanceof t?r.result=n.result:typeof n=="number"&&(r.result=n),r}return Fn(t,[{key:"add",value:function(r){return r instanceof t?this.result+=r.result:typeof r=="number"&&(this.result+=r),this}},{key:"sub",value:function(r){return r instanceof t?this.result-=r.result:typeof r=="number"&&(this.result-=r),this}},{key:"mul",value:function(r){return r instanceof t?this.result*=r.result:typeof r=="number"&&(this.result*=r),this}},{key:"div",value:function(r){return r instanceof t?this.result/=r.result:typeof r=="number"&&(this.result/=r),this}},{key:"equal",value:function(){return this.result}}]),t}(Zx);function t5(e,t,n){return t=Zo(t),Fh(e,Ud()?Reflect.construct(t,n||[],Zo(e).constructor):t.apply(e,n))}const Jx="CALC_UNIT";function iv(e){return typeof e=="number"?`${e}${Jx}`:e}let n5=function(e){Bi(t,e);function t(n){var r;return zn(this,t),r=t5(this,t),r.result="",n instanceof t?r.result=`(${n.result})`:typeof n=="number"?r.result=iv(n):typeof n=="string"&&(r.result=n),r}return Fn(t,[{key:"add",value:function(r){return r instanceof t?this.result=`${this.result} + ${r.getResult()}`:(typeof r=="number"||typeof r=="string")&&(this.result=`${this.result} + ${iv(r)}`),this.lowPriority=!0,this}},{key:"sub",value:function(r){return r instanceof t?this.result=`${this.result} - ${r.getResult()}`:(typeof r=="number"||typeof r=="string")&&(this.result=`${this.result} - ${iv(r)}`),this.lowPriority=!0,this}},{key:"mul",value:function(r){return this.lowPriority&&(this.result=`(${this.result})`),r instanceof t?this.result=`${this.result} * ${r.getResult(!0)}`:(typeof r=="number"||typeof r=="string")&&(this.result=`${this.result} * ${r}`),this.lowPriority=!1,this}},{key:"div",value:function(r){return this.lowPriority&&(this.result=`(${this.result})`),r instanceof t?this.result=`${this.result} / ${r.getResult(!0)}`:(typeof r=="number"||typeof r=="string")&&(this.result=`${this.result} / ${r}`),this.lowPriority=!1,this}},{key:"getResult",value:function(r){return this.lowPriority||r?`(${this.result})`:this.result}},{key:"equal",value:function(r){const{unit:o=!0}=r||{},i=new RegExp(`${Jx}`,"g");return this.result=this.result.replace(i,o?"px":""),typeof this.lowPriority<"u"?`calc(${this.result})`:this.result}}]),t}(Zx);const r5=e=>{const t=e==="css"?n5:e5;return n=>new t(n)},o5=r5;function i5(e){return e==="js"?{max:Math.max,min:Math.min}:{max:function(){for(var t=arguments.length,n=new Array(t),r=0;rX(o)).join(",")})`},min:function(){for(var t=arguments.length,n=new Array(t),r=0;rX(o)).join(",")})`}}}const ew=typeof CSSINJS_STATISTIC<"u";let Zp=!0;function $t(){for(var e=arguments.length,t=new Array(e),n=0;n{Object.keys(o).forEach(a=>{Object.defineProperty(r,a,{configurable:!0,enumerable:!0,get:()=>o[a]})})}),Zp=!0,r}const Py={};function a5(){}const l5=e=>{let t,n=e,r=a5;return ew&&typeof Proxy<"u"&&(t=new Set,n=new Proxy(e,{get(o,i){return Zp&&t.add(i),o[i]}}),r=(o,i)=>{var a;Py[o]={global:Array.from(t),component:Object.assign(Object.assign({},(a=Py[o])===null||a===void 0?void 0:a.component),i)}}),{token:n,keys:t,flush:r}},s5=(e,t)=>{const[n,r]=Kn();return Gp({theme:n,token:r,hashId:"",path:["ant-design-icons",e],nonce:()=>t==null?void 0:t.nonce},()=>[{[`.${e}`]:Object.assign(Object.assign({},Uh()),{[`.${e} .${e}-icon`]:{display:"block"}})}])},tw=s5,nw=(e,t,n)=>{var r;return typeof n=="function"?n($t(t,(r=t[e])!==null&&r!==void 0?r:{})):n!=null?n:{}},rw=(e,t,n,r)=>{const o=Object.assign({},t[e]);if(r!=null&&r.deprecatedTokens){const{deprecatedTokens:a}=r;a.forEach(l=>{let[s,c]=l;var u;((o==null?void 0:o[s])||(o==null?void 0:o[c]))&&((u=o[c])!==null&&u!==void 0||(o[c]=o==null?void 0:o[s]))})}const i=Object.assign(Object.assign({},n),o);return Object.keys(i).forEach(a=>{i[a]===t[a]&&delete i[a]}),i},c5=(e,t)=>`${[t,e.replace(/([A-Z]+)([A-Z][a-z]+)/g,"$1-$2").replace(/([a-z])([A-Z])/g,"$1-$2")].filter(Boolean).join("-")}`;function Gh(e,t,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:{};const o=Array.isArray(e)?e:[e,e],[i]=o,a=o.join("-");return function(l){let s=arguments.length>1&&arguments[1]!==void 0?arguments[1]:l;const[c,u,d,v,h]=Kn(),{getPrefixCls:g,iconPrefixCls:p,csp:b}=f.exports.useContext(ot),m=g(),y=h?"css":"js",S=o5(y),{max:x,min:$}=i5(y),E={theme:c,token:v,hashId:d,nonce:()=>b==null?void 0:b.nonce,clientOnly:r.clientOnly,order:r.order||-999};return Gp(Object.assign(Object.assign({},E),{clientOnly:!1,path:["Shared",m]}),()=>[{"&":X3(v)}]),tw(p,b),[Gp(Object.assign(Object.assign({},E),{path:[a,l,p]}),()=>{if(r.injectStyle===!1)return[];const{token:R,flush:P}=l5(v),N=nw(i,u,n),I=`.${l}`,z=rw(i,u,N,{deprecatedTokens:r.deprecatedTokens});h&&Object.keys(N).forEach(D=>{N[D]=`var(${$x(D,c5(i,h.prefix))})`});const F=$t(R,{componentCls:I,prefixCls:l,iconCls:`.${p}`,antCls:`.${m}`,calc:S,max:x,min:$},h?N:z),T=t(F,{hashId:d,prefixCls:l,rootPrefixCls:m,iconPrefixCls:p});return P(i,z),[r.resetStyle===!1?null:Q3(F,l,s),T]}),d]}}const Kh=(e,t,n,r)=>{const o=Gh(e,t,n,Object.assign({resetStyle:!1,order:-998},r));return a=>{let{prefixCls:l,rootCls:s=l}=a;return o(l,s),null}},u5=(e,t,n)=>{function r(c){return`${e}${c.slice(0,1).toUpperCase()}${c.slice(1)}`}const{unitless:o={},injectStyle:i=!0}=n!=null?n:{},a={[r("zIndexPopup")]:!0};Object.keys(o).forEach(c=>{a[r(c)]=o[c]});const l=c=>{let{rootCls:u,cssVar:d}=c;const[,v]=Kn();return s3({path:[e],prefix:d.prefix,key:d==null?void 0:d.key,unitless:Object.assign(Object.assign({},qx),a),ignore:Xx,token:v,scope:u},()=>{const h=nw(e,v,t),g=rw(e,v,h,{deprecatedTokens:n==null?void 0:n.deprecatedTokens});return Object.keys(h).forEach(p=>{g[r(p)]=g[p],delete g[p]}),g}),null};return c=>{const[,,,,u]=Kn();return[d=>i&&u?ie(Tt,{children:[C(l,{rootCls:c,cssVar:u,component:e}),d]}):d,u==null?void 0:u.key]}},vn=(e,t,n,r)=>{const o=Gh(e,t,n,r),i=u5(Array.isArray(e)?e[0]:e,n,r);return function(a){let l=arguments.length>1&&arguments[1]!==void 0?arguments[1]:a;const[,s]=o(a,l),[c,u]=i(l);return[c,s,u]}};function ow(e,t){return $s.reduce((n,r)=>{const o=e[`${r}1`],i=e[`${r}3`],a=e[`${r}6`],l=e[`${r}7`];return Object.assign(Object.assign({},n),t(r,{lightColor:o,lightBorderColor:i,darkColor:a,textColor:l}))},{})}const d5=Object.assign({},As),{useId:Ty}=d5,f5=()=>"",v5=typeof Ty>"u"?f5:Ty,p5=v5;function g5(e,t){var n;jx();const r=e||{},o=r.inherit===!1||!t?Object.assign(Object.assign({},qp),{hashed:(n=t==null?void 0:t.hashed)!==null&&n!==void 0?n:qp.hashed,cssVar:t==null?void 0:t.cssVar}):t,i=p5();return Hs(()=>{var a,l;if(!e)return t;const s=Object.assign({},o.components);Object.keys(e.components||{}).forEach(d=>{s[d]=Object.assign(Object.assign({},s[d]),e.components[d])});const c=`css-var-${i.replace(/:/g,"")}`,u=((a=r.cssVar)!==null&&a!==void 0?a:o.cssVar)&&Object.assign(Object.assign(Object.assign({prefix:"ant"},typeof o.cssVar=="object"?o.cssVar:{}),typeof r.cssVar=="object"?r.cssVar:{}),{key:typeof r.cssVar=="object"&&((l=r.cssVar)===null||l===void 0?void 0:l.key)||c});return Object.assign(Object.assign(Object.assign({},o),r),{token:Object.assign(Object.assign({},o.token),r.token),components:s,cssVar:u})},[r,o],(a,l)=>a.some((s,c)=>{const u=l[c];return!Vs(s,u,!0)}))}var h5=["children"],iw=f.exports.createContext({});function m5(e){var t=e.children,n=Je(e,h5);return C(iw.Provider,{value:n,children:t})}var y5=function(e){Bi(n,e);var t=Ws(n);function n(){return zn(this,n),t.apply(this,arguments)}return Fn(n,[{key:"render",value:function(){return this.props.children}}]),n}(f.exports.Component),vi="none",Rc="appear",Ic="enter",Pc="leave",Ny="none",Nr="prepare",xa="start",wa="active",qh="end",aw="prepared";function _y(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit".concat(e)]="webkit".concat(t),n["Moz".concat(e)]="moz".concat(t),n["ms".concat(e)]="MS".concat(t),n["O".concat(e)]="o".concat(t.toLowerCase()),n}function b5(e,t){var n={animationend:_y("Animation","AnimationEnd"),transitionend:_y("Transition","TransitionEnd")};return e&&("AnimationEvent"in t||delete n.animationend.animation,"TransitionEvent"in t||delete n.transitionend.transition),n}var S5=b5(Rn(),typeof window<"u"?window:{}),lw={};if(Rn()){var C5=document.createElement("div");lw=C5.style}var Tc={};function sw(e){if(Tc[e])return Tc[e];var t=S5[e];if(t)for(var n=Object.keys(t),r=n.length,o=0;o1&&arguments[1]!==void 0?arguments[1]:2;t();var i=St(function(){o<=1?r({isCanceled:function(){return i!==e.current}}):n(r,o-1)});e.current=i}return f.exports.useEffect(function(){return function(){t()}},[]),[n,t]};var $5=[Nr,xa,wa,qh],E5=[Nr,aw],vw=!1,M5=!0;function pw(e){return e===wa||e===qh}const O5=function(e,t,n){var r=_a(Ny),o=G(r,2),i=o[0],a=o[1],l=w5(),s=G(l,2),c=s[0],u=s[1];function d(){a(Nr,!0)}var v=t?E5:$5;return fw(function(){if(i!==Ny&&i!==qh){var h=v.indexOf(i),g=v[h+1],p=n(i);p===vw?a(g,!0):g&&c(function(b){function m(){b.isCanceled()||a(g,!0)}p===!0?m():Promise.resolve(p).then(m)})}},[e,i]),f.exports.useEffect(function(){return function(){u()}},[]),[d,i]};function R5(e,t,n,r){var o=r.motionEnter,i=o===void 0?!0:o,a=r.motionAppear,l=a===void 0?!0:a,s=r.motionLeave,c=s===void 0?!0:s,u=r.motionDeadline,d=r.motionLeaveImmediately,v=r.onAppearPrepare,h=r.onEnterPrepare,g=r.onLeavePrepare,p=r.onAppearStart,b=r.onEnterStart,m=r.onLeaveStart,y=r.onAppearActive,S=r.onEnterActive,x=r.onLeaveActive,$=r.onAppearEnd,E=r.onEnterEnd,w=r.onLeaveEnd,R=r.onVisibleChanged,P=_a(),N=G(P,2),I=N[0],z=N[1],F=_a(vi),T=G(F,2),D=T[0],_=T[1],O=_a(null),M=G(O,2),L=M[0],A=M[1],B=f.exports.useRef(!1),k=f.exports.useRef(null);function j(){return n()}var H=f.exports.useRef(!1);function W(){_(vi,!0),A(null,!0)}function Y(oe){var se=j();if(!(oe&&!oe.deadline&&oe.target!==se)){var le=H.current,Ce;D===Rc&&le?Ce=$==null?void 0:$(se,oe):D===Ic&&le?Ce=E==null?void 0:E(se,oe):D===Pc&&le&&(Ce=w==null?void 0:w(se,oe)),D!==vi&&le&&Ce!==!1&&W()}}var K=x5(Y),q=G(K,1),ee=q[0],Z=function(se){var le,Ce,ce;switch(se){case Rc:return le={},V(le,Nr,v),V(le,xa,p),V(le,wa,y),le;case Ic:return Ce={},V(Ce,Nr,h),V(Ce,xa,b),V(Ce,wa,S),Ce;case Pc:return ce={},V(ce,Nr,g),V(ce,xa,m),V(ce,wa,x),ce;default:return{}}},Q=f.exports.useMemo(function(){return Z(D)},[D]),ne=O5(D,!e,function(oe){if(oe===Nr){var se=Q[Nr];return se?se(j()):vw}if(re in Q){var le;A(((le=Q[re])===null||le===void 0?void 0:le.call(Q,j(),null))||null)}return re===wa&&(ee(j()),u>0&&(clearTimeout(k.current),k.current=setTimeout(function(){Y({deadline:!0})},u))),re===aw&&W(),M5}),ae=G(ne,2),J=ae[0],re=ae[1],fe=pw(re);H.current=fe,fw(function(){z(t);var oe=B.current;B.current=!0;var se;!oe&&t&&l&&(se=Rc),oe&&t&&i&&(se=Ic),(oe&&!t&&c||!oe&&d&&!t&&c)&&(se=Pc);var le=Z(se);se&&(e||le[Nr])?(_(se),J()):_(vi)},[t]),f.exports.useEffect(function(){(D===Rc&&!l||D===Ic&&!i||D===Pc&&!c)&&_(vi)},[l,i,c]),f.exports.useEffect(function(){return function(){B.current=!1,clearTimeout(k.current)}},[]);var ve=f.exports.useRef(!1);f.exports.useEffect(function(){I&&(ve.current=!0),I!==void 0&&D===vi&&((ve.current||I)&&(R==null||R(I)),ve.current=!0)},[I,D]);var pe=L;return Q[Nr]&&re===xa&&(pe=U({transition:"none"},pe)),[D,re,pe,I!=null?I:t]}function I5(e){var t=e;Qe(e)==="object"&&(t=e.transitionSupport);function n(o,i){return!!(o.motionName&&t&&i!==!1)}var r=f.exports.forwardRef(function(o,i){var a=o.visible,l=a===void 0?!0:a,s=o.removeOnLeave,c=s===void 0?!0:s,u=o.forceRender,d=o.children,v=o.motionName,h=o.leavedClassName,g=o.eventProps,p=f.exports.useContext(iw),b=p.motion,m=n(o,b),y=f.exports.useRef(),S=f.exports.useRef();function x(){try{return y.current instanceof HTMLElement?y.current:ql(S.current)}catch{return null}}var $=R5(m,l,x,o),E=G($,4),w=E[0],R=E[1],P=E[2],N=E[3],I=f.exports.useRef(N);N&&(I.current=!0);var z=f.exports.useCallback(function(A){y.current=A,zh(i,A)},[i]),F,T=U(U({},g),{},{visible:l});if(!d)F=null;else if(w===vi)N?F=d(U({},T),z):!c&&I.current&&h?F=d(U(U({},T),{},{className:h}),z):u||!c&&!h?F=d(U(U({},T),{},{style:{display:"none"}}),z):F=null;else{var D,_;R===Nr?_="prepare":pw(R)?_="active":R===xa&&(_="start");var O=Ly(v,"".concat(w,"-").concat(_));F=d(U(U({},T),{},{className:te(Ly(v,w),(D={},V(D,O,O&&_),V(D,v,typeof v=="string"),D)),style:P}),z)}if(f.exports.isValidElement(F)&&ki(F)){var M=F,L=M.ref;L||(F=f.exports.cloneElement(F,{ref:z}))}return C(y5,{ref:S,children:F})});return r.displayName="CSSMotion",r}const to=I5(dw);var Jp="add",eg="keep",tg="remove",av="removed";function P5(e){var t;return e&&Qe(e)==="object"&&"key"in e?t=e:t={key:e},U(U({},t),{},{key:String(t.key)})}function ng(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];return e.map(P5)}function T5(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[],n=[],r=0,o=t.length,i=ng(e),a=ng(t);i.forEach(function(c){for(var u=!1,d=r;d1});return s.forEach(function(c){n=n.filter(function(u){var d=u.key,v=u.status;return d!==c||v!==tg}),n.forEach(function(u){u.key===c&&(u.status=eg)})}),n}var N5=["component","children","onVisibleChanged","onAllRemoved"],_5=["status"],A5=["eventProps","visible","children","motionName","motionAppear","motionEnter","motionLeave","motionLeaveImmediately","motionDeadline","removeOnLeave","leavedClassName","onAppearPrepare","onAppearStart","onAppearActive","onAppearEnd","onEnterStart","onEnterActive","onEnterEnd","onLeaveStart","onLeaveActive","onLeaveEnd"];function D5(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:to,n=function(r){Bi(i,r);var o=Ws(i);function i(){var a;zn(this,i);for(var l=arguments.length,s=new Array(l),c=0;cnull;var F5=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);ot.endsWith("Color"))}const W5=e=>{const{prefixCls:t,iconPrefixCls:n,theme:r,holderRender:o}=e;t!==void 0&&(gw=t),r&&H5(r)&&W3(j5(),r)},V5=e=>{const{children:t,csp:n,autoInsertSpaceInButton:r,alert:o,anchor:i,form:a,locale:l,componentSize:s,direction:c,space:u,virtual:d,dropdownMatchSelectWidth:v,popupMatchSelectWidth:h,popupOverflow:g,legacyLocale:p,parentContext:b,iconPrefixCls:m,theme:y,componentDisabled:S,segmented:x,statistic:$,spin:E,calendar:w,carousel:R,cascader:P,collapse:N,typography:I,checkbox:z,descriptions:F,divider:T,drawer:D,skeleton:_,steps:O,image:M,layout:L,list:A,mentions:B,modal:k,progress:j,result:H,slider:W,breadcrumb:Y,menu:K,pagination:q,input:ee,empty:Z,badge:Q,radio:ne,rate:ae,switch:J,transfer:re,avatar:fe,message:ve,tag:pe,table:oe,card:se,tabs:le,timeline:Ce,timePicker:ce,upload:de,notification:xe,tree:he,colorPicker:ke,datePicker:we,rangePicker:ge,flex:Pe,wave:Se,dropdown:st,warning:nt,tour:Ne}=e,Ee=f.exports.useCallback((Re,be)=>{const{prefixCls:Ae}=e;if(be)return be;const Me=Ae||b.getPrefixCls("");return Re?`${Me}-${Re}`:Me},[b.getPrefixCls,e.prefixCls]),_e=m||b.iconPrefixCls||Gx,Be=n||b.csp;tw(_e,Be);const qe=g5(y,b.theme),it={csp:Be,autoInsertSpaceInButton:r,alert:o,anchor:i,locale:l||p,direction:c,space:u,virtual:d,popupMatchSelectWidth:h!=null?h:v,popupOverflow:g,getPrefixCls:Ee,iconPrefixCls:_e,theme:qe,segmented:x,statistic:$,spin:E,calendar:w,carousel:R,cascader:P,collapse:N,typography:I,checkbox:z,descriptions:F,divider:T,drawer:D,skeleton:_,steps:O,image:M,input:ee,layout:L,list:A,mentions:B,modal:k,progress:j,result:H,slider:W,breadcrumb:Y,menu:K,pagination:q,empty:Z,badge:Q,radio:ne,rate:ae,switch:J,transfer:re,avatar:fe,message:ve,tag:pe,table:oe,card:se,tabs:le,timeline:Ce,timePicker:ce,upload:de,notification:xe,tree:he,colorPicker:ke,datePicker:we,rangePicker:ge,flex:Pe,wave:Se,dropdown:st,warning:nt,tour:Ne},ft=Object.assign({},b);Object.keys(it).forEach(Re=>{it[Re]!==void 0&&(ft[Re]=it[Re])}),k5.forEach(Re=>{const be=e[Re];be&&(ft[Re]=be)});const ut=Hs(()=>ft,ft,(Re,be)=>{const Ae=Object.keys(Re),Me=Object.keys(be);return Ae.length!==Me.length||Ae.some($e=>Re[$e]!==be[$e])}),Ue=f.exports.useMemo(()=>({prefixCls:_e,csp:Be}),[_e,Be]);let He=ie(Tt,{children:[C(z5,{dropdownMatchSelectWidth:v}),t]});const Xe=f.exports.useMemo(()=>{var Re,be,Ae,Me;return Ca(((Re=Jo.Form)===null||Re===void 0?void 0:Re.defaultValidateMessages)||{},((Ae=(be=ut.locale)===null||be===void 0?void 0:be.Form)===null||Ae===void 0?void 0:Ae.defaultValidateMessages)||{},((Me=ut.form)===null||Me===void 0?void 0:Me.validateMessages)||{},(a==null?void 0:a.validateMessages)||{})},[ut,a==null?void 0:a.validateMessages]);Object.keys(Xe).length>0&&(He=C(p3.Provider,{value:Xe,children:He})),l&&(He=C(E3,{locale:l,_ANT_MARK__:w3,children:He})),(_e||Be)&&(He=C(Th.Provider,{value:Ue,children:He})),s&&(He=C(U3,{size:s,children:He})),He=C(L5,{children:He});const Le=f.exports.useMemo(()=>{const Re=qe||{},{algorithm:be,token:Ae,components:Me,cssVar:$e}=Re,Te=F5(Re,["algorithm","token","components","cssVar"]),ye=be&&(!Array.isArray(be)||be.length>0)?Bp(be):Ux,Ge={};Object.entries(Me||{}).forEach(et=>{let[ht,mt]=et;const ct=Object.assign({},mt);"algorithm"in ct&&(ct.algorithm===!0?ct.theme=ye:(Array.isArray(ct.algorithm)||typeof ct.algorithm=="function")&&(ct.theme=Bp(ct.algorithm)),delete ct.algorithm),Ge[ht]=ct});const Ze=Object.assign(Object.assign({},ws),Ae);return Object.assign(Object.assign({},Te),{theme:ye,token:Ze,components:Ge,override:Object.assign({override:Ze},Ge),cssVar:$e})},[qe]);return y&&(He=C(Yx.Provider,{value:Le,children:He})),ut.warning&&(He=C(v3.Provider,{value:ut.warning,children:He})),S!==void 0&&(He=C(V3,{disabled:S,children:He})),C(ot.Provider,{value:ut,children:He})},ai=e=>{const t=f.exports.useContext(ot),n=f.exports.useContext(Vh);return C(V5,{...Object.assign({parentContext:t,legacyLocale:n},e)})};ai.ConfigContext=ot;ai.SizeContext=qd;ai.config=W5;ai.useConfig=Y3;Object.defineProperty(ai,"SizeContext",{get:()=>qd});var U5=`accept acceptCharset accessKey action allowFullScreen allowTransparency
+ alt async autoComplete autoFocus autoPlay capture cellPadding cellSpacing challenge
+ charSet checked classID className colSpan cols content contentEditable contextMenu
+ controls coords crossOrigin data dateTime default defer dir disabled download draggable
+ encType form formAction formEncType formMethod formNoValidate formTarget frameBorder
+ headers height hidden high href hrefLang htmlFor httpEquiv icon id inputMode integrity
+ is keyParams keyType kind label lang list loop low manifest marginHeight marginWidth max maxLength media
+ mediaGroup method min minLength multiple muted name noValidate nonce open
+ optimum pattern placeholder poster preload radioGroup readOnly rel required
+ reversed role rowSpan rows sandbox scope scoped scrolling seamless selected
+ shape size sizes span spellCheck src srcDoc srcLang srcSet start step style
+ summary tabIndex target title type useMap value width wmode wrap`,Y5=`onCopy onCut onPaste onCompositionEnd onCompositionStart onCompositionUpdate onKeyDown
+ onKeyPress onKeyUp onFocus onBlur onChange onInput onSubmit onClick onContextMenu onDoubleClick
+ onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown
+ onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp onSelect onTouchCancel
+ onTouchEnd onTouchMove onTouchStart onScroll onWheel onAbort onCanPlay onCanPlayThrough
+ onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata
+ onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting onLoad onError`,G5="".concat(U5," ").concat(Y5).split(/[\s\n]+/),K5="aria-",q5="data-";function zy(e,t){return e.indexOf(t)===0}function Ka(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n;t===!1?n={aria:!0,data:!0,attr:!0}:t===!0?n={aria:!0}:n=U({},t);var r={};return Object.keys(e).forEach(function(o){(n.aria&&(o==="role"||zy(o,K5))||n.data&&zy(o,q5)||n.attr&&G5.includes(o))&&(r[o]=e[o])}),r}const{isValidElement:Es}=As;function hw(e){return e&&Es(e)&&e.type===f.exports.Fragment}function X5(e,t,n){return Es(e)?f.exports.cloneElement(e,typeof n=="function"?n(e.props||{}):n):t}function ti(e,t){return X5(e,e,t)}const Q5=e=>{const[,,,,t]=Kn();return t?`${e}-css-var`:""},no=Q5;var ue={MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,QUESTION_MARK:63,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,SLASH:191,APOSTROPHE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,WIN_IME:229,isTextModifyingKeyEvent:function(t){var n=t.keyCode;if(t.altKey&&!t.ctrlKey||t.metaKey||n>=ue.F1&&n<=ue.F12)return!1;switch(n){case ue.ALT:case ue.CAPS_LOCK:case ue.CONTEXT_MENU:case ue.CTRL:case ue.DOWN:case ue.END:case ue.ESC:case ue.HOME:case ue.INSERT:case ue.LEFT:case ue.MAC_FF_META:case ue.META:case ue.NUMLOCK:case ue.NUM_CENTER:case ue.PAGE_DOWN:case ue.PAGE_UP:case ue.PAUSE:case ue.PRINT_SCREEN:case ue.RIGHT:case ue.SHIFT:case ue.UP:case ue.WIN_KEY:case ue.WIN_KEY_RIGHT:return!1;default:return!0}},isCharacterKey:function(t){if(t>=ue.ZERO&&t<=ue.NINE||t>=ue.NUM_ZERO&&t<=ue.NUM_MULTIPLY||t>=ue.A&&t<=ue.Z||window.navigator.userAgent.indexOf("WebKit")!==-1&&t===0)return!0;switch(t){case ue.SPACE:case ue.QUESTION_MARK:case ue.NUM_PLUS:case ue.NUM_MINUS:case ue.NUM_PERIOD:case ue.NUM_DIVISION:case ue.SEMICOLON:case ue.DASH:case ue.EQUALS:case ue.COMMA:case ue.PERIOD:case ue.SLASH:case ue.APOSTROPHE:case ue.SINGLE_QUOTE:case ue.OPEN_SQUARE_BRACKET:case ue.BACKSLASH:case ue.CLOSE_SQUARE_BRACKET:return!0;default:return!1}}};const Z5=lt.createContext(void 0),mw=Z5,pi=100,J5=10,eN=pi*J5,yw={Modal:pi,Drawer:pi,Popover:pi,Popconfirm:pi,Tooltip:pi,Tour:pi},tN={SelectLike:50,Dropdown:50,DatePicker:50,Menu:50,ImagePreview:1};function nN(e){return e in yw}function Qd(e,t){const[,n]=Kn(),r=lt.useContext(mw),o=nN(e);if(t!==void 0)return[t,t];let i=r!=null?r:0;return o?(i+=(r?0:n.zIndexPopupBase)+yw[e],i=Math.min(i,n.zIndexPopupBase+eN)):i+=tN[e],[r===void 0?t:i,i]}function An(){An=function(){return t};var e,t={},n=Object.prototype,r=n.hasOwnProperty,o=Object.defineProperty||function(_,O,M){_[O]=M.value},i=typeof Symbol=="function"?Symbol:{},a=i.iterator||"@@iterator",l=i.asyncIterator||"@@asyncIterator",s=i.toStringTag||"@@toStringTag";function c(_,O,M){return Object.defineProperty(_,O,{value:M,enumerable:!0,configurable:!0,writable:!0}),_[O]}try{c({},"")}catch{c=function(M,L,A){return M[L]=A}}function u(_,O,M,L){var A=O&&O.prototype instanceof m?O:m,B=Object.create(A.prototype),k=new T(L||[]);return o(B,"_invoke",{value:N(_,M,k)}),B}function d(_,O,M){try{return{type:"normal",arg:_.call(O,M)}}catch(L){return{type:"throw",arg:L}}}t.wrap=u;var v="suspendedStart",h="suspendedYield",g="executing",p="completed",b={};function m(){}function y(){}function S(){}var x={};c(x,a,function(){return this});var $=Object.getPrototypeOf,E=$&&$($(D([])));E&&E!==n&&r.call(E,a)&&(x=E);var w=S.prototype=m.prototype=Object.create(x);function R(_){["next","throw","return"].forEach(function(O){c(_,O,function(M){return this._invoke(O,M)})})}function P(_,O){function M(A,B,k,j){var H=d(_[A],_,B);if(H.type!=="throw"){var W=H.arg,Y=W.value;return Y&&Qe(Y)=="object"&&r.call(Y,"__await")?O.resolve(Y.__await).then(function(K){M("next",K,k,j)},function(K){M("throw",K,k,j)}):O.resolve(Y).then(function(K){W.value=K,k(W)},function(K){return M("throw",K,k,j)})}j(H.arg)}var L;o(this,"_invoke",{value:function(B,k){function j(){return new O(function(H,W){M(B,k,H,W)})}return L=L?L.then(j,j):j()}})}function N(_,O,M){var L=v;return function(A,B){if(L===g)throw new Error("Generator is already running");if(L===p){if(A==="throw")throw B;return{value:e,done:!0}}for(M.method=A,M.arg=B;;){var k=M.delegate;if(k){var j=I(k,M);if(j){if(j===b)continue;return j}}if(M.method==="next")M.sent=M._sent=M.arg;else if(M.method==="throw"){if(L===v)throw L=p,M.arg;M.dispatchException(M.arg)}else M.method==="return"&&M.abrupt("return",M.arg);L=g;var H=d(_,O,M);if(H.type==="normal"){if(L=M.done?p:h,H.arg===b)continue;return{value:H.arg,done:M.done}}H.type==="throw"&&(L=p,M.method="throw",M.arg=H.arg)}}}function I(_,O){var M=O.method,L=_.iterator[M];if(L===e)return O.delegate=null,M==="throw"&&_.iterator.return&&(O.method="return",O.arg=e,I(_,O),O.method==="throw")||M!=="return"&&(O.method="throw",O.arg=new TypeError("The iterator does not provide a '"+M+"' method")),b;var A=d(L,_.iterator,O.arg);if(A.type==="throw")return O.method="throw",O.arg=A.arg,O.delegate=null,b;var B=A.arg;return B?B.done?(O[_.resultName]=B.value,O.next=_.nextLoc,O.method!=="return"&&(O.method="next",O.arg=e),O.delegate=null,b):B:(O.method="throw",O.arg=new TypeError("iterator result is not an object"),O.delegate=null,b)}function z(_){var O={tryLoc:_[0]};1 in _&&(O.catchLoc=_[1]),2 in _&&(O.finallyLoc=_[2],O.afterLoc=_[3]),this.tryEntries.push(O)}function F(_){var O=_.completion||{};O.type="normal",delete O.arg,_.completion=O}function T(_){this.tryEntries=[{tryLoc:"root"}],_.forEach(z,this),this.reset(!0)}function D(_){if(_||_===""){var O=_[a];if(O)return O.call(_);if(typeof _.next=="function")return _;if(!isNaN(_.length)){var M=-1,L=function A(){for(;++M<_.length;)if(r.call(_,M))return A.value=_[M],A.done=!1,A;return A.value=e,A.done=!0,A};return L.next=L}}throw new TypeError(Qe(_)+" is not iterable")}return y.prototype=S,o(w,"constructor",{value:S,configurable:!0}),o(S,"constructor",{value:y,configurable:!0}),y.displayName=c(S,s,"GeneratorFunction"),t.isGeneratorFunction=function(_){var O=typeof _=="function"&&_.constructor;return!!O&&(O===y||(O.displayName||O.name)==="GeneratorFunction")},t.mark=function(_){return Object.setPrototypeOf?Object.setPrototypeOf(_,S):(_.__proto__=S,c(_,s,"GeneratorFunction")),_.prototype=Object.create(w),_},t.awrap=function(_){return{__await:_}},R(P.prototype),c(P.prototype,l,function(){return this}),t.AsyncIterator=P,t.async=function(_,O,M,L,A){A===void 0&&(A=Promise);var B=new P(u(_,O,M,L),A);return t.isGeneratorFunction(O)?B:B.next().then(function(k){return k.done?k.value:B.next()})},R(w),c(w,s,"Generator"),c(w,a,function(){return this}),c(w,"toString",function(){return"[object Generator]"}),t.keys=function(_){var O=Object(_),M=[];for(var L in O)M.push(L);return M.reverse(),function A(){for(;M.length;){var B=M.pop();if(B in O)return A.value=B,A.done=!1,A}return A.done=!0,A}},t.values=D,T.prototype={constructor:T,reset:function(O){if(this.prev=0,this.next=0,this.sent=this._sent=e,this.done=!1,this.delegate=null,this.method="next",this.arg=e,this.tryEntries.forEach(F),!O)for(var M in this)M.charAt(0)==="t"&&r.call(this,M)&&!isNaN(+M.slice(1))&&(this[M]=e)},stop:function(){this.done=!0;var O=this.tryEntries[0].completion;if(O.type==="throw")throw O.arg;return this.rval},dispatchException:function(O){if(this.done)throw O;var M=this;function L(W,Y){return k.type="throw",k.arg=O,M.next=W,Y&&(M.method="next",M.arg=e),!!Y}for(var A=this.tryEntries.length-1;A>=0;--A){var B=this.tryEntries[A],k=B.completion;if(B.tryLoc==="root")return L("end");if(B.tryLoc<=this.prev){var j=r.call(B,"catchLoc"),H=r.call(B,"finallyLoc");if(j&&H){if(this.prev=0;--L){var A=this.tryEntries[L];if(A.tryLoc<=this.prev&&r.call(A,"finallyLoc")&&this.prev=0;--M){var L=this.tryEntries[M];if(L.finallyLoc===O)return this.complete(L.completion,L.afterLoc),F(L),b}},catch:function(O){for(var M=this.tryEntries.length-1;M>=0;--M){var L=this.tryEntries[M];if(L.tryLoc===O){var A=L.completion;if(A.type==="throw"){var B=A.arg;F(L)}return B}}throw new Error("illegal catch attempt")},delegateYield:function(O,M,L){return this.delegate={iterator:D(O),resultName:M,nextLoc:L},this.method==="next"&&(this.arg=e),b}},t}function Fy(e,t,n,r,o,i,a){try{var l=e[i](a),s=l.value}catch(c){n(c);return}l.done?t(s):Promise.resolve(s).then(r,o)}function ji(e){return function(){var t=this,n=arguments;return new Promise(function(r,o){var i=e.apply(t,n);function a(s){Fy(i,r,o,a,l,"next",s)}function l(s){Fy(i,r,o,a,l,"throw",s)}a(void 0)})}}var Ys=U({},$O),rN=Ys.version,oN=Ys.render,iN=Ys.unmountComponentAtNode,Zd;try{var aN=Number((rN||"").split(".")[0]);aN>=18&&(Zd=Ys.createRoot)}catch{}function ky(e){var t=Ys.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;t&&Qe(t)==="object"&&(t.usingClientEntryPoint=e)}var Ku="__rc_react_root__";function lN(e,t){ky(!0);var n=t[Ku]||Zd(t);ky(!1),n.render(e),t[Ku]=n}function sN(e,t){oN(e,t)}function cN(e,t){if(Zd){lN(e,t);return}sN(e,t)}function uN(e){return rg.apply(this,arguments)}function rg(){return rg=ji(An().mark(function e(t){return An().wrap(function(r){for(;;)switch(r.prev=r.next){case 0:return r.abrupt("return",Promise.resolve().then(function(){var o;(o=t[Ku])===null||o===void 0||o.unmount(),delete t[Ku]}));case 1:case"end":return r.stop()}},e)})),rg.apply(this,arguments)}function dN(e){iN(e)}function fN(e){return og.apply(this,arguments)}function og(){return og=ji(An().mark(function e(t){return An().wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(Zd===void 0){r.next=2;break}return r.abrupt("return",uN(t));case 2:dN(t);case 3:case"end":return r.stop()}},e)})),og.apply(this,arguments)}const ni=(e,t,n)=>n!==void 0?n:`${e}-${t}`,Jd=function(e){if(!e)return!1;if(e instanceof Element){if(e.offsetParent)return!0;if(e.getBBox){var t=e.getBBox(),n=t.width,r=t.height;if(n||r)return!0}if(e.getBoundingClientRect){var o=e.getBoundingClientRect(),i=o.width,a=o.height;if(i||a)return!0}}return!1},vN=e=>{const{componentCls:t,colorPrimary:n}=e;return{[t]:{position:"absolute",background:"transparent",pointerEvents:"none",boxSizing:"border-box",color:`var(--wave-color, ${n})`,boxShadow:"0 0 0 0 currentcolor",opacity:.2,"&.wave-motion-appear":{transition:[`box-shadow 0.4s ${e.motionEaseOutCirc}`,`opacity 2s ${e.motionEaseOutCirc}`].join(","),"&-active":{boxShadow:"0 0 0 6px currentcolor",opacity:0},"&.wave-quick":{transition:[`box-shadow 0.3s ${e.motionEaseInOut}`,`opacity 0.35s ${e.motionEaseInOut}`].join(",")}}}}},pN=Gh("Wave",e=>[vN(e)]);function gN(e){const t=(e||"").match(/rgba?\((\d*), (\d*), (\d*)(, [\d.]*)?\)/);return t&&t[1]&&t[2]&&t[3]?!(t[1]===t[2]&&t[2]===t[3]):!0}function lv(e){return e&&e!=="#fff"&&e!=="#ffffff"&&e!=="rgb(255, 255, 255)"&&e!=="rgba(255, 255, 255, 1)"&&gN(e)&&!/rgba\((?:\d*, ){3}0\)/.test(e)&&e!=="transparent"}function hN(e){const{borderTopColor:t,borderColor:n,backgroundColor:r}=getComputedStyle(e);return lv(t)?t:lv(n)?n:lv(r)?r:null}const Xh="ant-wave-target";function sv(e){return Number.isNaN(e)?0:e}const mN=e=>{const{className:t,target:n,component:r}=e,o=f.exports.useRef(null),[i,a]=f.exports.useState(null),[l,s]=f.exports.useState([]),[c,u]=f.exports.useState(0),[d,v]=f.exports.useState(0),[h,g]=f.exports.useState(0),[p,b]=f.exports.useState(0),[m,y]=f.exports.useState(!1),S={left:c,top:d,width:h,height:p,borderRadius:l.map(E=>`${E}px`).join(" ")};i&&(S["--wave-color"]=i);function x(){const E=getComputedStyle(n);a(hN(n));const w=E.position==="static",{borderLeftWidth:R,borderTopWidth:P}=E;u(w?n.offsetLeft:sv(-parseFloat(R))),v(w?n.offsetTop:sv(-parseFloat(P))),g(n.offsetWidth),b(n.offsetHeight);const{borderTopLeftRadius:N,borderTopRightRadius:I,borderBottomLeftRadius:z,borderBottomRightRadius:F}=E;s([N,I,F,z].map(T=>sv(parseFloat(T))))}if(f.exports.useEffect(()=>{if(n){const E=St(()=>{x(),y(!0)});let w;return typeof ResizeObserver<"u"&&(w=new ResizeObserver(x),w.observe(n)),()=>{St.cancel(E),w==null||w.disconnect()}}},[]),!m)return null;const $=(r==="Checkbox"||r==="Radio")&&(n==null?void 0:n.classList.contains(Xh));return C(to,{visible:!0,motionAppear:!0,motionName:"wave-motion",motionDeadline:5e3,onAppearEnd:(E,w)=>{var R;if(w.deadline||w.propertyName==="opacity"){const P=(R=o.current)===null||R===void 0?void 0:R.parentElement;fN(P).then(()=>{P==null||P.remove()})}return!1},children:E=>{let{className:w}=E;return C("div",{ref:o,className:te(t,{"wave-quick":$},w),style:S})}})},yN=(e,t)=>{var n;const{component:r}=t;if(r==="Checkbox"&&!(!((n=e.querySelector("input"))===null||n===void 0)&&n.checked))return;const o=document.createElement("div");o.style.position="absolute",o.style.left="0px",o.style.top="0px",e==null||e.insertBefore(o,e==null?void 0:e.firstChild),cN(C(mN,{...Object.assign({},t,{target:e})}),o)},bN=yN;function SN(e,t,n){const{wave:r}=f.exports.useContext(ot),[,o,i]=Kn(),a=hn(c=>{const u=e.current;if((r==null?void 0:r.disabled)||!u)return;const d=u.querySelector(`.${Xh}`)||u,{showEffect:v}=r||{};(v||bN)(d,{className:t,token:o,component:n,event:c,hashId:i})}),l=f.exports.useRef();return c=>{St.cancel(l.current),l.current=St(()=>{a(c)})}}const CN=e=>{const{children:t,disabled:n,component:r}=e,{getPrefixCls:o}=f.exports.useContext(ot),i=f.exports.useRef(null),a=o("wave"),[,l]=pN(a),s=SN(i,te(a,l),r);if(lt.useEffect(()=>{const u=i.current;if(!u||u.nodeType!==1||n)return;const d=v=>{!Jd(v.target)||!u.getAttribute||u.getAttribute("disabled")||u.disabled||u.className.includes("disabled")||u.className.includes("-leave")||s(v)};return u.addEventListener("click",d,!0),()=>{u.removeEventListener("click",d,!0)}},[n]),!lt.isValidElement(t))return t!=null?t:null;const c=ki(t)?xr(t.ref,i):i;return ti(t,{ref:c})},Qh=CN,xN=e=>{const t=lt.useContext(qd);return lt.useMemo(()=>e?typeof e=="string"?e!=null?e:t:e instanceof Function?e(t):t:t,[e,t])},So=xN;globalThis&&globalThis.__rest;const bw=f.exports.createContext(null),ef=(e,t)=>{const n=f.exports.useContext(bw),r=f.exports.useMemo(()=>{if(!n)return"";const{compactDirection:o,isFirstItem:i,isLastItem:a}=n,l=o==="vertical"?"-vertical-":"-";return te(`${e}-compact${l}item`,{[`${e}-compact${l}first-item`]:i,[`${e}-compact${l}last-item`]:a,[`${e}-compact${l}item-rtl`]:t==="rtl"})},[e,t,n]);return{compactSize:n==null?void 0:n.compactSize,compactDirection:n==null?void 0:n.compactDirection,compactItemClassnames:r}},ig=e=>{let{children:t}=e;return C(bw.Provider,{value:null,children:t})};var wN=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{getPrefixCls:t,direction:n}=f.exports.useContext(ot),{prefixCls:r,size:o,className:i}=e,a=wN(e,["prefixCls","size","className"]),l=t("btn-group",r),[,,s]=Kn();let c="";switch(o){case"large":c="lg";break;case"small":c="sm";break}const u=te(l,{[`${l}-${c}`]:c,[`${l}-rtl`]:n==="rtl"},i,s);return C(Sw.Provider,{value:o,children:C("div",{...Object.assign({},a,{className:u})})})},EN=$N,By=/^[\u4e00-\u9fa5]{2}$/,ag=By.test.bind(By);function jy(e){return typeof e=="string"}function cv(e){return e==="text"||e==="link"}function MN(e,t){if(e==null)return;const n=t?" ":"";return typeof e!="string"&&typeof e!="number"&&jy(e.type)&&ag(e.props.children)?ti(e,{children:e.props.children.split("").join(n)}):jy(e)?ag(e)?C("span",{children:e.split("").join(n)}):C("span",{children:e}):hw(e)?C("span",{children:e}):e}function ON(e,t){let n=!1;const r=[];return lt.Children.forEach(e,o=>{const i=typeof o,a=i==="string"||i==="number";if(n&&a){const l=r.length-1,s=r[l];r[l]=`${s}${o}`}else r.push(o);n=a}),lt.Children.map(r,o=>MN(o,t))}const RN=f.exports.forwardRef((e,t)=>{const{className:n,style:r,children:o,prefixCls:i}=e,a=te(`${i}-icon`,n);return C("span",{ref:t,className:a,style:r,children:o})}),Cw=RN,Hy=f.exports.forwardRef((e,t)=>{let{prefixCls:n,className:r,style:o,iconClassName:i}=e;const a=te(`${n}-loading-icon`,r);return C(Cw,{prefixCls:n,className:a,style:o,ref:t,children:C(ux,{className:i})})}),uv=()=>({width:0,opacity:0,transform:"scale(0)"}),dv=e=>({width:e.scrollWidth,opacity:1,transform:"scale(1)"}),IN=e=>{const{prefixCls:t,loading:n,existIcon:r,className:o,style:i}=e,a=!!n;return r?C(Hy,{prefixCls:t,className:o,style:i}):C(to,{visible:a,motionName:`${t}-loading-icon-motion`,motionLeave:a,removeOnLeave:!0,onAppearStart:uv,onAppearActive:dv,onEnterStart:uv,onEnterActive:dv,onLeaveStart:dv,onLeaveActive:uv,children:(l,s)=>{let{className:c,style:u}=l;return C(Hy,{prefixCls:t,className:o,style:Object.assign(Object.assign({},i),u),ref:s,iconClassName:c})}})},PN=IN,Wy=(e,t)=>({[`> span, > ${e}`]:{"&:not(:last-child)":{[`&, & > ${e}`]:{"&:not(:disabled)":{borderInlineEndColor:t}}},"&:not(:first-child)":{[`&, & > ${e}`]:{"&:not(:disabled)":{borderInlineStartColor:t}}}}}),TN=e=>{const{componentCls:t,fontSize:n,lineWidth:r,groupBorderColor:o,colorErrorHover:i}=e;return{[`${t}-group`]:[{position:"relative",display:"inline-flex",[`> span, > ${t}`]:{"&:not(:last-child)":{[`&, & > ${t}`]:{borderStartEndRadius:0,borderEndEndRadius:0}},"&:not(:first-child)":{marginInlineStart:e.calc(r).mul(-1).equal(),[`&, & > ${t}`]:{borderStartStartRadius:0,borderEndStartRadius:0}}},[t]:{position:"relative",zIndex:1,[`&:hover,
+ &:focus,
+ &:active`]:{zIndex:2},"&[disabled]":{zIndex:0}},[`${t}-icon-only`]:{fontSize:n}},Wy(`${t}-primary`,o),Wy(`${t}-danger`,i)]}},NN=TN,xw=e=>{const{paddingInline:t,onlyIconSize:n,paddingBlock:r}=e;return $t(e,{buttonPaddingHorizontal:t,buttonPaddingVertical:r,buttonIconOnlyFontSize:n})},ww=e=>{var t,n,r,o,i,a;const l=(t=e.contentFontSize)!==null&&t!==void 0?t:e.fontSize,s=(n=e.contentFontSizeSM)!==null&&n!==void 0?n:e.fontSize,c=(r=e.contentFontSizeLG)!==null&&r!==void 0?r:e.fontSizeLG,u=(o=e.contentLineHeight)!==null&&o!==void 0?o:ou(l),d=(i=e.contentLineHeightSM)!==null&&i!==void 0?i:ou(s),v=(a=e.contentLineHeightLG)!==null&&a!==void 0?a:ou(c);return{fontWeight:400,defaultShadow:`0 ${e.controlOutlineWidth}px 0 ${e.controlTmpOutline}`,primaryShadow:`0 ${e.controlOutlineWidth}px 0 ${e.controlOutline}`,dangerShadow:`0 ${e.controlOutlineWidth}px 0 ${e.colorErrorOutline}`,primaryColor:e.colorTextLightSolid,dangerColor:e.colorTextLightSolid,borderColorDisabled:e.colorBorder,defaultGhostColor:e.colorBgContainer,ghostBg:"transparent",defaultGhostBorderColor:e.colorBgContainer,paddingInline:e.paddingContentHorizontal-e.lineWidth,paddingInlineLG:e.paddingContentHorizontal-e.lineWidth,paddingInlineSM:8-e.lineWidth,onlyIconSize:e.fontSizeLG,onlyIconSizeSM:e.fontSizeLG-2,onlyIconSizeLG:e.fontSizeLG+2,groupBorderColor:e.colorPrimaryHover,linkHoverBg:"transparent",textHoverBg:e.colorBgTextHover,defaultColor:e.colorText,defaultBg:e.colorBgContainer,defaultBorderColor:e.colorBorder,defaultBorderColorDisabled:e.colorBorder,defaultHoverBg:e.colorBgContainer,defaultHoverColor:e.colorPrimaryHover,defaultHoverBorderColor:e.colorPrimaryHover,defaultActiveBg:e.colorBgContainer,defaultActiveColor:e.colorPrimaryActive,defaultActiveBorderColor:e.colorPrimaryActive,contentFontSize:l,contentFontSizeSM:s,contentFontSizeLG:c,contentLineHeight:u,contentLineHeightSM:d,contentLineHeightLG:v,paddingBlock:Math.max((e.controlHeight-l*u)/2-e.lineWidth,0),paddingBlockSM:Math.max((e.controlHeightSM-s*d)/2-e.lineWidth,0),paddingBlockLG:Math.max((e.controlHeightLG-c*v)/2-e.lineWidth,0)}},_N=e=>{const{componentCls:t,iconCls:n,fontWeight:r}=e;return{[t]:{outline:"none",position:"relative",display:"inline-block",fontWeight:r,whiteSpace:"nowrap",textAlign:"center",backgroundImage:"none",background:"transparent",border:`${X(e.lineWidth)} ${e.lineType} transparent`,cursor:"pointer",transition:`all ${e.motionDurationMid} ${e.motionEaseInOut}`,userSelect:"none",touchAction:"manipulation",color:e.colorText,"&:disabled > *":{pointerEvents:"none"},"> span":{display:"inline-block"},[`${t}-icon`]:{lineHeight:0},[`> ${n} + span, > span + ${n}`]:{marginInlineStart:e.marginXS},[`&:not(${t}-icon-only) > ${t}-icon`]:{[`&${t}-loading-icon, &:not(:last-child)`]:{marginInlineEnd:e.marginXS}},"> a":{color:"currentColor"},"&:not(:disabled)":Object.assign({},Xd(e)),[`&${t}-two-chinese-chars::first-letter`]:{letterSpacing:"0.34em"},[`&${t}-two-chinese-chars > *:not(${n})`]:{marginInlineEnd:"-0.34em",letterSpacing:"0.34em"},[`&-icon-only${t}-compact-item`]:{flex:"none"}}}},yo=(e,t,n)=>({[`&:not(:disabled):not(${e}-disabled)`]:{"&:hover":t,"&:active":n}}),AN=e=>({minWidth:e.controlHeight,paddingInlineStart:0,paddingInlineEnd:0,borderRadius:"50%"}),DN=e=>({borderRadius:e.controlHeight,paddingInlineStart:e.calc(e.controlHeight).div(2).equal(),paddingInlineEnd:e.calc(e.controlHeight).div(2).equal()}),LN=e=>({cursor:"not-allowed",borderColor:e.borderColorDisabled,color:e.colorTextDisabled,background:e.colorBgContainerDisabled,boxShadow:"none"}),Ms=(e,t,n,r,o,i,a,l)=>({[`&${e}-background-ghost`]:Object.assign(Object.assign({color:n||void 0,background:t,borderColor:r||void 0,boxShadow:"none"},yo(e,Object.assign({background:t},a),Object.assign({background:t},l))),{"&:disabled":{cursor:"not-allowed",color:o||void 0,borderColor:i||void 0}})}),Zh=e=>({[`&:disabled, &${e.componentCls}-disabled`]:Object.assign({},LN(e))}),$w=e=>Object.assign({},Zh(e)),qu=e=>({[`&:disabled, &${e.componentCls}-disabled`]:{cursor:"not-allowed",color:e.colorTextDisabled}}),Ew=e=>Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},$w(e)),{background:e.defaultBg,borderColor:e.defaultBorderColor,color:e.defaultColor,boxShadow:e.defaultShadow}),yo(e.componentCls,{color:e.defaultHoverColor,borderColor:e.defaultHoverBorderColor,background:e.defaultHoverBg},{color:e.defaultActiveColor,borderColor:e.defaultActiveBorderColor,background:e.defaultActiveBg})),Ms(e.componentCls,e.ghostBg,e.defaultGhostColor,e.defaultGhostBorderColor,e.colorTextDisabled,e.colorBorder)),{[`&${e.componentCls}-dangerous`]:Object.assign(Object.assign(Object.assign({color:e.colorError,borderColor:e.colorError},yo(e.componentCls,{color:e.colorErrorHover,borderColor:e.colorErrorBorderHover},{color:e.colorErrorActive,borderColor:e.colorErrorActive})),Ms(e.componentCls,e.ghostBg,e.colorError,e.colorError,e.colorTextDisabled,e.colorBorder)),Zh(e))}),zN=e=>Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},$w(e)),{color:e.primaryColor,background:e.colorPrimary,boxShadow:e.primaryShadow}),yo(e.componentCls,{color:e.colorTextLightSolid,background:e.colorPrimaryHover},{color:e.colorTextLightSolid,background:e.colorPrimaryActive})),Ms(e.componentCls,e.ghostBg,e.colorPrimary,e.colorPrimary,e.colorTextDisabled,e.colorBorder,{color:e.colorPrimaryHover,borderColor:e.colorPrimaryHover},{color:e.colorPrimaryActive,borderColor:e.colorPrimaryActive})),{[`&${e.componentCls}-dangerous`]:Object.assign(Object.assign(Object.assign({background:e.colorError,boxShadow:e.dangerShadow,color:e.dangerColor},yo(e.componentCls,{background:e.colorErrorHover},{background:e.colorErrorActive})),Ms(e.componentCls,e.ghostBg,e.colorError,e.colorError,e.colorTextDisabled,e.colorBorder,{color:e.colorErrorHover,borderColor:e.colorErrorHover},{color:e.colorErrorActive,borderColor:e.colorErrorActive})),Zh(e))}),FN=e=>Object.assign(Object.assign({},Ew(e)),{borderStyle:"dashed"}),kN=e=>Object.assign(Object.assign(Object.assign({color:e.colorLink},yo(e.componentCls,{color:e.colorLinkHover,background:e.linkHoverBg},{color:e.colorLinkActive})),qu(e)),{[`&${e.componentCls}-dangerous`]:Object.assign(Object.assign({color:e.colorError},yo(e.componentCls,{color:e.colorErrorHover},{color:e.colorErrorActive})),qu(e))}),BN=e=>Object.assign(Object.assign(Object.assign({},yo(e.componentCls,{color:e.colorText,background:e.textHoverBg},{color:e.colorText,background:e.colorBgTextActive})),qu(e)),{[`&${e.componentCls}-dangerous`]:Object.assign(Object.assign({color:e.colorError},qu(e)),yo(e.componentCls,{color:e.colorErrorHover,background:e.colorErrorBg},{color:e.colorErrorHover,background:e.colorErrorBg}))}),jN=e=>{const{componentCls:t}=e;return{[`${t}-default`]:Ew(e),[`${t}-primary`]:zN(e),[`${t}-dashed`]:FN(e),[`${t}-link`]:kN(e),[`${t}-text`]:BN(e),[`${t}-ghost`]:Ms(e.componentCls,e.ghostBg,e.colorBgContainer,e.colorBgContainer,e.colorTextDisabled,e.colorBorder)}},Jh=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"";const{componentCls:n,controlHeight:r,fontSize:o,lineHeight:i,borderRadius:a,buttonPaddingHorizontal:l,iconCls:s,buttonPaddingVertical:c}=e,u=`${n}-icon-only`;return[{[`${t}`]:{fontSize:o,lineHeight:i,height:r,padding:`${X(c)} ${X(l)}`,borderRadius:a,[`&${u}`]:{width:r,paddingInlineStart:0,paddingInlineEnd:0,[`&${n}-round`]:{width:"auto"},[s]:{fontSize:e.buttonIconOnlyFontSize}},[`&${n}-loading`]:{opacity:e.opacityLoading,cursor:"default"},[`${n}-loading-icon`]:{transition:`width ${e.motionDurationSlow} ${e.motionEaseInOut}, opacity ${e.motionDurationSlow} ${e.motionEaseInOut}`}}},{[`${n}${n}-circle${t}`]:AN(e)},{[`${n}${n}-round${t}`]:DN(e)}]},HN=e=>{const t=$t(e,{fontSize:e.contentFontSize,lineHeight:e.contentLineHeight});return Jh(t,e.componentCls)},WN=e=>{const t=$t(e,{controlHeight:e.controlHeightSM,fontSize:e.contentFontSizeSM,lineHeight:e.contentLineHeightSM,padding:e.paddingXS,buttonPaddingHorizontal:e.paddingInlineSM,buttonPaddingVertical:e.paddingBlockSM,borderRadius:e.borderRadiusSM,buttonIconOnlyFontSize:e.onlyIconSizeSM});return Jh(t,`${e.componentCls}-sm`)},VN=e=>{const t=$t(e,{controlHeight:e.controlHeightLG,fontSize:e.contentFontSizeLG,lineHeight:e.contentLineHeightLG,buttonPaddingHorizontal:e.paddingInlineLG,buttonPaddingVertical:e.paddingBlockLG,borderRadius:e.borderRadiusLG,buttonIconOnlyFontSize:e.onlyIconSizeLG});return Jh(t,`${e.componentCls}-lg`)},UN=e=>{const{componentCls:t}=e;return{[t]:{[`&${t}-block`]:{width:"100%"}}}},YN=vn("Button",e=>{const t=xw(e);return[_N(t),HN(t),WN(t),VN(t),UN(t),jN(t),NN(t)]},ww,{unitless:{fontWeight:!0,contentLineHeight:!0,contentLineHeightSM:!0,contentLineHeightLG:!0}});function GN(e,t,n){const{focusElCls:r,focus:o,borderElCls:i}=n,a=i?"> *":"",l=["hover",o?"focus":null,"active"].filter(Boolean).map(s=>`&:${s} ${a}`).join(",");return{[`&-item:not(${t}-last-item)`]:{marginInlineEnd:e.calc(e.lineWidth).mul(-1).equal()},"&-item":Object.assign(Object.assign({[l]:{zIndex:2}},r?{[`&${r}`]:{zIndex:2}}:{}),{[`&[disabled] ${a}`]:{zIndex:0}})}}function KN(e,t,n){const{borderElCls:r}=n,o=r?`> ${r}`:"";return{[`&-item:not(${t}-first-item):not(${t}-last-item) ${o}`]:{borderRadius:0},[`&-item:not(${t}-last-item)${t}-first-item`]:{[`& ${o}, &${e}-sm ${o}, &${e}-lg ${o}`]:{borderStartEndRadius:0,borderEndEndRadius:0}},[`&-item:not(${t}-first-item)${t}-last-item`]:{[`& ${o}, &${e}-sm ${o}, &${e}-lg ${o}`]:{borderStartStartRadius:0,borderEndStartRadius:0}}}}function tf(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{focus:!0};const{componentCls:n}=e,r=`${n}-compact`;return{[r]:Object.assign(Object.assign({},GN(e,r,t)),KN(n,r,t))}}function qN(e,t){return{[`&-item:not(${t}-last-item)`]:{marginBottom:e.calc(e.lineWidth).mul(-1).equal()},"&-item":{"&:hover,&:focus,&:active":{zIndex:2},"&[disabled]":{zIndex:0}}}}function XN(e,t){return{[`&-item:not(${t}-first-item):not(${t}-last-item)`]:{borderRadius:0},[`&-item${t}-first-item:not(${t}-last-item)`]:{[`&, &${e}-sm, &${e}-lg`]:{borderEndEndRadius:0,borderEndStartRadius:0}},[`&-item${t}-last-item:not(${t}-first-item)`]:{[`&, &${e}-sm, &${e}-lg`]:{borderStartStartRadius:0,borderStartEndRadius:0}}}}function QN(e){const t=`${e.componentCls}-compact-vertical`;return{[t]:Object.assign(Object.assign({},qN(e,t)),XN(e.componentCls,t))}}const ZN=e=>{const{componentCls:t,calc:n}=e;return{[t]:{[`&-compact-item${t}-primary`]:{[`&:not([disabled]) + ${t}-compact-item${t}-primary:not([disabled])`]:{position:"relative","&:before":{position:"absolute",top:n(e.lineWidth).mul(-1).equal(),insetInlineStart:n(e.lineWidth).mul(-1).equal(),display:"inline-block",width:e.lineWidth,height:`calc(100% + ${X(e.lineWidth)} * 2)`,backgroundColor:e.colorPrimaryHover,content:'""'}}},"&-compact-vertical-item":{[`&${t}-primary`]:{[`&:not([disabled]) + ${t}-compact-vertical-item${t}-primary:not([disabled])`]:{position:"relative","&:before":{position:"absolute",top:n(e.lineWidth).mul(-1).equal(),insetInlineStart:n(e.lineWidth).mul(-1).equal(),display:"inline-block",width:`calc(100% + ${X(e.lineWidth)} * 2)`,height:e.lineWidth,backgroundColor:e.colorPrimaryHover,content:'""'}}}}}}},JN=Kh(["Button","compact"],e=>{const t=xw(e);return[tf(t),QN(t),ZN(t)]},ww);var e6=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var n,r;const{loading:o=!1,prefixCls:i,type:a="default",danger:l,shape:s="default",size:c,styles:u,disabled:d,className:v,rootClassName:h,children:g,icon:p,ghost:b=!1,block:m=!1,htmlType:y="button",classNames:S,style:x={}}=e,$=e6(e,["loading","prefixCls","type","danger","shape","size","styles","disabled","className","rootClassName","children","icon","ghost","block","htmlType","classNames","style"]),{getPrefixCls:E,autoInsertSpaceInButton:w,direction:R,button:P}=f.exports.useContext(ot),N=E("btn",i),[I,z,F]=YN(N),T=f.exports.useContext(rl),D=d!=null?d:T,_=f.exports.useContext(Sw),O=f.exports.useMemo(()=>t6(o),[o]),[M,L]=f.exports.useState(O.loading),[A,B]=f.exports.useState(!1),j=xr(t,f.exports.createRef()),H=f.exports.Children.count(g)===1&&!p&&!cv(a);f.exports.useEffect(()=>{let le=null;O.delay>0?le=setTimeout(()=>{le=null,L(!0)},O.delay):L(O.loading);function Ce(){le&&(clearTimeout(le),le=null)}return Ce},[O]),f.exports.useEffect(()=>{if(!j||!j.current||w===!1)return;const le=j.current.textContent;H&&ag(le)?A||B(!0):A&&B(!1)},[j]);const W=le=>{const{onClick:Ce}=e;if(M||D){le.preventDefault();return}Ce==null||Ce(le)},Y=w!==!1,{compactSize:K,compactItemClassnames:q}=ef(N,R),ee={large:"lg",small:"sm",middle:void 0},Z=So(le=>{var Ce,ce;return(ce=(Ce=c!=null?c:K)!==null&&Ce!==void 0?Ce:_)!==null&&ce!==void 0?ce:le}),Q=Z&&ee[Z]||"",ne=M?"loading":p,ae=lr($,["navigate"]),J=te(N,z,F,{[`${N}-${s}`]:s!=="default"&&s,[`${N}-${a}`]:a,[`${N}-${Q}`]:Q,[`${N}-icon-only`]:!g&&g!==0&&!!ne,[`${N}-background-ghost`]:b&&!cv(a),[`${N}-loading`]:M,[`${N}-two-chinese-chars`]:A&&Y&&!M,[`${N}-block`]:m,[`${N}-dangerous`]:!!l,[`${N}-rtl`]:R==="rtl"},q,v,h,P==null?void 0:P.className),re=Object.assign(Object.assign({},P==null?void 0:P.style),x),fe=te(S==null?void 0:S.icon,(n=P==null?void 0:P.classNames)===null||n===void 0?void 0:n.icon),ve=Object.assign(Object.assign({},(u==null?void 0:u.icon)||{}),((r=P==null?void 0:P.styles)===null||r===void 0?void 0:r.icon)||{}),pe=p&&!M?C(Cw,{prefixCls:N,className:fe,style:ve,children:p}):C(PN,{existIcon:!!p,prefixCls:N,loading:!!M}),oe=g||g===0?ON(g,H&&Y):null;if(ae.href!==void 0)return I(ie("a",{...Object.assign({},ae,{className:te(J,{[`${N}-disabled`]:D}),href:D?void 0:ae.href,style:re,onClick:W,ref:j,tabIndex:D?-1:0}),children:[pe,oe]}));let se=ie("button",{...Object.assign({},$,{type:y,className:J,style:re,onClick:W,disabled:D,ref:j}),children:[pe,oe,!!q&&C(JN,{prefixCls:N},"compact")]});return cv(a)||(se=C(Qh,{component:"Button",disabled:!!M,children:se})),I(se)},em=f.exports.forwardRef(n6);em.Group=EN;em.__ANT_BUTTON=!0;const Xu=em;var Mw=f.exports.createContext(null),Vy=[];function r6(e,t){var n=f.exports.useState(function(){if(!Rn())return null;var g=document.createElement("div");return g}),r=G(n,1),o=r[0],i=f.exports.useRef(!1),a=f.exports.useContext(Mw),l=f.exports.useState(Vy),s=G(l,2),c=s[0],u=s[1],d=a||(i.current?void 0:function(g){u(function(p){var b=[g].concat(Oe(p));return b})});function v(){o.parentElement||document.body.appendChild(o),i.current=!0}function h(){var g;(g=o.parentElement)===null||g===void 0||g.removeChild(o),i.current=!1}return Nt(function(){return e?a?a(v):v():h(),h},[e]),Nt(function(){c.length&&(c.forEach(function(g){return g()}),u(Vy))},[c]),[o,d]}var fv;function o6(e){if(typeof document>"u")return 0;if(e||fv===void 0){var t=document.createElement("div");t.style.width="100%",t.style.height="200px";var n=document.createElement("div"),r=n.style;r.position="absolute",r.top="0",r.left="0",r.pointerEvents="none",r.visibility="hidden",r.width="200px",r.height="150px",r.overflow="hidden",n.appendChild(t),document.body.appendChild(n);var o=t.offsetWidth;n.style.overflow="scroll";var i=t.offsetWidth;o===i&&(i=n.clientWidth),document.body.removeChild(n),fv=o-i}return fv}function Uy(e){var t=e.match(/^(.*)px$/),n=Number(t==null?void 0:t[1]);return Number.isNaN(n)?o6():n}function i6(e){if(typeof document>"u"||!e||!(e instanceof Element))return{width:0,height:0};var t=getComputedStyle(e,"::-webkit-scrollbar"),n=t.width,r=t.height;return{width:Uy(n),height:Uy(r)}}function a6(){return document.body.scrollHeight>(window.innerHeight||document.documentElement.clientHeight)&&window.innerWidth>document.body.offsetWidth}var l6="rc-util-locker-".concat(Date.now()),Yy=0;function s6(e){var t=!!e,n=f.exports.useState(function(){return Yy+=1,"".concat(l6,"_").concat(Yy)}),r=G(n,1),o=r[0];Nt(function(){if(t){var i=i6(document.body).width,a=a6();Xo(`
+html body {
+ overflow-y: hidden;
+ `.concat(a?"width: calc(100% - ".concat(i,"px);"):"",`
+}`),o)}else Ss(o);return function(){Ss(o)}},[t,o])}var Gy=!1;function c6(e){return typeof e=="boolean"&&(Gy=e),Gy}var Ky=function(t){return t===!1?!1:!Rn()||!t?null:typeof t=="string"?document.querySelector(t):typeof t=="function"?t():t},nf=f.exports.forwardRef(function(e,t){var n=e.open,r=e.autoLock,o=e.getContainer;e.debug;var i=e.autoDestroy,a=i===void 0?!0:i,l=e.children,s=f.exports.useState(n),c=G(s,2),u=c[0],d=c[1],v=u||n;f.exports.useEffect(function(){(a||n)&&d(n)},[n,a]);var h=f.exports.useState(function(){return Ky(o)}),g=G(h,2),p=g[0],b=g[1];f.exports.useEffect(function(){var I=Ky(o);b(I!=null?I:null)});var m=r6(v&&!p),y=G(m,2),S=y[0],x=y[1],$=p!=null?p:S;s6(r&&n&&Rn()&&($===S||$===document.body));var E=null;if(l&&ki(l)&&t){var w=l;E=w.ref}var R=Fi(E,t);if(!v||!Rn()||p===void 0)return null;var P=$===!1||c6(),N=l;return t&&(N=f.exports.cloneElement(l,{ref:R})),C(Mw.Provider,{value:x,children:P?N:Gn.exports.createPortal(N,$)})}),Ow=f.exports.createContext({});function u6(){var e=U({},As);return e.useId}var qy=0,Xy=u6();const Rw=Xy?function(t){var n=Xy();return t||n}:function(t){var n=f.exports.useState("ssr-id"),r=G(n,2),o=r[0],i=r[1];return f.exports.useEffect(function(){var a=qy;qy+=1,i("rc_unique_".concat(a))},[]),t||o};function Qy(e,t,n){var r=t;return!r&&n&&(r="".concat(e,"-").concat(n)),r}function Zy(e,t){var n=e["page".concat(t?"Y":"X","Offset")],r="scroll".concat(t?"Top":"Left");if(typeof n!="number"){var o=e.document;n=o.documentElement[r],typeof n!="number"&&(n=o.body[r])}return n}function d6(e){var t=e.getBoundingClientRect(),n={left:t.left,top:t.top},r=e.ownerDocument,o=r.defaultView||r.parentWindow;return n.left+=Zy(o),n.top+=Zy(o,!0),n}const f6=f.exports.memo(function(e){var t=e.children;return t},function(e,t){var n=t.shouldUpdate;return!n});var Jy={width:0,height:0,overflow:"hidden",outline:"none"},v6=lt.forwardRef(function(e,t){var n=e.prefixCls,r=e.className,o=e.style,i=e.title,a=e.ariaId,l=e.footer,s=e.closable,c=e.closeIcon,u=e.onClose,d=e.children,v=e.bodyStyle,h=e.bodyProps,g=e.modalRender,p=e.onMouseDown,b=e.onMouseUp,m=e.holderRef,y=e.visible,S=e.forceRender,x=e.width,$=e.height,E=e.classNames,w=e.styles,R=lt.useContext(Ow),P=R.panel,N=Fi(m,P),I=f.exports.useRef(),z=f.exports.useRef();lt.useImperativeHandle(t,function(){return{focus:function(){var L;(L=I.current)===null||L===void 0||L.focus()},changeActive:function(L){var A=document,B=A.activeElement;L&&B===z.current?I.current.focus():!L&&B===I.current&&z.current.focus()}}});var F={};x!==void 0&&(F.width=x),$!==void 0&&(F.height=$);var T;l&&(T=C("div",{className:te("".concat(n,"-footer"),E==null?void 0:E.footer),style:U({},w==null?void 0:w.footer),children:l}));var D;i&&(D=C("div",{className:te("".concat(n,"-header"),E==null?void 0:E.header),style:U({},w==null?void 0:w.header),children:C("div",{className:"".concat(n,"-title"),id:a,children:i})}));var _;s&&(_=C("button",{type:"button",onClick:u,"aria-label":"Close",className:"".concat(n,"-close"),children:c||C("span",{className:"".concat(n,"-close-x")})}));var O=ie("div",{className:te("".concat(n,"-content"),E==null?void 0:E.content),style:w==null?void 0:w.content,children:[_,D,C("div",{className:te("".concat(n,"-body"),E==null?void 0:E.body),style:U(U({},v),w==null?void 0:w.body),...h,children:d}),T]});return ie("div",{role:"dialog","aria-labelledby":i?a:null,"aria-modal":"true",ref:N,style:U(U({},o),F),className:te(n,r),onMouseDown:p,onMouseUp:b,children:[C("div",{tabIndex:0,ref:I,style:Jy,"aria-hidden":"true"}),C(f6,{shouldUpdate:y||S,children:g?g(O):O}),C("div",{tabIndex:0,ref:z,style:Jy,"aria-hidden":"true"})]},"dialog-element")}),Iw=f.exports.forwardRef(function(e,t){var n=e.prefixCls,r=e.title,o=e.style,i=e.className,a=e.visible,l=e.forceRender,s=e.destroyOnClose,c=e.motionName,u=e.ariaId,d=e.onVisibleChanged,v=e.mousePosition,h=f.exports.useRef(),g=f.exports.useState(),p=G(g,2),b=p[0],m=p[1],y={};b&&(y.transformOrigin=b);function S(){var x=d6(h.current);m(v?"".concat(v.x-x.left,"px ").concat(v.y-x.top,"px"):"")}return C(to,{visible:a,onVisibleChanged:d,onAppearPrepare:S,onEnterPrepare:S,forceRender:l,motionName:c,removeOnLeave:s,ref:h,children:function(x,$){var E=x.className,w=x.style;return C(v6,{...e,ref:t,title:r,ariaId:u,prefixCls:n,holderRef:$,style:U(U(U({},w),o),y),className:te(i,E)})}})});Iw.displayName="Content";function p6(e){var t=e.prefixCls,n=e.style,r=e.visible,o=e.maskProps,i=e.motionName,a=e.className;return C(to,{visible:r,motionName:i,leavedClassName:"".concat(t,"-mask-hidden"),children:function(l,s){var c=l.className,u=l.style;return C("div",{ref:s,style:U(U({},u),n),className:te("".concat(t,"-mask"),c,a),...o})}},"mask")}function g6(e){var t=e.prefixCls,n=t===void 0?"rc-dialog":t,r=e.zIndex,o=e.visible,i=o===void 0?!1:o,a=e.keyboard,l=a===void 0?!0:a,s=e.focusTriggerAfterClose,c=s===void 0?!0:s,u=e.wrapStyle,d=e.wrapClassName,v=e.wrapProps,h=e.onClose,g=e.afterOpenChange,p=e.afterClose,b=e.transitionName,m=e.animation,y=e.closable,S=y===void 0?!0:y,x=e.mask,$=x===void 0?!0:x,E=e.maskTransitionName,w=e.maskAnimation,R=e.maskClosable,P=R===void 0?!0:R,N=e.maskStyle,I=e.maskProps,z=e.rootClassName,F=e.classNames,T=e.styles,D=f.exports.useRef(),_=f.exports.useRef(),O=f.exports.useRef(),M=f.exports.useState(i),L=G(M,2),A=L[0],B=L[1],k=Rw();function j(){Np(_.current,document.activeElement)||(D.current=document.activeElement)}function H(){if(!Np(_.current,document.activeElement)){var ae;(ae=O.current)===null||ae===void 0||ae.focus()}}function W(ae){if(ae)H();else{if(B(!1),$&&D.current&&c){try{D.current.focus({preventScroll:!0})}catch{}D.current=null}A&&(p==null||p())}g==null||g(ae)}function Y(ae){h==null||h(ae)}var K=f.exports.useRef(!1),q=f.exports.useRef(),ee=function(){clearTimeout(q.current),K.current=!0},Z=function(){q.current=setTimeout(function(){K.current=!1})},Q=null;P&&(Q=function(J){K.current?K.current=!1:_.current===J.target&&Y(J)});function ne(ae){if(l&&ae.keyCode===ue.ESC){ae.stopPropagation(),Y(ae);return}i&&ae.keyCode===ue.TAB&&O.current.changeActive(!ae.shiftKey)}return f.exports.useEffect(function(){i&&(B(!0),j())},[i]),f.exports.useEffect(function(){return function(){clearTimeout(q.current)}},[]),ie("div",{className:te("".concat(n,"-root"),z),...Ka(e,{data:!0}),children:[C(p6,{prefixCls:n,visible:$&&i,motionName:Qy(n,E,w),style:U(U({zIndex:r},N),T==null?void 0:T.mask),maskProps:I,className:F==null?void 0:F.mask}),C("div",{tabIndex:-1,onKeyDown:ne,className:te("".concat(n,"-wrap"),d,F==null?void 0:F.wrapper),ref:_,onClick:Q,style:U(U(U({zIndex:r},u),T==null?void 0:T.wrapper),{},{display:A?null:"none"}),...v,children:C(Iw,{...e,onMouseDown:ee,onMouseUp:Z,ref:O,closable:S,ariaId:k,prefixCls:n,visible:i&&A,onClose:Y,onVisibleChanged:W,motionName:Qy(n,b,m)})})]})}var Pw=function(t){var n=t.visible,r=t.getContainer,o=t.forceRender,i=t.destroyOnClose,a=i===void 0?!1:i,l=t.afterClose,s=t.panelRef,c=f.exports.useState(n),u=G(c,2),d=u[0],v=u[1],h=f.exports.useMemo(function(){return{panel:s}},[s]);return f.exports.useEffect(function(){n&&v(!0)},[n]),!o&&a&&!d?null:C(Ow.Provider,{value:h,children:C(nf,{open:n||o||d,autoDestroy:!1,getContainer:r,autoLock:n||d,children:C(g6,{...t,destroyOnClose:a,afterClose:function(){l==null||l(),v(!1)}})})})};Pw.displayName="Dialog";function h6(e,t,n){return typeof e=="boolean"?e:t===void 0?!!n:t!==!1&&t!==null}function m6(e,t,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:C(eo,{}),o=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!1;if(!h6(e,t,o))return[!1,null];const a=typeof t=="boolean"||t===void 0||t===null?r:t;return[!0,n?n(a):a]}var Si="RC_FORM_INTERNAL_HOOKS",Pt=function(){Mn(!1,"Can not find FormContext. Please make sure you wrap Field under Form.")},qa=f.exports.createContext({getFieldValue:Pt,getFieldsValue:Pt,getFieldError:Pt,getFieldWarning:Pt,getFieldsError:Pt,isFieldsTouched:Pt,isFieldTouched:Pt,isFieldValidating:Pt,isFieldsValidating:Pt,resetFields:Pt,setFields:Pt,setFieldValue:Pt,setFieldsValue:Pt,validateFields:Pt,submit:Pt,getInternalHooks:function(){return Pt(),{dispatch:Pt,initEntityValue:Pt,registerField:Pt,useSubscribe:Pt,setInitialValues:Pt,destroyForm:Pt,setCallbacks:Pt,registerWatch:Pt,getFields:Pt,setValidateMessages:Pt,setPreserve:Pt,getInitialValue:Pt}}}),Qu=f.exports.createContext(null);function lg(e){return e==null?[]:Array.isArray(e)?e:[e]}function y6(e){return e&&!!e._init}function Ci(){return Ci=Object.assign?Object.assign.bind():function(e){for(var t=1;t"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function iu(e,t,n){return S6()?iu=Reflect.construct.bind():iu=function(o,i,a){var l=[null];l.push.apply(l,i);var s=Function.bind.apply(o,l),c=new s;return a&&Os(c,a.prototype),c},iu.apply(null,arguments)}function C6(e){return Function.toString.call(e).indexOf("[native code]")!==-1}function cg(e){var t=typeof Map=="function"?new Map:void 0;return cg=function(r){if(r===null||!C6(r))return r;if(typeof r!="function")throw new TypeError("Super expression must either be null or a function");if(typeof t<"u"){if(t.has(r))return t.get(r);t.set(r,o)}function o(){return iu(r,arguments,sg(this).constructor)}return o.prototype=Object.create(r.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),Os(o,r)},cg(e)}var x6=/%[sdj%]/g,w6=function(){};typeof process<"u"&&process.env;function ug(e){if(!e||!e.length)return null;var t={};return e.forEach(function(n){var r=n.field;t[r]=t[r]||[],t[r].push(n)}),t}function nr(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r=i)return l;switch(l){case"%s":return String(n[o++]);case"%d":return Number(n[o++]);case"%j":try{return JSON.stringify(n[o++])}catch{return"[Circular]"}break;default:return l}});return a}return e}function $6(e){return e==="string"||e==="url"||e==="hex"||e==="email"||e==="date"||e==="pattern"}function ln(e,t){return!!(e==null||t==="array"&&Array.isArray(e)&&!e.length||$6(t)&&typeof e=="string"&&!e)}function E6(e,t,n){var r=[],o=0,i=e.length;function a(l){r.push.apply(r,l||[]),o++,o===i&&n(r)}e.forEach(function(l){t(l,a)})}function eb(e,t,n){var r=0,o=e.length;function i(a){if(a&&a.length){n(a);return}var l=r;r=r+1,l()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+\.)+[a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}))$/,hex:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i},Nl={integer:function(t){return Nl.number(t)&&parseInt(t,10)===t},float:function(t){return Nl.number(t)&&!Nl.integer(t)},array:function(t){return Array.isArray(t)},regexp:function(t){if(t instanceof RegExp)return!0;try{return!!new RegExp(t)}catch{return!1}},date:function(t){return typeof t.getTime=="function"&&typeof t.getMonth=="function"&&typeof t.getYear=="function"&&!isNaN(t.getTime())},number:function(t){return isNaN(t)?!1:typeof t=="number"},object:function(t){return typeof t=="object"&&!Nl.array(t)},method:function(t){return typeof t=="function"},email:function(t){return typeof t=="string"&&t.length<=320&&!!t.match(ob.email)},url:function(t){return typeof t=="string"&&t.length<=2048&&!!t.match(T6())},hex:function(t){return typeof t=="string"&&!!t.match(ob.hex)}},N6=function(t,n,r,o,i){if(t.required&&n===void 0){Tw(t,n,r,o,i);return}var a=["integer","float","array","regexp","object","method","email","number","date","url","hex"],l=t.type;a.indexOf(l)>-1?Nl[l](n)||o.push(nr(i.messages.types[l],t.fullField,t.type)):l&&typeof n!==t.type&&o.push(nr(i.messages.types[l],t.fullField,t.type))},_6=function(t,n,r,o,i){var a=typeof t.len=="number",l=typeof t.min=="number",s=typeof t.max=="number",c=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,u=n,d=null,v=typeof n=="number",h=typeof n=="string",g=Array.isArray(n);if(v?d="number":h?d="string":g&&(d="array"),!d)return!1;g&&(u=n.length),h&&(u=n.replace(c,"_").length),a?u!==t.len&&o.push(nr(i.messages[d].len,t.fullField,t.len)):l&&!s&&ut.max?o.push(nr(i.messages[d].max,t.fullField,t.max)):l&&s&&(ut.max)&&o.push(nr(i.messages[d].range,t.fullField,t.min,t.max))},Gi="enum",A6=function(t,n,r,o,i){t[Gi]=Array.isArray(t[Gi])?t[Gi]:[],t[Gi].indexOf(n)===-1&&o.push(nr(i.messages[Gi],t.fullField,t[Gi].join(", ")))},D6=function(t,n,r,o,i){if(t.pattern){if(t.pattern instanceof RegExp)t.pattern.lastIndex=0,t.pattern.test(n)||o.push(nr(i.messages.pattern.mismatch,t.fullField,n,t.pattern));else if(typeof t.pattern=="string"){var a=new RegExp(t.pattern);a.test(n)||o.push(nr(i.messages.pattern.mismatch,t.fullField,n,t.pattern))}}},pt={required:Tw,whitespace:P6,type:N6,range:_6,enum:A6,pattern:D6},L6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n,"string")&&!t.required)return r();pt.required(t,n,o,a,i,"string"),ln(n,"string")||(pt.type(t,n,o,a,i),pt.range(t,n,o,a,i),pt.pattern(t,n,o,a,i),t.whitespace===!0&&pt.whitespace(t,n,o,a,i))}r(a)},z6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),n!==void 0&&pt.type(t,n,o,a,i)}r(a)},F6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(n===""&&(n=void 0),ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),n!==void 0&&(pt.type(t,n,o,a,i),pt.range(t,n,o,a,i))}r(a)},k6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),n!==void 0&&pt.type(t,n,o,a,i)}r(a)},B6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),ln(n)||pt.type(t,n,o,a,i)}r(a)},j6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),n!==void 0&&(pt.type(t,n,o,a,i),pt.range(t,n,o,a,i))}r(a)},H6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),n!==void 0&&(pt.type(t,n,o,a,i),pt.range(t,n,o,a,i))}r(a)},W6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(n==null&&!t.required)return r();pt.required(t,n,o,a,i,"array"),n!=null&&(pt.type(t,n,o,a,i),pt.range(t,n,o,a,i))}r(a)},V6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),n!==void 0&&pt.type(t,n,o,a,i)}r(a)},U6="enum",Y6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i),n!==void 0&&pt[U6](t,n,o,a,i)}r(a)},G6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n,"string")&&!t.required)return r();pt.required(t,n,o,a,i),ln(n,"string")||pt.pattern(t,n,o,a,i)}r(a)},K6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n,"date")&&!t.required)return r();if(pt.required(t,n,o,a,i),!ln(n,"date")){var s;n instanceof Date?s=n:s=new Date(n),pt.type(t,s,o,a,i),s&&pt.range(t,s.getTime(),o,a,i)}}r(a)},q6=function(t,n,r,o,i){var a=[],l=Array.isArray(n)?"array":typeof n;pt.required(t,n,o,a,i,l),r(a)},vv=function(t,n,r,o,i){var a=t.type,l=[],s=t.required||!t.required&&o.hasOwnProperty(t.field);if(s){if(ln(n,a)&&!t.required)return r();pt.required(t,n,o,l,i,a),ln(n,a)||pt.type(t,n,o,l,i)}r(l)},X6=function(t,n,r,o,i){var a=[],l=t.required||!t.required&&o.hasOwnProperty(t.field);if(l){if(ln(n)&&!t.required)return r();pt.required(t,n,o,a,i)}r(a)},Zl={string:L6,method:z6,number:F6,boolean:k6,regexp:B6,integer:j6,float:H6,array:W6,object:V6,enum:Y6,pattern:G6,date:K6,url:vv,hex:vv,email:vv,required:q6,any:X6};function dg(){return{default:"Validation error on field %s",required:"%s is required",enum:"%s must be one of %s",whitespace:"%s cannot be empty",date:{format:"%s date %s is invalid for format %s",parse:"%s date could not be parsed, %s is invalid ",invalid:"%s date %s is invalid"},types:{string:"%s is not a %s",method:"%s is not a %s (function)",array:"%s is not an %s",object:"%s is not an %s",number:"%s is not a %s",date:"%s is not a %s",boolean:"%s is not a %s",integer:"%s is not an %s",float:"%s is not a %s",regexp:"%s is not a valid %s",email:"%s is not a valid %s",url:"%s is not a valid %s",hex:"%s is not a valid %s"},string:{len:"%s must be exactly %s characters",min:"%s must be at least %s characters",max:"%s cannot be longer than %s characters",range:"%s must be between %s and %s characters"},number:{len:"%s must equal %s",min:"%s cannot be less than %s",max:"%s cannot be greater than %s",range:"%s must be between %s and %s"},array:{len:"%s must be exactly %s in length",min:"%s cannot be less than %s in length",max:"%s cannot be greater than %s in length",range:"%s must be between %s and %s in length"},pattern:{mismatch:"%s value %s does not match pattern %s"},clone:function(){var t=JSON.parse(JSON.stringify(this));return t.clone=this.clone,t}}}var fg=dg(),Gs=function(){function e(n){this.rules=null,this._messages=fg,this.define(n)}var t=e.prototype;return t.define=function(r){var o=this;if(!r)throw new Error("Cannot configure a schema with no rules");if(typeof r!="object"||Array.isArray(r))throw new Error("Rules must be an object");this.rules={},Object.keys(r).forEach(function(i){var a=r[i];o.rules[i]=Array.isArray(a)?a:[a]})},t.messages=function(r){return r&&(this._messages=rb(dg(),r)),this._messages},t.validate=function(r,o,i){var a=this;o===void 0&&(o={}),i===void 0&&(i=function(){});var l=r,s=o,c=i;if(typeof s=="function"&&(c=s,s={}),!this.rules||Object.keys(this.rules).length===0)return c&&c(null,l),Promise.resolve(l);function u(p){var b=[],m={};function y(x){if(Array.isArray(x)){var $;b=($=b).concat.apply($,x)}else b.push(x)}for(var S=0;S2&&arguments[2]!==void 0?arguments[2]:!1;return e&&e.some(function(r){return _w(t,r,n)})}function _w(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!1;return!e||!t||!n&&e.length!==t.length?!1:t.every(function(r,o){return e[o]===r})}function t_(e,t){if(e===t)return!0;if(!e&&t||e&&!t||!e||!t||Qe(e)!=="object"||Qe(t)!=="object")return!1;var n=Object.keys(e),r=Object.keys(t),o=new Set([].concat(n,r));return Oe(o).every(function(i){var a=e[i],l=t[i];return typeof a=="function"&&typeof l=="function"?!0:a===l})}function n_(e){var t=arguments.length<=1?void 0:arguments[1];return t&&t.target&&Qe(t.target)==="object"&&e in t.target?t.target[e]:t}function sb(e,t,n){var r=e.length;if(t<0||t>=r||n<0||n>=r)return e;var o=e[t],i=t-n;return i>0?[].concat(Oe(e.slice(0,n)),[o],Oe(e.slice(n,t)),Oe(e.slice(t+1,r))):i<0?[].concat(Oe(e.slice(0,t)),Oe(e.slice(t+1,n+1)),[o],Oe(e.slice(n+1,r))):e}var r_=["name"],cr=[];function cb(e,t,n,r,o,i){return typeof e=="function"?e(t,n,"source"in i?{source:i.source}:{}):r!==o}var tm=function(e){Bi(n,e);var t=Ws(n);function n(r){var o;if(zn(this,n),o=t.call(this,r),V(xt(o),"state",{resetCount:0}),V(xt(o),"cancelRegisterFunc",null),V(xt(o),"mounted",!1),V(xt(o),"touched",!1),V(xt(o),"dirty",!1),V(xt(o),"validatePromise",void 0),V(xt(o),"prevValidating",void 0),V(xt(o),"errors",cr),V(xt(o),"warnings",cr),V(xt(o),"cancelRegister",function(){var s=o.props,c=s.preserve,u=s.isListField,d=s.name;o.cancelRegisterFunc&&o.cancelRegisterFunc(u,c,qt(d)),o.cancelRegisterFunc=null}),V(xt(o),"getNamePath",function(){var s=o.props,c=s.name,u=s.fieldContext,d=u.prefixName,v=d===void 0?[]:d;return c!==void 0?[].concat(Oe(v),Oe(c)):[]}),V(xt(o),"getRules",function(){var s=o.props,c=s.rules,u=c===void 0?[]:c,d=s.fieldContext;return u.map(function(v){return typeof v=="function"?v(d):v})}),V(xt(o),"refresh",function(){!o.mounted||o.setState(function(s){var c=s.resetCount;return{resetCount:c+1}})}),V(xt(o),"metaCache",null),V(xt(o),"triggerMetaEvent",function(s){var c=o.props.onMetaChange;if(c){var u=U(U({},o.getMeta()),{},{destroy:s});Vs(o.metaCache,u)||c(u),o.metaCache=u}else o.metaCache=null}),V(xt(o),"onStoreChange",function(s,c,u){var d=o.props,v=d.shouldUpdate,h=d.dependencies,g=h===void 0?[]:h,p=d.onReset,b=u.store,m=o.getNamePath(),y=o.getValue(s),S=o.getValue(b),x=c&&Aa(c,m);switch(u.type==="valueUpdate"&&u.source==="external"&&y!==S&&(o.touched=!0,o.dirty=!0,o.validatePromise=null,o.errors=cr,o.warnings=cr,o.triggerMetaEvent()),u.type){case"reset":if(!c||x){o.touched=!1,o.dirty=!1,o.validatePromise=void 0,o.errors=cr,o.warnings=cr,o.triggerMetaEvent(),p==null||p(),o.refresh();return}break;case"remove":{if(v){o.reRender();return}break}case"setField":{var $=u.data;if(x){"touched"in $&&(o.touched=$.touched),"validating"in $&&!("originRCField"in $)&&(o.validatePromise=$.validating?Promise.resolve([]):null),"errors"in $&&(o.errors=$.errors||cr),"warnings"in $&&(o.warnings=$.warnings||cr),o.dirty=!0,o.triggerMetaEvent(),o.reRender();return}else if("value"in $&&Aa(c,m,!0)){o.reRender();return}if(v&&!m.length&&cb(v,s,b,y,S,u)){o.reRender();return}break}case"dependenciesUpdate":{var E=g.map(qt);if(E.some(function(w){return Aa(u.relatedFields,w)})){o.reRender();return}break}default:if(x||(!g.length||m.length||v)&&cb(v,s,b,y,S,u)){o.reRender();return}break}v===!0&&o.reRender()}),V(xt(o),"validateRules",function(s){var c=o.getNamePath(),u=o.getValue(),d=s||{},v=d.triggerName,h=d.validateOnly,g=h===void 0?!1:h,p=Promise.resolve().then(ji(An().mark(function b(){var m,y,S,x,$,E,w;return An().wrap(function(P){for(;;)switch(P.prev=P.next){case 0:if(o.mounted){P.next=2;break}return P.abrupt("return",[]);case 2:if(m=o.props,y=m.validateFirst,S=y===void 0?!1:y,x=m.messageVariables,$=m.validateDebounce,E=o.getRules(),v&&(E=E.filter(function(N){return N}).filter(function(N){var I=N.validateTrigger;if(!I)return!0;var z=lg(I);return z.includes(v)})),!($&&v)){P.next=10;break}return P.next=8,new Promise(function(N){setTimeout(N,$)});case 8:if(o.validatePromise===p){P.next=10;break}return P.abrupt("return",[]);case 10:return w=Z6(c,u,E,s,S,x),w.catch(function(N){return N}).then(function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:cr;if(o.validatePromise===p){var I;o.validatePromise=null;var z=[],F=[];(I=N.forEach)===null||I===void 0||I.call(N,function(T){var D=T.rule.warningOnly,_=T.errors,O=_===void 0?cr:_;D?F.push.apply(F,Oe(O)):z.push.apply(z,Oe(O))}),o.errors=z,o.warnings=F,o.triggerMetaEvent(),o.reRender()}}),P.abrupt("return",w);case 13:case"end":return P.stop()}},b)})));return g||(o.validatePromise=p,o.dirty=!0,o.errors=cr,o.warnings=cr,o.triggerMetaEvent(),o.reRender()),p}),V(xt(o),"isFieldValidating",function(){return!!o.validatePromise}),V(xt(o),"isFieldTouched",function(){return o.touched}),V(xt(o),"isFieldDirty",function(){if(o.dirty||o.props.initialValue!==void 0)return!0;var s=o.props.fieldContext,c=s.getInternalHooks(Si),u=c.getInitialValue;return u(o.getNamePath())!==void 0}),V(xt(o),"getErrors",function(){return o.errors}),V(xt(o),"getWarnings",function(){return o.warnings}),V(xt(o),"isListField",function(){return o.props.isListField}),V(xt(o),"isList",function(){return o.props.isList}),V(xt(o),"isPreserve",function(){return o.props.preserve}),V(xt(o),"getMeta",function(){o.prevValidating=o.isFieldValidating();var s={touched:o.isFieldTouched(),validating:o.prevValidating,errors:o.errors,warnings:o.warnings,name:o.getNamePath(),validated:o.validatePromise===null};return s}),V(xt(o),"getOnlyChild",function(s){if(typeof s=="function"){var c=o.getMeta();return U(U({},o.getOnlyChild(s(o.getControlled(),c,o.props.fieldContext))),{},{isFunction:!0})}var u=Qo(s);return u.length!==1||!f.exports.isValidElement(u[0])?{child:u,isFunction:!1}:{child:u[0],isFunction:!1}}),V(xt(o),"getValue",function(s){var c=o.props.fieldContext.getFieldsValue,u=o.getNamePath();return qr(s||c(!0),u)}),V(xt(o),"getControlled",function(){var s=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},c=o.props,u=c.trigger,d=c.validateTrigger,v=c.getValueFromEvent,h=c.normalize,g=c.valuePropName,p=c.getValueProps,b=c.fieldContext,m=d!==void 0?d:b.validateTrigger,y=o.getNamePath(),S=b.getInternalHooks,x=b.getFieldsValue,$=S(Si),E=$.dispatch,w=o.getValue(),R=p||function(z){return V({},g,z)},P=s[u],N=U(U({},s),R(w));N[u]=function(){o.touched=!0,o.dirty=!0,o.triggerMetaEvent();for(var z,F=arguments.length,T=new Array(F),D=0;D=0&&N<=I.length?(u.keys=[].concat(Oe(u.keys.slice(0,N)),[u.id],Oe(u.keys.slice(N))),S([].concat(Oe(I.slice(0,N)),[P],Oe(I.slice(N))))):(u.keys=[].concat(Oe(u.keys),[u.id]),S([].concat(Oe(I),[P]))),u.id+=1},remove:function(P){var N=$(),I=new Set(Array.isArray(P)?P:[P]);I.size<=0||(u.keys=u.keys.filter(function(z,F){return!I.has(F)}),S(N.filter(function(z,F){return!I.has(F)})))},move:function(P,N){if(P!==N){var I=$();P<0||P>=I.length||N<0||N>=I.length||(u.keys=sb(u.keys,P,N),S(sb(I,P,N)))}}},w=y||[];return Array.isArray(w)||(w=[]),r(w.map(function(R,P){var N=u.keys[P];return N===void 0&&(u.keys[P]=u.id,N=u.keys[P],u.id+=1),{name:P,key:N,isListField:!0}}),E,b)}})})})}function i_(e){var t=!1,n=e.length,r=[];return e.length?new Promise(function(o,i){e.forEach(function(a,l){a.catch(function(s){return t=!0,s}).then(function(s){n-=1,r[l]=s,!(n>0)&&(t&&i(r),o(r))})})}):Promise.resolve([])}var Dw="__@field_split__";function pv(e){return e.map(function(t){return"".concat(Qe(t),":").concat(t)}).join(Dw)}var Ki=function(){function e(){zn(this,e),V(this,"kvs",new Map)}return Fn(e,[{key:"set",value:function(n,r){this.kvs.set(pv(n),r)}},{key:"get",value:function(n){return this.kvs.get(pv(n))}},{key:"update",value:function(n,r){var o=this.get(n),i=r(o);i?this.set(n,i):this.delete(n)}},{key:"delete",value:function(n){this.kvs.delete(pv(n))}},{key:"map",value:function(n){return Oe(this.kvs.entries()).map(function(r){var o=G(r,2),i=o[0],a=o[1],l=i.split(Dw);return n({key:l.map(function(s){var c=s.match(/^([^:]*):(.*)$/),u=G(c,3),d=u[1],v=u[2];return d==="number"?Number(v):v}),value:a})})}},{key:"toJSON",value:function(){var n={};return this.map(function(r){var o=r.key,i=r.value;return n[o.join(".")]=i,null}),n}}]),e}(),a_=["name"],l_=Fn(function e(t){var n=this;zn(this,e),V(this,"formHooked",!1),V(this,"forceRootUpdate",void 0),V(this,"subscribable",!0),V(this,"store",{}),V(this,"fieldEntities",[]),V(this,"initialValues",{}),V(this,"callbacks",{}),V(this,"validateMessages",null),V(this,"preserve",null),V(this,"lastValidatePromise",null),V(this,"getForm",function(){return{getFieldValue:n.getFieldValue,getFieldsValue:n.getFieldsValue,getFieldError:n.getFieldError,getFieldWarning:n.getFieldWarning,getFieldsError:n.getFieldsError,isFieldsTouched:n.isFieldsTouched,isFieldTouched:n.isFieldTouched,isFieldValidating:n.isFieldValidating,isFieldsValidating:n.isFieldsValidating,resetFields:n.resetFields,setFields:n.setFields,setFieldValue:n.setFieldValue,setFieldsValue:n.setFieldsValue,validateFields:n.validateFields,submit:n.submit,_init:!0,getInternalHooks:n.getInternalHooks}}),V(this,"getInternalHooks",function(r){return r===Si?(n.formHooked=!0,{dispatch:n.dispatch,initEntityValue:n.initEntityValue,registerField:n.registerField,useSubscribe:n.useSubscribe,setInitialValues:n.setInitialValues,destroyForm:n.destroyForm,setCallbacks:n.setCallbacks,setValidateMessages:n.setValidateMessages,getFields:n.getFields,setPreserve:n.setPreserve,getInitialValue:n.getInitialValue,registerWatch:n.registerWatch}):(Mn(!1,"`getInternalHooks` is internal usage. Should not call directly."),null)}),V(this,"useSubscribe",function(r){n.subscribable=r}),V(this,"prevWithoutPreserves",null),V(this,"setInitialValues",function(r,o){if(n.initialValues=r||{},o){var i,a=Ca(r,n.store);(i=n.prevWithoutPreserves)===null||i===void 0||i.map(function(l){var s=l.key;a=Tr(a,s,qr(r,s))}),n.prevWithoutPreserves=null,n.updateStore(a)}}),V(this,"destroyForm",function(){var r=new Ki;n.getFieldEntities(!0).forEach(function(o){n.isMergedPreserve(o.isPreserve())||r.set(o.getNamePath(),!0)}),n.prevWithoutPreserves=r}),V(this,"getInitialValue",function(r){var o=qr(n.initialValues,r);return r.length?Ca(o):o}),V(this,"setCallbacks",function(r){n.callbacks=r}),V(this,"setValidateMessages",function(r){n.validateMessages=r}),V(this,"setPreserve",function(r){n.preserve=r}),V(this,"watchList",[]),V(this,"registerWatch",function(r){return n.watchList.push(r),function(){n.watchList=n.watchList.filter(function(o){return o!==r})}}),V(this,"notifyWatch",function(){var r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[];if(n.watchList.length){var o=n.getFieldsValue(),i=n.getFieldsValue(!0);n.watchList.forEach(function(a){a(o,i,r)})}}),V(this,"timeoutId",null),V(this,"warningUnhooked",function(){}),V(this,"updateStore",function(r){n.store=r}),V(this,"getFieldEntities",function(){var r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1;return r?n.fieldEntities.filter(function(o){return o.getNamePath().length}):n.fieldEntities}),V(this,"getFieldsMap",function(){var r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1,o=new Ki;return n.getFieldEntities(r).forEach(function(i){var a=i.getNamePath();o.set(a,i)}),o}),V(this,"getFieldEntitiesForNamePathList",function(r){if(!r)return n.getFieldEntities(!0);var o=n.getFieldsMap(!0);return r.map(function(i){var a=qt(i);return o.get(a)||{INVALIDATE_NAME_PATH:qt(i)}})}),V(this,"getFieldsValue",function(r,o){n.warningUnhooked();var i,a,l;if(r===!0||Array.isArray(r)?(i=r,a=o):r&&Qe(r)==="object"&&(l=r.strict,a=r.filter),i===!0&&!a)return n.store;var s=n.getFieldEntitiesForNamePathList(Array.isArray(i)?i:null),c=[];return s.forEach(function(u){var d,v,h="INVALIDATE_NAME_PATH"in u?u.INVALIDATE_NAME_PATH:u.getNamePath();if(l){var g,p;if((g=(p=u).isList)!==null&&g!==void 0&&g.call(p))return}else if(!i&&(d=(v=u).isListField)!==null&&d!==void 0&&d.call(v))return;if(!a)c.push(h);else{var b="getMeta"in u?u.getMeta():null;a(b)&&c.push(h)}}),lb(n.store,c.map(qt))}),V(this,"getFieldValue",function(r){n.warningUnhooked();var o=qt(r);return qr(n.store,o)}),V(this,"getFieldsError",function(r){n.warningUnhooked();var o=n.getFieldEntitiesForNamePathList(r);return o.map(function(i,a){return i&&!("INVALIDATE_NAME_PATH"in i)?{name:i.getNamePath(),errors:i.getErrors(),warnings:i.getWarnings()}:{name:qt(r[a]),errors:[],warnings:[]}})}),V(this,"getFieldError",function(r){n.warningUnhooked();var o=qt(r),i=n.getFieldsError([o])[0];return i.errors}),V(this,"getFieldWarning",function(r){n.warningUnhooked();var o=qt(r),i=n.getFieldsError([o])[0];return i.warnings}),V(this,"isFieldsTouched",function(){n.warningUnhooked();for(var r=arguments.length,o=new Array(r),i=0;i0&&arguments[0]!==void 0?arguments[0]:{},o=new Ki,i=n.getFieldEntities(!0);i.forEach(function(s){var c=s.props.initialValue,u=s.getNamePath();if(c!==void 0){var d=o.get(u)||new Set;d.add({entity:s,value:c}),o.set(u,d)}});var a=function(c){c.forEach(function(u){var d=u.props.initialValue;if(d!==void 0){var v=u.getNamePath(),h=n.getInitialValue(v);if(h!==void 0)Mn(!1,"Form already set 'initialValues' with path '".concat(v.join("."),"'. Field can not overwrite it."));else{var g=o.get(v);if(g&&g.size>1)Mn(!1,"Multiple Field with path '".concat(v.join("."),"' set 'initialValue'. Can not decide which one to pick."));else if(g){var p=n.getFieldValue(v),b=u.isListField();!b&&(!r.skipExist||p===void 0)&&n.updateStore(Tr(n.store,v,Oe(g)[0].value))}}}})},l;r.entities?l=r.entities:r.namePathList?(l=[],r.namePathList.forEach(function(s){var c=o.get(s);if(c){var u;(u=l).push.apply(u,Oe(Oe(c).map(function(d){return d.entity})))}})):l=i,a(l)}),V(this,"resetFields",function(r){n.warningUnhooked();var o=n.store;if(!r){n.updateStore(Ca(n.initialValues)),n.resetWithFieldInitialValue(),n.notifyObservers(o,null,{type:"reset"}),n.notifyWatch();return}var i=r.map(qt);i.forEach(function(a){var l=n.getInitialValue(a);n.updateStore(Tr(n.store,a,l))}),n.resetWithFieldInitialValue({namePathList:i}),n.notifyObservers(o,i,{type:"reset"}),n.notifyWatch(i)}),V(this,"setFields",function(r){n.warningUnhooked();var o=n.store,i=[];r.forEach(function(a){var l=a.name,s=Je(a,a_),c=qt(l);i.push(c),"value"in s&&n.updateStore(Tr(n.store,c,s.value)),n.notifyObservers(o,[c],{type:"setField",data:a})}),n.notifyWatch(i)}),V(this,"getFields",function(){var r=n.getFieldEntities(!0),o=r.map(function(i){var a=i.getNamePath(),l=i.getMeta(),s=U(U({},l),{},{name:a,value:n.getFieldValue(a)});return Object.defineProperty(s,"originRCField",{value:!0}),s});return o}),V(this,"initEntityValue",function(r){var o=r.props.initialValue;if(o!==void 0){var i=r.getNamePath(),a=qr(n.store,i);a===void 0&&n.updateStore(Tr(n.store,i,o))}}),V(this,"isMergedPreserve",function(r){var o=r!==void 0?r:n.preserve;return o!=null?o:!0}),V(this,"registerField",function(r){n.fieldEntities.push(r);var o=r.getNamePath();if(n.notifyWatch([o]),r.props.initialValue!==void 0){var i=n.store;n.resetWithFieldInitialValue({entities:[r],skipExist:!0}),n.notifyObservers(i,[r.getNamePath()],{type:"valueUpdate",source:"internal"})}return function(a,l){var s=arguments.length>2&&arguments[2]!==void 0?arguments[2]:[];if(n.fieldEntities=n.fieldEntities.filter(function(d){return d!==r}),!n.isMergedPreserve(l)&&(!a||s.length>1)){var c=a?void 0:n.getInitialValue(o);if(o.length&&n.getFieldValue(o)!==c&&n.fieldEntities.every(function(d){return!_w(d.getNamePath(),o)})){var u=n.store;n.updateStore(Tr(u,o,c,!0)),n.notifyObservers(u,[o],{type:"remove"}),n.triggerDependenciesUpdate(u,o)}}n.notifyWatch([o])}}),V(this,"dispatch",function(r){switch(r.type){case"updateValue":{var o=r.namePath,i=r.value;n.updateValue(o,i);break}case"validateField":{var a=r.namePath,l=r.triggerName;n.validateFields([a],{triggerName:l});break}}}),V(this,"notifyObservers",function(r,o,i){if(n.subscribable){var a=U(U({},i),{},{store:n.getFieldsValue(!0)});n.getFieldEntities().forEach(function(l){var s=l.onStoreChange;s(r,o,a)})}else n.forceRootUpdate()}),V(this,"triggerDependenciesUpdate",function(r,o){var i=n.getDependencyChildrenFields(o);return i.length&&n.validateFields(i),n.notifyObservers(r,i,{type:"dependenciesUpdate",relatedFields:[o].concat(Oe(i))}),i}),V(this,"updateValue",function(r,o){var i=qt(r),a=n.store;n.updateStore(Tr(n.store,i,o)),n.notifyObservers(a,[i],{type:"valueUpdate",source:"internal"}),n.notifyWatch([i]);var l=n.triggerDependenciesUpdate(a,i),s=n.callbacks.onValuesChange;if(s){var c=lb(n.store,[i]);s(c,n.getFieldsValue())}n.triggerOnFieldsChange([i].concat(Oe(l)))}),V(this,"setFieldsValue",function(r){n.warningUnhooked();var o=n.store;if(r){var i=Ca(n.store,r);n.updateStore(i)}n.notifyObservers(o,null,{type:"valueUpdate",source:"external"}),n.notifyWatch()}),V(this,"setFieldValue",function(r,o){n.setFields([{name:r,value:o}])}),V(this,"getDependencyChildrenFields",function(r){var o=new Set,i=[],a=new Ki;n.getFieldEntities().forEach(function(s){var c=s.props.dependencies;(c||[]).forEach(function(u){var d=qt(u);a.update(d,function(){var v=arguments.length>0&&arguments[0]!==void 0?arguments[0]:new Set;return v.add(s),v})})});var l=function s(c){var u=a.get(c)||new Set;u.forEach(function(d){if(!o.has(d)){o.add(d);var v=d.getNamePath();d.isFieldDirty()&&v.length&&(i.push(v),s(v))}})};return l(r),i}),V(this,"triggerOnFieldsChange",function(r,o){var i=n.callbacks.onFieldsChange;if(i){var a=n.getFields();if(o){var l=new Ki;o.forEach(function(c){var u=c.name,d=c.errors;l.set(u,d)}),a.forEach(function(c){c.errors=l.get(c.name)||c.errors})}var s=a.filter(function(c){var u=c.name;return Aa(r,u)});s.length&&i(s,a)}}),V(this,"validateFields",function(r,o){n.warningUnhooked();var i,a;Array.isArray(r)||typeof r=="string"||typeof o=="string"?(i=r,a=o):a=r;var l=!!i,s=l?i.map(qt):[],c=[],u=String(Date.now()),d=new Set,v=a||{},h=v.recursive,g=v.dirty;n.getFieldEntities(!0).forEach(function(y){if(l||s.push(y.getNamePath()),!(!y.props.rules||!y.props.rules.length)&&!(g&&!y.isFieldDirty())){var S=y.getNamePath();if(d.add(S.join(u)),!l||Aa(s,S,h)){var x=y.validateRules(U({validateMessages:U(U({},Nw),n.validateMessages)},a));c.push(x.then(function(){return{name:S,errors:[],warnings:[]}}).catch(function($){var E,w=[],R=[];return(E=$.forEach)===null||E===void 0||E.call($,function(P){var N=P.rule.warningOnly,I=P.errors;N?R.push.apply(R,Oe(I)):w.push.apply(w,Oe(I))}),w.length?Promise.reject({name:S,errors:w,warnings:R}):{name:S,errors:w,warnings:R}}))}}});var p=i_(c);n.lastValidatePromise=p,p.catch(function(y){return y}).then(function(y){var S=y.map(function(x){var $=x.name;return $});n.notifyObservers(n.store,S,{type:"validateFinish"}),n.triggerOnFieldsChange(S,y)});var b=p.then(function(){return n.lastValidatePromise===p?Promise.resolve(n.getFieldsValue(s)):Promise.reject([])}).catch(function(y){var S=y.filter(function(x){return x&&x.errors.length});return Promise.reject({values:n.getFieldsValue(s),errorFields:S,outOfDate:n.lastValidatePromise!==p})});b.catch(function(y){return y});var m=s.filter(function(y){return d.has(y.join(u))});return n.triggerOnFieldsChange(m),b}),V(this,"submit",function(){n.warningUnhooked(),n.validateFields().then(function(r){var o=n.callbacks.onFinish;if(o)try{o(r)}catch(i){console.error(i)}}).catch(function(r){var o=n.callbacks.onFinishFailed;o&&o(r)})}),this.forceRootUpdate=t});function Lw(e){var t=f.exports.useRef(),n=f.exports.useState({}),r=G(n,2),o=r[1];if(!t.current)if(e)t.current=e;else{var i=function(){o({})},a=new l_(i);t.current=a.getForm()}return[t.current]}var mg=f.exports.createContext({triggerFormChange:function(){},triggerFormFinish:function(){},registerForm:function(){},unregisterForm:function(){}}),s_=function(t){var n=t.validateMessages,r=t.onFormChange,o=t.onFormFinish,i=t.children,a=f.exports.useContext(mg),l=f.exports.useRef({});return C(mg.Provider,{value:U(U({},a),{},{validateMessages:U(U({},a.validateMessages),n),triggerFormChange:function(c,u){r&&r(c,{changedFields:u,forms:l.current}),a.triggerFormChange(c,u)},triggerFormFinish:function(c,u){o&&o(c,{values:u,forms:l.current}),a.triggerFormFinish(c,u)},registerForm:function(c,u){c&&(l.current=U(U({},l.current),{},V({},c,u))),a.registerForm(c,u)},unregisterForm:function(c){var u=U({},l.current);delete u[c],l.current=u,a.unregisterForm(c)}}),children:i})},c_=["name","initialValues","fields","form","preserve","children","component","validateMessages","validateTrigger","onValuesChange","onFieldsChange","onFinish","onFinishFailed"],u_=function(t,n){var r=t.name,o=t.initialValues,i=t.fields,a=t.form,l=t.preserve,s=t.children,c=t.component,u=c===void 0?"form":c,d=t.validateMessages,v=t.validateTrigger,h=v===void 0?"onChange":v,g=t.onValuesChange,p=t.onFieldsChange,b=t.onFinish,m=t.onFinishFailed,y=Je(t,c_),S=f.exports.useContext(mg),x=Lw(a),$=G(x,1),E=$[0],w=E.getInternalHooks(Si),R=w.useSubscribe,P=w.setInitialValues,N=w.setCallbacks,I=w.setValidateMessages,z=w.setPreserve,F=w.destroyForm;f.exports.useImperativeHandle(n,function(){return E}),f.exports.useEffect(function(){return S.registerForm(r,E),function(){S.unregisterForm(r)}},[S,E,r]),I(U(U({},S.validateMessages),d)),N({onValuesChange:g,onFieldsChange:function(k){if(S.triggerFormChange(r,k),p){for(var j=arguments.length,H=new Array(j>1?j-1:0),W=1;W{let{children:t,status:n,override:r}=e;const o=f.exports.useContext(Jr),i=f.exports.useMemo(()=>{const a=Object.assign({},o);return r&&delete a.isFormItemInput,n&&(delete a.status,delete a.hasFeedback,delete a.feedbackIcon),a},[n,r,o]);return C(Jr.Provider,{value:i,children:t})},v_=f.exports.createContext(void 0),p_=e=>({animationDuration:e,animationFillMode:"both"}),g_=e=>({animationDuration:e,animationFillMode:"both"}),rf=function(e,t,n,r){const i=(arguments.length>4&&arguments[4]!==void 0?arguments[4]:!1)?"&":"";return{[`
+ ${i}${e}-enter,
+ ${i}${e}-appear
+ `]:Object.assign(Object.assign({},p_(r)),{animationPlayState:"paused"}),[`${i}${e}-leave`]:Object.assign(Object.assign({},g_(r)),{animationPlayState:"paused"}),[`
+ ${i}${e}-enter${e}-enter-active,
+ ${i}${e}-appear${e}-appear-active
+ `]:{animationName:t,animationPlayState:"running"},[`${i}${e}-leave${e}-leave-active`]:{animationName:n,animationPlayState:"running",pointerEvents:"none"}}},h_=new Ct("antFadeIn",{"0%":{opacity:0},"100%":{opacity:1}}),m_=new Ct("antFadeOut",{"0%":{opacity:1},"100%":{opacity:0}}),zw=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;const{antCls:n}=e,r=`${n}-fade`,o=t?"&":"";return[rf(r,h_,m_,e.motionDurationMid,t),{[`
+ ${o}${r}-enter,
+ ${o}${r}-appear
+ `]:{opacity:0,animationTimingFunction:"linear"},[`${o}${r}-leave`]:{animationTimingFunction:"linear"}}]},y_=new Ct("antMoveDownIn",{"0%":{transform:"translate3d(0, 100%, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),b_=new Ct("antMoveDownOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(0, 100%, 0)",transformOrigin:"0 0",opacity:0}}),S_=new Ct("antMoveLeftIn",{"0%":{transform:"translate3d(-100%, 0, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),C_=new Ct("antMoveLeftOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(-100%, 0, 0)",transformOrigin:"0 0",opacity:0}}),x_=new Ct("antMoveRightIn",{"0%":{transform:"translate3d(100%, 0, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),w_=new Ct("antMoveRightOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(100%, 0, 0)",transformOrigin:"0 0",opacity:0}}),$_=new Ct("antMoveUpIn",{"0%":{transform:"translate3d(0, -100%, 0)",transformOrigin:"0 0",opacity:0},"100%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1}}),E_=new Ct("antMoveUpOut",{"0%":{transform:"translate3d(0, 0, 0)",transformOrigin:"0 0",opacity:1},"100%":{transform:"translate3d(0, -100%, 0)",transformOrigin:"0 0",opacity:0}}),M_={"move-up":{inKeyframes:$_,outKeyframes:E_},"move-down":{inKeyframes:y_,outKeyframes:b_},"move-left":{inKeyframes:S_,outKeyframes:C_},"move-right":{inKeyframes:x_,outKeyframes:w_}},Zu=(e,t)=>{const{antCls:n}=e,r=`${n}-${t}`,{inKeyframes:o,outKeyframes:i}=M_[t];return[rf(r,o,i,e.motionDurationMid),{[`
+ ${r}-enter,
+ ${r}-appear
+ `]:{opacity:0,animationTimingFunction:e.motionEaseOutCirc},[`${r}-leave`]:{animationTimingFunction:e.motionEaseInOutCirc}}]},nm=new Ct("antSlideUpIn",{"0%":{transform:"scaleY(0.8)",transformOrigin:"0% 0%",opacity:0},"100%":{transform:"scaleY(1)",transformOrigin:"0% 0%",opacity:1}}),rm=new Ct("antSlideUpOut",{"0%":{transform:"scaleY(1)",transformOrigin:"0% 0%",opacity:1},"100%":{transform:"scaleY(0.8)",transformOrigin:"0% 0%",opacity:0}}),om=new Ct("antSlideDownIn",{"0%":{transform:"scaleY(0.8)",transformOrigin:"100% 100%",opacity:0},"100%":{transform:"scaleY(1)",transformOrigin:"100% 100%",opacity:1}}),im=new Ct("antSlideDownOut",{"0%":{transform:"scaleY(1)",transformOrigin:"100% 100%",opacity:1},"100%":{transform:"scaleY(0.8)",transformOrigin:"100% 100%",opacity:0}}),O_=new Ct("antSlideLeftIn",{"0%":{transform:"scaleX(0.8)",transformOrigin:"0% 0%",opacity:0},"100%":{transform:"scaleX(1)",transformOrigin:"0% 0%",opacity:1}}),R_=new Ct("antSlideLeftOut",{"0%":{transform:"scaleX(1)",transformOrigin:"0% 0%",opacity:1},"100%":{transform:"scaleX(0.8)",transformOrigin:"0% 0%",opacity:0}}),I_=new Ct("antSlideRightIn",{"0%":{transform:"scaleX(0.8)",transformOrigin:"100% 0%",opacity:0},"100%":{transform:"scaleX(1)",transformOrigin:"100% 0%",opacity:1}}),P_=new Ct("antSlideRightOut",{"0%":{transform:"scaleX(1)",transformOrigin:"100% 0%",opacity:1},"100%":{transform:"scaleX(0.8)",transformOrigin:"100% 0%",opacity:0}}),T_={"slide-up":{inKeyframes:nm,outKeyframes:rm},"slide-down":{inKeyframes:om,outKeyframes:im},"slide-left":{inKeyframes:O_,outKeyframes:R_},"slide-right":{inKeyframes:I_,outKeyframes:P_}},Xa=(e,t)=>{const{antCls:n}=e,r=`${n}-${t}`,{inKeyframes:o,outKeyframes:i}=T_[t];return[rf(r,o,i,e.motionDurationMid),{[`
+ ${r}-enter,
+ ${r}-appear
+ `]:{transform:"scale(0)",transformOrigin:"0% 0%",opacity:0,animationTimingFunction:e.motionEaseOutQuint,["&-prepare"]:{transform:"scale(1)"}},[`${r}-leave`]:{animationTimingFunction:e.motionEaseInQuint}}]},N_=new Ct("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),__=new Ct("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),fb=new Ct("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),vb=new Ct("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),A_=new Ct("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),D_=new Ct("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),L_=new Ct("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),z_=new Ct("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),F_=new Ct("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),k_=new Ct("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),B_=new Ct("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),j_=new Ct("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),H_={zoom:{inKeyframes:N_,outKeyframes:__},"zoom-big":{inKeyframes:fb,outKeyframes:vb},"zoom-big-fast":{inKeyframes:fb,outKeyframes:vb},"zoom-left":{inKeyframes:L_,outKeyframes:z_},"zoom-right":{inKeyframes:F_,outKeyframes:k_},"zoom-up":{inKeyframes:A_,outKeyframes:D_},"zoom-down":{inKeyframes:B_,outKeyframes:j_}},of=(e,t)=>{const{antCls:n}=e,r=`${n}-${t}`,{inKeyframes:o,outKeyframes:i}=H_[t];return[rf(r,o,i,t==="zoom-big-fast"?e.motionDurationFast:e.motionDurationMid),{[`
+ ${r}-enter,
+ ${r}-appear
+ `]:{transform:"scale(0)",opacity:0,animationTimingFunction:e.motionEaseOutCirc,"&-prepare":{transform:"none"}},[`${r}-leave`]:{animationTimingFunction:e.motionEaseInOutCirc}}]};function pb(e){return{position:e,inset:0}}const Fw=e=>{const{componentCls:t,antCls:n}=e;return[{[`${t}-root`]:{[`${t}${n}-zoom-enter, ${t}${n}-zoom-appear`]:{transform:"none",opacity:0,animationDuration:e.motionDurationSlow,userSelect:"none"},[`${t}${n}-zoom-leave ${t}-content`]:{pointerEvents:"none"},[`${t}-mask`]:Object.assign(Object.assign({},pb("fixed")),{zIndex:e.zIndexPopupBase,height:"100%",backgroundColor:e.colorBgMask,pointerEvents:"none",[`${t}-hidden`]:{display:"none"}}),[`${t}-wrap`]:Object.assign(Object.assign({},pb("fixed")),{zIndex:e.zIndexPopupBase,overflow:"auto",outline:0,WebkitOverflowScrolling:"touch"})}},{[`${t}-root`]:zw(e)}]},W_=e=>{const{componentCls:t}=e;return[{[`${t}-root`]:{[`${t}-wrap-rtl`]:{direction:"rtl"},[`${t}-centered`]:{textAlign:"center","&::before":{display:"inline-block",width:0,height:"100%",verticalAlign:"middle",content:'""'},[t]:{top:0,display:"inline-block",paddingBottom:0,textAlign:"start",verticalAlign:"middle"}},[`@media (max-width: ${e.screenSMMax}px)`]:{[t]:{maxWidth:"calc(100vw - 16px)",margin:`${X(e.marginXS)} auto`},[`${t}-centered`]:{[t]:{flex:1}}}}},{[t]:Object.assign(Object.assign({},Qt(e)),{pointerEvents:"none",position:"relative",top:100,width:"auto",maxWidth:`calc(100vw - ${X(e.calc(e.margin).mul(2).equal())})`,margin:"0 auto",paddingBottom:e.paddingLG,[`${t}-title`]:{margin:0,color:e.titleColor,fontWeight:e.fontWeightStrong,fontSize:e.titleFontSize,lineHeight:e.titleLineHeight,wordWrap:"break-word"},[`${t}-content`]:{position:"relative",backgroundColor:e.contentBg,backgroundClip:"padding-box",border:0,borderRadius:e.borderRadiusLG,boxShadow:e.boxShadow,pointerEvents:"auto",padding:e.contentPadding},[`${t}-close`]:Object.assign({position:"absolute",top:e.calc(e.modalHeaderHeight).sub(e.modalCloseBtnSize).div(2).equal(),insetInlineEnd:e.calc(e.modalHeaderHeight).sub(e.modalCloseBtnSize).div(2).equal(),zIndex:e.calc(e.zIndexPopupBase).add(10).equal(),padding:0,color:e.modalCloseIconColor,fontWeight:e.fontWeightStrong,lineHeight:1,textDecoration:"none",background:"transparent",borderRadius:e.borderRadiusSM,width:e.modalCloseBtnSize,height:e.modalCloseBtnSize,border:0,outline:0,cursor:"pointer",transition:`color ${e.motionDurationMid}, background-color ${e.motionDurationMid}`,"&-x":{display:"flex",fontSize:e.fontSizeLG,fontStyle:"normal",lineHeight:`${X(e.modalCloseBtnSize)}`,justifyContent:"center",textTransform:"none",textRendering:"auto"},"&:hover":{color:e.modalIconHoverColor,backgroundColor:e.closeBtnHoverBg,textDecoration:"none"},"&:active":{backgroundColor:e.closeBtnActiveBg}},Xd(e)),[`${t}-header`]:{color:e.colorText,background:e.headerBg,borderRadius:`${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)} 0 0`,marginBottom:e.headerMarginBottom,padding:e.headerPadding,borderBottom:e.headerBorderBottom},[`${t}-body`]:{fontSize:e.fontSize,lineHeight:e.lineHeight,wordWrap:"break-word",padding:e.bodyPadding},[`${t}-footer`]:{textAlign:"end",background:e.footerBg,marginTop:e.footerMarginTop,padding:e.footerPadding,borderTop:e.footerBorderTop,borderRadius:e.footerBorderRadius,[`> ${e.antCls}-btn + ${e.antCls}-btn`]:{marginInlineStart:e.marginXS}},[`${t}-open`]:{overflow:"hidden"}})},{[`${t}-pure-panel`]:{top:"auto",padding:0,display:"flex",flexDirection:"column",[`${t}-content,
+ ${t}-body,
+ ${t}-confirm-body-wrapper`]:{display:"flex",flexDirection:"column",flex:"auto"},[`${t}-confirm-body`]:{marginBottom:"auto"}}}]},V_=e=>{const{componentCls:t}=e;return{[`${t}-root`]:{[`${t}-wrap-rtl`]:{direction:"rtl",[`${t}-confirm-body`]:{direction:"rtl"}}}}},U_=e=>{const t=e.padding,n=e.fontSizeHeading5,r=e.lineHeightHeading5;return $t(e,{modalHeaderHeight:e.calc(e.calc(r).mul(n).equal()).add(e.calc(t).mul(2).equal()).equal(),modalFooterBorderColorSplit:e.colorSplit,modalFooterBorderStyle:e.lineType,modalFooterBorderWidth:e.lineWidth,modalIconHoverColor:e.colorIconHover,modalCloseIconColor:e.colorIcon,modalCloseBtnSize:e.fontHeight,modalConfirmIconSize:e.fontHeight,modalTitleHeight:e.calc(e.titleFontSize).mul(e.titleLineHeight).equal()})},Y_=e=>({footerBg:"transparent",headerBg:e.colorBgElevated,titleLineHeight:e.lineHeightHeading5,titleFontSize:e.fontSizeHeading5,contentBg:e.colorBgElevated,titleColor:e.colorTextHeading,closeBtnHoverBg:e.wireframe?"transparent":e.colorFillContent,closeBtnActiveBg:e.wireframe?"transparent":e.colorFillContentHover,contentPadding:e.wireframe?0:`${X(e.paddingMD)} ${X(e.paddingContentHorizontalLG)}`,headerPadding:e.wireframe?`${X(e.padding)} ${X(e.paddingLG)}`:0,headerBorderBottom:e.wireframe?`${X(e.lineWidth)} ${e.lineType} ${e.colorSplit}`:"none",headerMarginBottom:e.wireframe?0:e.marginXS,bodyPadding:e.wireframe?e.paddingLG:0,footerPadding:e.wireframe?`${X(e.paddingXS)} ${X(e.padding)}`:0,footerBorderTop:e.wireframe?`${X(e.lineWidth)} ${e.lineType} ${e.colorSplit}`:"none",footerBorderRadius:e.wireframe?`0 0 ${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)}`:0,footerMarginTop:e.wireframe?0:e.marginSM,confirmBodyPadding:e.wireframe?`${X(e.padding*2)} ${X(e.padding*2)} ${X(e.paddingLG)}`:0,confirmIconMarginInlineEnd:e.wireframe?e.margin:e.marginSM,confirmBtnsMarginTop:e.wireframe?e.marginLG:e.marginSM});vn("Modal",e=>{const t=U_(e);return[W_(t),V_(t),Fw(t),of(t,"zoom")]},Y_,{unitless:{titleLineHeight:!0}});function G_(e){return t=>C(ai,{theme:{token:{motion:!1,zIndexPopupBase:0}},children:C(e,{...Object.assign({},t)})})}const K_=(e,t,n,r)=>G_(i=>{const{prefixCls:a,style:l}=i,s=f.exports.useRef(null),[c,u]=f.exports.useState(0),[d,v]=f.exports.useState(0),[h,g]=kt(!1,{value:i.open}),{getPrefixCls:p}=f.exports.useContext(ot),b=p(t||"select",a);f.exports.useEffect(()=>{if(g(!0),typeof ResizeObserver<"u"){const S=new ResizeObserver($=>{const E=$[0].target;u(E.offsetHeight+8),v(E.offsetWidth)}),x=setInterval(()=>{var $;const E=n?`.${n(b)}`:`.${b}-dropdown`,w=($=s.current)===null||$===void 0?void 0:$.querySelector(E);w&&(clearInterval(x),S.observe(w))},10);return()=>{clearInterval(x),S.disconnect()}}},[]);let m=Object.assign(Object.assign({},i),{style:Object.assign(Object.assign({},l),{margin:0}),open:h,visible:h,getPopupContainer:()=>s.current});return r&&(m=r(m)),C("div",{ref:s,style:{paddingBottom:c,position:"relative",minWidth:d},children:C(e,{...Object.assign({},m)})})}),q_=K_,am=function(){if(typeof navigator>"u"||typeof window>"u")return!1;var e=navigator.userAgent||navigator.vendor||window.opera;return/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(e)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(e==null?void 0:e.substr(0,4))};var af=function(t){var n=t.className,r=t.customizeIcon,o=t.customizeIconProps,i=t.children,a=t.onMouseDown,l=t.onClick,s=typeof r=="function"?r(o):r;return C("span",{className:n,onMouseDown:function(u){u.preventDefault(),a==null||a(u)},style:{userSelect:"none",WebkitUserSelect:"none"},unselectable:"on",onClick:l,"aria-hidden":!0,children:s!==void 0?s:C("span",{className:te(n.split(/\s+/).map(function(c){return"".concat(c,"-icon")})),children:i})})},X_=function(t,n,r,o,i){var a=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!1,l=arguments.length>6?arguments[6]:void 0,s=arguments.length>7?arguments[7]:void 0,c=lt.useMemo(function(){if(Qe(o)==="object")return o.clearIcon;if(i)return i},[o,i]),u=lt.useMemo(function(){return!!(!a&&!!o&&(r.length||l)&&!(s==="combobox"&&l===""))},[o,a,r.length,l,s]);return{allowClear:u,clearIcon:C(af,{className:"".concat(t,"-clear"),onMouseDown:n,customizeIcon:c,children:"\xD7"})}},kw=f.exports.createContext(null);function Q_(){return f.exports.useContext(kw)}function Z_(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:10,t=f.exports.useState(!1),n=G(t,2),r=n[0],o=n[1],i=f.exports.useRef(null),a=function(){window.clearTimeout(i.current)};f.exports.useEffect(function(){return a},[]);var l=function(c,u){a(),i.current=window.setTimeout(function(){o(c),u&&u()},e)};return[r,l,a]}function Bw(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:250,t=f.exports.useRef(null),n=f.exports.useRef(null);f.exports.useEffect(function(){return function(){window.clearTimeout(n.current)}},[]);function r(o){(o||t.current===null)&&(t.current=o),window.clearTimeout(n.current),n.current=window.setTimeout(function(){t.current=null},e)}return[function(){return t.current},r]}function J_(e,t,n,r){var o=f.exports.useRef(null);o.current={open:t,triggerOpen:n,customizedTrigger:r},f.exports.useEffect(function(){function i(a){var l;if(!((l=o.current)!==null&&l!==void 0&&l.customizedTrigger)){var s=a.target;s.shadowRoot&&a.composed&&(s=a.composedPath()[0]||s),o.current.open&&e().filter(function(c){return c}).every(function(c){return!c.contains(s)&&c!==s})&&o.current.triggerOpen(!1)}}return window.addEventListener("mousedown",i),function(){return window.removeEventListener("mousedown",i)}},[])}var eA=["prefixCls","invalidate","item","renderItem","responsive","responsiveDisabled","registerSize","itemKey","className","style","children","display","order","component"],qi=void 0;function tA(e,t){var n=e.prefixCls,r=e.invalidate,o=e.item,i=e.renderItem,a=e.responsive,l=e.responsiveDisabled,s=e.registerSize,c=e.itemKey,u=e.className,d=e.style,v=e.children,h=e.display,g=e.order,p=e.component,b=p===void 0?"div":p,m=Je(e,eA),y=a&&!h;function S(R){s(c,R)}f.exports.useEffect(function(){return function(){S(null)}},[]);var x=i&&o!==qi?i(o):v,$;r||($={opacity:y?0:1,height:y?0:qi,overflowY:y?"hidden":qi,order:a?g:qi,pointerEvents:y?"none":qi,position:y?"absolute":qi});var E={};y&&(E["aria-hidden"]=!0);var w=C(b,{className:te(!r&&n,u),style:U(U({},$),d),...E,...m,ref:t,children:x});return a&&(w=C(mr,{onResize:function(P){var N=P.offsetWidth;S(N)},disabled:l,children:w})),w}var Jl=f.exports.forwardRef(tA);Jl.displayName="Item";function nA(e){if(typeof MessageChannel>"u")St(e);else{var t=new MessageChannel;t.port1.onmessage=function(){return e()},t.port2.postMessage(void 0)}}function rA(){var e=f.exports.useRef(null),t=function(r){e.current||(e.current=[],nA(function(){Gn.exports.unstable_batchedUpdates(function(){e.current.forEach(function(o){o()}),e.current=null})})),e.current.push(r)};return t}function Cl(e,t){var n=f.exports.useState(t),r=G(n,2),o=r[0],i=r[1],a=hn(function(l){e(function(){i(l)})});return[o,a]}var Ju=lt.createContext(null),oA=["component"],iA=["className"],aA=["className"],lA=function(t,n){var r=f.exports.useContext(Ju);if(!r){var o=t.component,i=o===void 0?"div":o,a=Je(t,oA);return C(i,{...a,ref:n})}var l=r.className,s=Je(r,iA),c=t.className,u=Je(t,aA);return C(Ju.Provider,{value:null,children:C(Jl,{ref:n,className:te(l,c),...s,...u})})},jw=f.exports.forwardRef(lA);jw.displayName="RawItem";var sA=["prefixCls","data","renderItem","renderRawItem","itemKey","itemWidth","ssr","style","className","maxCount","renderRest","renderRawRest","suffix","component","itemComponent","onVisibleChange"],Hw="responsive",Ww="invalidate";function cA(e){return"+ ".concat(e.length," ...")}function uA(e,t){var n=e.prefixCls,r=n===void 0?"rc-overflow":n,o=e.data,i=o===void 0?[]:o,a=e.renderItem,l=e.renderRawItem,s=e.itemKey,c=e.itemWidth,u=c===void 0?10:c,d=e.ssr,v=e.style,h=e.className,g=e.maxCount,p=e.renderRest,b=e.renderRawRest,m=e.suffix,y=e.component,S=y===void 0?"div":y,x=e.itemComponent,$=e.onVisibleChange,E=Je(e,sA),w=d==="full",R=rA(),P=Cl(R,null),N=G(P,2),I=N[0],z=N[1],F=I||0,T=Cl(R,new Map),D=G(T,2),_=D[0],O=D[1],M=Cl(R,0),L=G(M,2),A=L[0],B=L[1],k=Cl(R,0),j=G(k,2),H=j[0],W=j[1],Y=Cl(R,0),K=G(Y,2),q=K[0],ee=K[1],Z=f.exports.useState(null),Q=G(Z,2),ne=Q[0],ae=Q[1],J=f.exports.useState(null),re=G(J,2),fe=re[0],ve=re[1],pe=f.exports.useMemo(function(){return fe===null&&w?Number.MAX_SAFE_INTEGER:fe||0},[fe,I]),oe=f.exports.useState(!1),se=G(oe,2),le=se[0],Ce=se[1],ce="".concat(r,"-item"),de=Math.max(A,H),xe=g===Hw,he=i.length&&xe,ke=g===Ww,we=he||typeof g=="number"&&i.length>g,ge=f.exports.useMemo(function(){var be=i;return he?I===null&&w?be=i:be=i.slice(0,Math.min(i.length,F/u)):typeof g=="number"&&(be=i.slice(0,g)),be},[i,u,I,g,he]),Pe=f.exports.useMemo(function(){return he?i.slice(pe+1):i.slice(ge.length)},[i,ge,he,pe]),Se=f.exports.useCallback(function(be,Ae){var Me;return typeof s=="function"?s(be):(Me=s&&(be==null?void 0:be[s]))!==null&&Me!==void 0?Me:Ae},[s]),st=f.exports.useCallback(a||function(be){return be},[a]);function nt(be,Ae,Me){fe===be&&(Ae===void 0||Ae===ne)||(ve(be),Me||(Ce(beF){nt($e-1,be-Te-q+H);break}}m&&qe(0)+q>F&&ae(null)}},[F,_,H,q,Se,ge]);var it=le&&!!Pe.length,ft={};ne!==null&&he&&(ft={position:"absolute",left:ne,top:0});var ut={prefixCls:ce,responsive:he,component:x,invalidate:ke},Ue=l?function(be,Ae){var Me=Se(be,Ae);return C(Ju.Provider,{value:U(U({},ut),{},{order:Ae,item:be,itemKey:Me,registerSize:Ee,display:Ae<=pe}),children:l(be,Ae)},Me)}:function(be,Ae){var Me=Se(be,Ae);return f.exports.createElement(Jl,{...ut,order:Ae,key:Me,item:be,renderItem:st,itemKey:Me,registerSize:Ee,display:Ae<=pe})},He,Xe={order:it?pe:Number.MAX_SAFE_INTEGER,className:"".concat(ce,"-rest"),registerSize:_e,display:it};if(b)b&&(He=C(Ju.Provider,{value:U(U({},ut),Xe),children:b(Pe)}));else{var Le=p||cA;He=C(Jl,{...ut,...Xe,children:typeof Le=="function"?Le(Pe):Le})}var Re=ie(S,{className:te(!ke&&r,h),style:v,ref:t,...E,children:[ge.map(Ue),we?He:null,m&&C(Jl,{...ut,responsive:xe,responsiveDisabled:!he,order:pe,className:"".concat(ce,"-suffix"),registerSize:Be,display:!0,style:ft,children:m})]});return xe&&(Re=C(mr,{onResize:Ne,disabled:!he,children:Re})),Re}var Zr=f.exports.forwardRef(uA);Zr.displayName="Overflow";Zr.Item=jw;Zr.RESPONSIVE=Hw;Zr.INVALIDATE=Ww;var dA=function(t,n){var r,o=t.prefixCls,i=t.id,a=t.inputElement,l=t.disabled,s=t.tabIndex,c=t.autoFocus,u=t.autoComplete,d=t.editable,v=t.activeDescendantId,h=t.value,g=t.maxLength,p=t.onKeyDown,b=t.onMouseDown,m=t.onChange,y=t.onPaste,S=t.onCompositionStart,x=t.onCompositionEnd,$=t.open,E=t.attrs,w=a||C("input",{}),R=w,P=R.ref,N=R.props,I=N.onKeyDown,z=N.onChange,F=N.onMouseDown,T=N.onCompositionStart,D=N.onCompositionEnd,_=N.style;return"maxLength"in w.props,w=f.exports.cloneElement(w,U(U(U({type:"search"},N),{},{id:i,ref:xr(n,P),disabled:l,tabIndex:s,autoComplete:u||"off",autoFocus:c,className:te("".concat(o,"-selection-search-input"),(r=w)===null||r===void 0||(r=r.props)===null||r===void 0?void 0:r.className),role:"combobox","aria-expanded":$||!1,"aria-haspopup":"listbox","aria-owns":"".concat(i,"_list"),"aria-autocomplete":"list","aria-controls":"".concat(i,"_list"),"aria-activedescendant":$?v:void 0},E),{},{value:d?h:"",maxLength:g,readOnly:!d,unselectable:d?null:"on",style:U(U({},_),{},{opacity:d?null:0}),onKeyDown:function(M){p(M),I&&I(M)},onMouseDown:function(M){b(M),F&&F(M)},onChange:function(M){m(M),z&&z(M)},onCompositionStart:function(M){S(M),T&&T(M)},onCompositionEnd:function(M){x(M),D&&D(M)},onPaste:y})),w},Vw=f.exports.forwardRef(dA);function Uw(e){return Array.isArray(e)?e:e!==void 0?[e]:[]}var fA=typeof window<"u"&&window.document&&window.document.documentElement,vA=fA;function pA(e){return e!=null}function gA(e){return!e&&e!==0}function gb(e){return["string","number"].includes(Qe(e))}function Yw(e){var t=void 0;return e&&(gb(e.title)?t=e.title.toString():gb(e.label)&&(t=e.label.toString())),t}function hA(e,t){vA?f.exports.useLayoutEffect(e,t):f.exports.useEffect(e,t)}function mA(e){var t;return(t=e.key)!==null&&t!==void 0?t:e.value}var hb=function(t){t.preventDefault(),t.stopPropagation()},yA=function(t){var n=t.id,r=t.prefixCls,o=t.values,i=t.open,a=t.searchValue,l=t.autoClearSearchValue,s=t.inputRef,c=t.placeholder,u=t.disabled,d=t.mode,v=t.showSearch,h=t.autoFocus,g=t.autoComplete,p=t.activeDescendantId,b=t.tabIndex,m=t.removeIcon,y=t.maxTagCount,S=t.maxTagTextLength,x=t.maxTagPlaceholder,$=x===void 0?function(ae){return"+ ".concat(ae.length," ...")}:x,E=t.tagRender,w=t.onToggleOpen,R=t.onRemove,P=t.onInputChange,N=t.onInputPaste,I=t.onInputKeyDown,z=t.onInputMouseDown,F=t.onInputCompositionStart,T=t.onInputCompositionEnd,D=f.exports.useRef(null),_=f.exports.useState(0),O=G(_,2),M=O[0],L=O[1],A=f.exports.useState(!1),B=G(A,2),k=B[0],j=B[1],H="".concat(r,"-selection"),W=i||d==="multiple"&&l===!1||d==="tags"?a:"",Y=d==="tags"||d==="multiple"&&l===!1||v&&(i||k);hA(function(){L(D.current.scrollWidth)},[W]);var K=function(J,re,fe,ve,pe){return ie("span",{title:Yw(J),className:te("".concat(H,"-item"),V({},"".concat(H,"-item-disabled"),fe)),children:[C("span",{className:"".concat(H,"-item-content"),children:re}),ve&&C(af,{className:"".concat(H,"-item-remove"),onMouseDown:hb,onClick:pe,customizeIcon:m,children:"\xD7"})]})},q=function(J,re,fe,ve,pe){var oe=function(le){hb(le),w(!i)};return C("span",{onMouseDown:oe,children:E({label:re,value:J,disabled:fe,closable:ve,onClose:pe})})},ee=function(J){var re=J.disabled,fe=J.label,ve=J.value,pe=!u&&!re,oe=fe;if(typeof S=="number"&&(typeof fe=="string"||typeof fe=="number")){var se=String(oe);se.length>S&&(oe="".concat(se.slice(0,S),"..."))}var le=function(ce){ce&&ce.stopPropagation(),R(J)};return typeof E=="function"?q(ve,oe,re,pe,le):K(J,oe,re,pe,le)},Z=function(J){var re=typeof $=="function"?$(J):$;return K({title:re},re,!1)},Q=ie("div",{className:"".concat(H,"-search"),style:{width:M},onFocus:function(){j(!0)},onBlur:function(){j(!1)},children:[C(Vw,{ref:s,open:i,prefixCls:r,id:n,inputElement:null,disabled:u,autoFocus:h,autoComplete:g,editable:Y,activeDescendantId:p,value:W,onKeyDown:I,onMouseDown:z,onChange:P,onPaste:N,onCompositionStart:F,onCompositionEnd:T,tabIndex:b,attrs:Ka(t,!0)}),ie("span",{ref:D,className:"".concat(H,"-search-mirror"),"aria-hidden":!0,children:[W,"\xA0"]})]}),ne=C(Zr,{prefixCls:"".concat(H,"-overflow"),data:o,renderItem:ee,renderRest:Z,suffix:Q,itemKey:mA,maxCount:y});return ie(Tt,{children:[ne,!o.length&&!W&&C("span",{className:"".concat(H,"-placeholder"),children:c})]})},bA=function(t){var n=t.inputElement,r=t.prefixCls,o=t.id,i=t.inputRef,a=t.disabled,l=t.autoFocus,s=t.autoComplete,c=t.activeDescendantId,u=t.mode,d=t.open,v=t.values,h=t.placeholder,g=t.tabIndex,p=t.showSearch,b=t.searchValue,m=t.activeValue,y=t.maxLength,S=t.onInputKeyDown,x=t.onInputMouseDown,$=t.onInputChange,E=t.onInputPaste,w=t.onInputCompositionStart,R=t.onInputCompositionEnd,P=t.title,N=f.exports.useState(!1),I=G(N,2),z=I[0],F=I[1],T=u==="combobox",D=T||p,_=v[0],O=b||"";T&&m&&!z&&(O=m),f.exports.useEffect(function(){T&&F(!1)},[T,m]);var M=u!=="combobox"&&!d&&!p?!1:!!O,L=P===void 0?Yw(_):P,A=f.exports.useMemo(function(){return _?null:C("span",{className:"".concat(r,"-selection-placeholder"),style:M?{visibility:"hidden"}:void 0,children:h})},[_,M,h,r]);return ie(Tt,{children:[C("span",{className:"".concat(r,"-selection-search"),children:C(Vw,{ref:i,prefixCls:r,id:o,open:d,inputElement:n,disabled:a,autoFocus:l,autoComplete:s,editable:D,activeDescendantId:c,value:O,onKeyDown:S,onMouseDown:x,onChange:function(k){F(!0),$(k)},onPaste:E,onCompositionStart:w,onCompositionEnd:R,tabIndex:g,attrs:Ka(t,!0),maxLength:T?y:void 0})}),!T&&_?C("span",{className:"".concat(r,"-selection-item"),title:L,style:M?{visibility:"hidden"}:void 0,children:_.label}):null,A]})};function SA(e){return![ue.ESC,ue.SHIFT,ue.BACKSPACE,ue.TAB,ue.WIN_KEY,ue.ALT,ue.META,ue.WIN_KEY_RIGHT,ue.CTRL,ue.SEMICOLON,ue.EQUALS,ue.CAPS_LOCK,ue.CONTEXT_MENU,ue.F1,ue.F2,ue.F3,ue.F4,ue.F5,ue.F6,ue.F7,ue.F8,ue.F9,ue.F10,ue.F11,ue.F12].includes(e)}var CA=function(t,n){var r=f.exports.useRef(null),o=f.exports.useRef(!1),i=t.prefixCls,a=t.open,l=t.mode,s=t.showSearch,c=t.tokenWithEnter,u=t.autoClearSearchValue,d=t.onSearch,v=t.onSearchSubmit,h=t.onToggleOpen,g=t.onInputKeyDown,p=t.domRef;f.exports.useImperativeHandle(n,function(){return{focus:function(){r.current.focus()},blur:function(){r.current.blur()}}});var b=Bw(0),m=G(b,2),y=m[0],S=m[1],x=function(O){var M=O.which;(M===ue.UP||M===ue.DOWN)&&O.preventDefault(),g&&g(O),M===ue.ENTER&&l==="tags"&&!o.current&&!a&&(v==null||v(O.target.value)),SA(M)&&h(!0)},$=function(){S(!0)},E=f.exports.useRef(null),w=function(O){d(O,!0,o.current)!==!1&&h(!0)},R=function(){o.current=!0},P=function(O){o.current=!1,l!=="combobox"&&w(O.target.value)},N=function(O){var M=O.target.value;if(c&&E.current&&/[\r\n]/.test(E.current)){var L=E.current.replace(/[\r\n]+$/,"").replace(/\r\n/g," ").replace(/[\r\n]/g," ");M=M.replace(L,E.current)}E.current=null,w(M)},I=function(O){var M=O.clipboardData,L=M==null?void 0:M.getData("text");E.current=L||""},z=function(O){var M=O.target;if(M!==r.current){var L=document.body.style.msTouchAction!==void 0;L?setTimeout(function(){r.current.focus()}):r.current.focus()}},F=function(O){var M=y();O.target!==r.current&&!M&&l!=="combobox"&&O.preventDefault(),(l!=="combobox"&&(!s||!M)||!a)&&(a&&u!==!1&&d("",!0,!1),h())},T={inputRef:r,onInputKeyDown:x,onInputMouseDown:$,onInputChange:N,onInputPaste:I,onInputCompositionStart:R,onInputCompositionEnd:P},D=l==="multiple"||l==="tags"?C(yA,{...t,...T}):C(bA,{...t,...T});return C("div",{ref:p,className:"".concat(i,"-selector"),onClick:z,onMouseDown:F,children:D})},xA=f.exports.forwardRef(CA);function wA(e){var t=e.prefixCls,n=e.align,r=e.arrow,o=e.arrowPos,i=r||{},a=i.className,l=i.content,s=o.x,c=s===void 0?0:s,u=o.y,d=u===void 0?0:u,v=f.exports.useRef();if(!n||!n.points)return null;var h={position:"absolute"};if(n.autoArrow!==!1){var g=n.points[0],p=n.points[1],b=g[0],m=g[1],y=p[0],S=p[1];b===y||!["t","b"].includes(b)?h.top=d:b==="t"?h.top=0:h.bottom=0,m===S||!["l","r"].includes(m)?h.left=c:m==="l"?h.left=0:h.right=0}return C("div",{ref:v,className:te("".concat(t,"-arrow"),a),style:h,children:l})}function $A(e){var t=e.prefixCls,n=e.open,r=e.zIndex,o=e.mask,i=e.motion;return o?C(to,{...i,motionAppear:!0,visible:n,removeOnLeave:!0,children:function(a){var l=a.className;return C("div",{style:{zIndex:r},className:te("".concat(t,"-mask"),l)})}}):null}var EA=f.exports.memo(function(e){var t=e.children;return t},function(e,t){return t.cache}),MA=f.exports.forwardRef(function(e,t){var n=e.popup,r=e.className,o=e.prefixCls,i=e.style,a=e.target,l=e.onVisibleChanged,s=e.open,c=e.keepDom,u=e.fresh,d=e.onClick,v=e.mask,h=e.arrow,g=e.arrowPos,p=e.align,b=e.motion,m=e.maskMotion,y=e.forceRender,S=e.getPopupContainer,x=e.autoDestroy,$=e.portal,E=e.zIndex,w=e.onMouseEnter,R=e.onMouseLeave,P=e.onPointerEnter,N=e.ready,I=e.offsetX,z=e.offsetY,F=e.offsetR,T=e.offsetB,D=e.onAlign,_=e.onPrepare,O=e.stretch,M=e.targetWidth,L=e.targetHeight,A=typeof n=="function"?n():n,B=s||c,k=(S==null?void 0:S.length)>0,j=f.exports.useState(!S||!k),H=G(j,2),W=H[0],Y=H[1];if(Nt(function(){!W&&k&&a&&Y(!0)},[W,k,a]),!W)return null;var K="auto",q={left:"-1000vw",top:"-1000vh",right:K,bottom:K};if(N||!s){var ee,Z=p.points,Q=p.dynamicInset||((ee=p._experimental)===null||ee===void 0?void 0:ee.dynamicInset),ne=Q&&Z[0][1]==="r",ae=Q&&Z[0][0]==="b";ne?(q.right=F,q.left=K):(q.left=I,q.right=K),ae?(q.bottom=T,q.top=K):(q.top=z,q.bottom=K)}var J={};return O&&(O.includes("height")&&L?J.height=L:O.includes("minHeight")&&L&&(J.minHeight=L),O.includes("width")&&M?J.width=M:O.includes("minWidth")&&M&&(J.minWidth=M)),s||(J.pointerEvents="none"),ie($,{open:y||B,getContainer:S&&function(){return S(a)},autoDestroy:x,children:[C($A,{prefixCls:o,open:s,zIndex:E,mask:v,motion:m}),C(mr,{onResize:D,disabled:!s,children:function(re){return C(to,{motionAppear:!0,motionEnter:!0,motionLeave:!0,removeOnLeave:!1,forceRender:y,leavedClassName:"".concat(o,"-hidden"),...b,onAppearPrepare:_,onEnterPrepare:_,visible:s,onVisibleChanged:function(ve){var pe;b==null||(pe=b.onVisibleChanged)===null||pe===void 0||pe.call(b,ve),l(ve)},children:function(fe,ve){var pe=fe.className,oe=fe.style,se=te(o,pe,r);return ie("div",{ref:xr(re,t,ve),className:se,style:U(U(U(U({"--arrow-x":"".concat(g.x||0,"px"),"--arrow-y":"".concat(g.y||0,"px")},q),J),oe),{},{boxSizing:"border-box",zIndex:E},i),onMouseEnter:w,onMouseLeave:R,onPointerEnter:P,onClick:d,children:[h&&C(wA,{prefixCls:o,arrow:h,arrowPos:g,align:p}),C(EA,{cache:!s&&!u,children:A})]})}})}})]})}),OA=f.exports.forwardRef(function(e,t){var n=e.children,r=e.getTriggerDOMNode,o=ki(n),i=f.exports.useCallback(function(l){zh(t,r?r(l):l)},[r]),a=Fi(i,n.ref);return o?f.exports.cloneElement(n,{ref:a}):n}),mb=f.exports.createContext(null);function yb(e){return e?Array.isArray(e)?e:[e]:[]}function RA(e,t,n,r){return f.exports.useMemo(function(){var o=yb(n!=null?n:t),i=yb(r!=null?r:t),a=new Set(o),l=new Set(i);return e&&(a.has("hover")&&(a.delete("hover"),a.add("click")),l.has("hover")&&(l.delete("hover"),l.add("click"))),[a,l]},[e,t,n,r])}function IA(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[],n=arguments.length>2?arguments[2]:void 0;return n?e[0]===t[0]:e[0]===t[0]&&e[1]===t[1]}function PA(e,t,n,r){for(var o=n.points,i=Object.keys(e),a=0;a1&&arguments[1]!==void 0?arguments[1]:1;return Number.isNaN(e)?t:e}function xl(e){return Rs(parseFloat(e),0)}function Sb(e,t){var n=U({},e);return(t||[]).forEach(function(r){if(!(r instanceof HTMLBodyElement||r instanceof HTMLHtmlElement)){var o=qs(r).getComputedStyle(r),i=o.overflow,a=o.overflowClipMargin,l=o.borderTopWidth,s=o.borderBottomWidth,c=o.borderLeftWidth,u=o.borderRightWidth,d=r.getBoundingClientRect(),v=r.offsetHeight,h=r.clientHeight,g=r.offsetWidth,p=r.clientWidth,b=xl(l),m=xl(s),y=xl(c),S=xl(u),x=Rs(Math.round(d.width/g*1e3)/1e3),$=Rs(Math.round(d.height/v*1e3)/1e3),E=(g-p-y-S)*x,w=(v-h-b-m)*$,R=b*$,P=m*$,N=y*x,I=S*x,z=0,F=0;if(i==="clip"){var T=xl(a);z=T*x,F=T*$}var D=d.x+N-z,_=d.y+R-F,O=D+d.width+2*z-N-I-E,M=_+d.height+2*F-R-P-w;n.left=Math.max(n.left,D),n.top=Math.max(n.top,_),n.right=Math.min(n.right,O),n.bottom=Math.min(n.bottom,M)}}),n}function Cb(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n="".concat(t),r=n.match(/^(.*)\%$/);return r?e*(parseFloat(r[1])/100):parseFloat(n)}function xb(e,t){var n=t||[],r=G(n,2),o=r[0],i=r[1];return[Cb(e.width,o),Cb(e.height,i)]}function wb(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"";return[e[0],e[1]]}function Xi(e,t){var n=t[0],r=t[1],o,i;return n==="t"?i=e.y:n==="b"?i=e.y+e.height:i=e.y+e.height/2,r==="l"?o=e.x:r==="r"?o=e.x+e.width:o=e.x+e.width/2,{x:o,y:i}}function Mo(e,t){var n={t:"b",b:"t",l:"r",r:"l"};return e.map(function(r,o){return o===t?n[r]||"c":r}).join("")}function TA(e,t,n,r,o,i,a){var l=f.exports.useState({ready:!1,offsetX:0,offsetY:0,offsetR:0,offsetB:0,arrowX:0,arrowY:0,scaleX:1,scaleY:1,align:o[r]||{}}),s=G(l,2),c=s[0],u=s[1],d=f.exports.useRef(0),v=f.exports.useMemo(function(){return t?yg(t):[]},[t]),h=f.exports.useRef({}),g=function(){h.current={}};e||g();var p=hn(function(){if(t&&n&&e){let un=function(tc,ro){var si=arguments.length>2&&arguments[2]!==void 0?arguments[2]:se,Vi=A.x+tc,ul=A.y+ro,yf=Vi+ee,bf=ul+q,Sf=Math.max(Vi,si.left),Cf=Math.max(ul,si.top),je=Math.min(yf,si.right),tt=Math.min(bf,si.bottom);return Math.max(0,(je-Sf)*(tt-Cf))},cl=function(){ct=A.y+Le,We=ct+q,Ve=A.x+Xe,vt=Ve+ee};var Wi=un,iE=cl,y,S,x=t,$=x.ownerDocument,E=qs(x),w=E.getComputedStyle(x),R=w.width,P=w.height,N=w.position,I=x.style.left,z=x.style.top,F=x.style.right,T=x.style.bottom,D=x.style.overflow,_=U(U({},o[r]),i),O=$.createElement("div");(y=x.parentElement)===null||y===void 0||y.appendChild(O),O.style.left="".concat(x.offsetLeft,"px"),O.style.top="".concat(x.offsetTop,"px"),O.style.position=N,O.style.height="".concat(x.offsetHeight,"px"),O.style.width="".concat(x.offsetWidth,"px"),x.style.left="0",x.style.top="0",x.style.right="auto",x.style.bottom="auto",x.style.overflow="hidden";var M;if(Array.isArray(n))M={x:n[0],y:n[1],width:0,height:0};else{var L=n.getBoundingClientRect();M={x:L.x,y:L.y,width:L.width,height:L.height}}var A=x.getBoundingClientRect(),B=$.documentElement,k=B.clientWidth,j=B.clientHeight,H=B.scrollWidth,W=B.scrollHeight,Y=B.scrollTop,K=B.scrollLeft,q=A.height,ee=A.width,Z=M.height,Q=M.width,ne={left:0,top:0,right:k,bottom:j},ae={left:-K,top:-Y,right:H-K,bottom:W-Y},J=_.htmlRegion,re="visible",fe="visibleFirst";J!=="scroll"&&J!==fe&&(J=re);var ve=J===fe,pe=Sb(ae,v),oe=Sb(ne,v),se=J===re?oe:pe,le=ve?oe:se;x.style.left="auto",x.style.top="auto",x.style.right="0",x.style.bottom="0";var Ce=x.getBoundingClientRect();x.style.left=I,x.style.top=z,x.style.right=F,x.style.bottom=T,x.style.overflow=D,(S=x.parentElement)===null||S===void 0||S.removeChild(O);var ce=Rs(Math.round(ee/parseFloat(R)*1e3)/1e3),de=Rs(Math.round(q/parseFloat(P)*1e3)/1e3);if(ce===0||de===0||Wu(n)&&!Jd(n))return;var xe=_.offset,he=_.targetOffset,ke=xb(A,xe),we=G(ke,2),ge=we[0],Pe=we[1],Se=xb(M,he),st=G(Se,2),nt=st[0],Ne=st[1];M.x-=nt,M.y-=Ne;var Ee=_.points||[],_e=G(Ee,2),Be=_e[0],qe=_e[1],it=wb(qe),ft=wb(Be),ut=Xi(M,it),Ue=Xi(A,ft),He=U({},_),Xe=ut.x-Ue.x+ge,Le=ut.y-Ue.y+Pe,Re=un(Xe,Le),be=un(Xe,Le,oe),Ae=Xi(M,["t","l"]),Me=Xi(A,["t","l"]),$e=Xi(M,["b","r"]),Te=Xi(A,["b","r"]),ye=_.overflow||{},Ge=ye.adjustX,Ze=ye.adjustY,et=ye.shiftX,ht=ye.shiftY,mt=function(ro){return typeof ro=="boolean"?ro:ro>=0},ct,We,Ve,vt;cl();var Ie=mt(Ze),ze=ft[0]===it[0];if(Ie&&ft[0]==="t"&&(We>le.bottom||h.current.bt)){var Ke=Le;ze?Ke-=q-Z:Ke=Ae.y-Te.y-Pe;var at=un(Xe,Ke),Gt=un(Xe,Ke,oe);at>Re||at===Re&&(!ve||Gt>=be)?(h.current.bt=!0,Le=Ke,Pe=-Pe,He.points=[Mo(ft,0),Mo(it,0)]):h.current.bt=!1}if(Ie&&ft[0]==="b"&&(ctRe||Zt===Re&&(!ve||Jt>=be)?(h.current.tb=!0,Le=At,Pe=-Pe,He.points=[Mo(ft,0),Mo(it,0)]):h.current.tb=!1}var kn=mt(Ge),qn=ft[1]===it[1];if(kn&&ft[1]==="l"&&(vt>le.right||h.current.rl)){var pn=Xe;qn?pn-=ee-Q:pn=Ae.x-Te.x-ge;var Co=un(pn,Le),xo=un(pn,Le,oe);Co>Re||Co===Re&&(!ve||xo>=be)?(h.current.rl=!0,Xe=pn,ge=-ge,He.points=[Mo(ft,1),Mo(it,1)]):h.current.rl=!1}if(kn&&ft[1]==="r"&&(VeRe||wo===Re&&(!ve||wr>=be)?(h.current.lr=!0,Xe=In,ge=-ge,He.points=[Mo(ft,1),Mo(it,1)]):h.current.lr=!1}cl();var Bn=et===!0?0:et;typeof Bn=="number"&&(Veoe.right&&(Xe-=vt-oe.right-ge,M.x>oe.right-Bn&&(Xe+=M.x-oe.right+Bn)));var sr=ht===!0?0:ht;typeof sr=="number"&&(ctoe.bottom&&(Le-=We-oe.bottom-Pe,M.y>oe.bottom-sr&&(Le+=M.y-oe.bottom+sr)));var $r=A.x+Xe,Ur=$r+ee,Xn=A.y+Le,$o=Xn+q,Er=M.x,bt=Er+Q,dt=M.y,Fe=dt+Z,Ye=Math.max($r,Er),yt=Math.min(Ur,bt),Bt=(Ye+yt)/2,It=Bt-$r,Kt=Math.max(Xn,dt),sn=Math.min($o,Fe),Pn=(Kt+sn)/2,cn=Pn-Xn;a==null||a(t,He);var Tn=Ce.right-A.x-(Xe+A.width),jn=Ce.bottom-A.y-(Le+A.height);u({ready:!0,offsetX:Xe/ce,offsetY:Le/de,offsetR:Tn/ce,offsetB:jn/de,arrowX:It/ce,arrowY:cn/de,scaleX:ce,scaleY:de,align:He})}}),b=function(){d.current+=1;var S=d.current;Promise.resolve().then(function(){d.current===S&&p()})},m=function(){u(function(S){return U(U({},S),{},{ready:!1})})};return Nt(m,[r]),Nt(function(){e||m()},[e]),[c.ready,c.offsetX,c.offsetY,c.offsetR,c.offsetB,c.arrowX,c.arrowY,c.scaleX,c.scaleY,c.align,b]}function NA(e,t,n,r,o){Nt(function(){if(e&&t&&n){let v=function(){r(),o()};var d=v,i=t,a=n,l=yg(i),s=yg(a),c=qs(a),u=new Set([c].concat(Oe(l),Oe(s)));return u.forEach(function(h){h.addEventListener("scroll",v,{passive:!0})}),c.addEventListener("resize",v,{passive:!0}),r(),function(){u.forEach(function(h){h.removeEventListener("scroll",v),c.removeEventListener("resize",v)})}}},[e,t,n])}function _A(e,t,n,r,o,i,a,l){var s=f.exports.useRef(e),c=f.exports.useRef(!1);s.current!==e&&(c.current=!0,s.current=e),f.exports.useEffect(function(){var u=St(function(){c.current=!1});return function(){St.cancel(u)}},[e]),f.exports.useEffect(function(){if(t&&r&&(!o||i)){var u=function(){var E=!1,w=function(N){var I=N.target;E=a(I)},R=function(N){var I=N.target;!c.current&&s.current&&!E&&!a(I)&&l(!1)};return[w,R]},d=u(),v=G(d,2),h=v[0],g=v[1],p=u(),b=G(p,2),m=b[0],y=b[1],S=qs(r);S.addEventListener("mousedown",h,!0),S.addEventListener("click",g,!0),S.addEventListener("contextmenu",g,!0);var x=Hu(n);return x&&(x.addEventListener("mousedown",m,!0),x.addEventListener("click",y,!0),x.addEventListener("contextmenu",y,!0)),function(){S.removeEventListener("mousedown",h,!0),S.removeEventListener("click",g,!0),S.removeEventListener("contextmenu",g,!0),x&&(x.removeEventListener("mousedown",m,!0),x.removeEventListener("click",y,!0),x.removeEventListener("contextmenu",y,!0))}}},[t,n,r,o,i])}var AA=["prefixCls","children","action","showAction","hideAction","popupVisible","defaultPopupVisible","onPopupVisibleChange","afterPopupVisibleChange","mouseEnterDelay","mouseLeaveDelay","focusDelay","blurDelay","mask","maskClosable","getPopupContainer","forceRender","autoDestroy","destroyPopupOnHide","popup","popupClassName","popupStyle","popupPlacement","builtinPlacements","popupAlign","zIndex","stretch","getPopupClassNameFromAlign","fresh","alignPoint","onPopupClick","onPopupAlign","arrow","popupMotion","maskMotion","popupTransitionName","popupAnimation","maskTransitionName","maskAnimation","className","getTriggerDOMNode"];function DA(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:nf,t=f.exports.forwardRef(function(n,r){var o=n.prefixCls,i=o===void 0?"rc-trigger-popup":o,a=n.children,l=n.action,s=l===void 0?"hover":l,c=n.showAction,u=n.hideAction,d=n.popupVisible,v=n.defaultPopupVisible,h=n.onPopupVisibleChange,g=n.afterPopupVisibleChange,p=n.mouseEnterDelay,b=n.mouseLeaveDelay,m=b===void 0?.1:b,y=n.focusDelay,S=n.blurDelay,x=n.mask,$=n.maskClosable,E=$===void 0?!0:$,w=n.getPopupContainer,R=n.forceRender,P=n.autoDestroy,N=n.destroyPopupOnHide,I=n.popup,z=n.popupClassName,F=n.popupStyle,T=n.popupPlacement,D=n.builtinPlacements,_=D===void 0?{}:D,O=n.popupAlign,M=n.zIndex,L=n.stretch,A=n.getPopupClassNameFromAlign,B=n.fresh,k=n.alignPoint,j=n.onPopupClick,H=n.onPopupAlign,W=n.arrow,Y=n.popupMotion,K=n.maskMotion,q=n.popupTransitionName,ee=n.popupAnimation,Z=n.maskTransitionName,Q=n.maskAnimation,ne=n.className,ae=n.getTriggerDOMNode,J=Je(n,AA),re=P||N||!1,fe=f.exports.useState(!1),ve=G(fe,2),pe=ve[0],oe=ve[1];Nt(function(){oe(am())},[]);var se=f.exports.useRef({}),le=f.exports.useContext(mb),Ce=f.exports.useMemo(function(){return{registerSubPopup:function(tt,Vt){se.current[tt]=Vt,le==null||le.registerSubPopup(tt,Vt)}}},[le]),ce=Rw(),de=f.exports.useState(null),xe=G(de,2),he=xe[0],ke=xe[1],we=hn(function(je){Wu(je)&&he!==je&&ke(je),le==null||le.registerSubPopup(ce,je)}),ge=f.exports.useState(null),Pe=G(ge,2),Se=Pe[0],st=Pe[1],nt=f.exports.useRef(null),Ne=hn(function(je){Wu(je)&&Se!==je&&(st(je),nt.current=je)}),Ee=f.exports.Children.only(a),_e=(Ee==null?void 0:Ee.props)||{},Be={},qe=hn(function(je){var tt,Vt,nn=Se;return(nn==null?void 0:nn.contains(je))||((tt=Hu(nn))===null||tt===void 0?void 0:tt.host)===je||je===nn||(he==null?void 0:he.contains(je))||((Vt=Hu(he))===null||Vt===void 0?void 0:Vt.host)===je||je===he||Object.values(se.current).some(function(Ut){return(Ut==null?void 0:Ut.contains(je))||je===Ut})}),it=bb(i,Y,ee,q),ft=bb(i,K,Q,Z),ut=f.exports.useState(v||!1),Ue=G(ut,2),He=Ue[0],Xe=Ue[1],Le=d!=null?d:He,Re=hn(function(je){d===void 0&&Xe(je)});Nt(function(){Xe(d||!1)},[d]);var be=f.exports.useRef(Le);be.current=Le;var Ae=f.exports.useRef([]);Ae.current=[];var Me=hn(function(je){var tt;Re(je),((tt=Ae.current[Ae.current.length-1])!==null&&tt!==void 0?tt:Le)!==je&&(Ae.current.push(je),h==null||h(je))}),$e=f.exports.useRef(),Te=function(){clearTimeout($e.current)},ye=function(tt){var Vt=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;Te(),Vt===0?Me(tt):$e.current=setTimeout(function(){Me(tt)},Vt*1e3)};f.exports.useEffect(function(){return Te},[]);var Ge=f.exports.useState(!1),Ze=G(Ge,2),et=Ze[0],ht=Ze[1];Nt(function(je){(!je||Le)&&ht(!0)},[Le]);var mt=f.exports.useState(null),ct=G(mt,2),We=ct[0],Ve=ct[1],vt=f.exports.useState([0,0]),Ie=G(vt,2),ze=Ie[0],Ke=Ie[1],at=function(tt){Ke([tt.clientX,tt.clientY])},Gt=TA(Le,he,k?ze:Se,T,_,O,H),At=G(Gt,11),Zt=At[0],Jt=At[1],kn=At[2],qn=At[3],pn=At[4],Co=At[5],xo=At[6],In=At[7],wo=At[8],wr=At[9],Bn=At[10],sr=RA(pe,s,c,u),$r=G(sr,2),Ur=$r[0],Xn=$r[1],$o=Ur.has("click"),Er=Xn.has("click")||Xn.has("contextMenu"),bt=hn(function(){et||Bn()}),dt=function(){be.current&&k&&Er&&ye(!1)};NA(Le,Se,he,bt,dt),Nt(function(){bt()},[ze,T]),Nt(function(){Le&&!(_!=null&&_[T])&&bt()},[JSON.stringify(O)]);var Fe=f.exports.useMemo(function(){var je=PA(_,i,wr,k);return te(je,A==null?void 0:A(wr))},[wr,A,_,i,k]);f.exports.useImperativeHandle(r,function(){return{nativeElement:nt.current,forceAlign:bt}});var Ye=f.exports.useState(0),yt=G(Ye,2),Bt=yt[0],It=yt[1],Kt=f.exports.useState(0),sn=G(Kt,2),Pn=sn[0],cn=sn[1],Tn=function(){if(L&&Se){var tt=Se.getBoundingClientRect();It(tt.width),cn(tt.height)}},jn=function(){Tn(),bt()},Wi=function(tt){ht(!1),Bn(),g==null||g(tt)},iE=function(){return new Promise(function(tt){Tn(),Ve(function(){return tt})})};Nt(function(){We&&(Bn(),We(),Ve(null))},[We]);function un(je,tt,Vt,nn){Be[je]=function(Ut){var nc;nn==null||nn(Ut),ye(tt,Vt);for(var xf=arguments.length,km=new Array(xf>1?xf-1:0),rc=1;rc1?Vt-1:0),Ut=1;Ut1?Vt-1:0),Ut=1;Ut1&&arguments[1]!==void 0?arguments[1]:{},n=t.fieldNames,r=t.childrenAsData,o=[],i=Gw(n,!1),a=i.label,l=i.value,s=i.options,c=i.groupLabel;function u(d,v){!Array.isArray(d)||d.forEach(function(h){if(v||!(s in h)){var g=h[l];o.push({key:$b(h,o.length),groupOption:v,data:h,label:h[a],value:g})}else{var p=h[c];p===void 0&&r&&(p=h.label),o.push({key:$b(h,o.length),group:!0,data:h,label:p}),u(h[s],!0)}})}return u(e,!1),o}function bg(e){var t=U({},e);return"props"in t||Object.defineProperty(t,"props",{get:function(){return Mn(!1,"Return type is option instead of Option instance. Please read value directly instead of reading from `props`."),t}}),t}var jA=function(t,n,r){if(!n||!n.length)return null;var o=!1,i=function l(s,c){var u=kx(c),d=u[0],v=u.slice(1);if(!d)return[s];var h=s.split(d);return o=o||h.length>1,h.reduce(function(g,p){return[].concat(Oe(g),Oe(l(p,v)))},[]).filter(Boolean)},a=i(t,n);return o?typeof r<"u"?a.slice(0,r):a:null},lm=f.exports.createContext(null),HA=["id","prefixCls","className","showSearch","tagRender","direction","omitDomProps","displayValues","onDisplayValuesChange","emptyOptions","notFoundContent","onClear","mode","disabled","loading","getInputElement","getRawInputElement","open","defaultOpen","onDropdownVisibleChange","activeValue","onActiveValueChange","activeDescendantId","searchValue","autoClearSearchValue","onSearch","onSearchSplit","tokenSeparators","allowClear","suffixIcon","clearIcon","OptionList","animation","transitionName","dropdownStyle","dropdownClassName","dropdownMatchSelectWidth","dropdownRender","dropdownAlign","placement","builtinPlacements","getPopupContainer","showAction","onFocus","onBlur","onKeyUp","onKeyDown","onMouseDown"],WA=["value","onChange","removeIcon","placeholder","autoFocus","maxTagCount","maxTagTextLength","maxTagPlaceholder","choiceTransitionName","onInputKeyDown","onPopupScroll","tabIndex"],Sg=function(t){return t==="tags"||t==="multiple"},VA=f.exports.forwardRef(function(e,t){var n,r,o=e.id,i=e.prefixCls,a=e.className,l=e.showSearch,s=e.tagRender,c=e.direction,u=e.omitDomProps,d=e.displayValues,v=e.onDisplayValuesChange,h=e.emptyOptions,g=e.notFoundContent,p=g===void 0?"Not Found":g,b=e.onClear,m=e.mode,y=e.disabled,S=e.loading,x=e.getInputElement,$=e.getRawInputElement,E=e.open,w=e.defaultOpen,R=e.onDropdownVisibleChange,P=e.activeValue,N=e.onActiveValueChange,I=e.activeDescendantId,z=e.searchValue,F=e.autoClearSearchValue,T=e.onSearch,D=e.onSearchSplit,_=e.tokenSeparators,O=e.allowClear,M=e.suffixIcon,L=e.clearIcon,A=e.OptionList,B=e.animation,k=e.transitionName,j=e.dropdownStyle,H=e.dropdownClassName,W=e.dropdownMatchSelectWidth,Y=e.dropdownRender,K=e.dropdownAlign,q=e.placement,ee=e.builtinPlacements,Z=e.getPopupContainer,Q=e.showAction,ne=Q===void 0?[]:Q,ae=e.onFocus,J=e.onBlur,re=e.onKeyUp,fe=e.onKeyDown,ve=e.onMouseDown,pe=Je(e,HA),oe=Sg(m),se=(l!==void 0?l:oe)||m==="combobox",le=U({},pe);WA.forEach(function(Fe){delete le[Fe]}),u==null||u.forEach(function(Fe){delete le[Fe]});var Ce=f.exports.useState(!1),ce=G(Ce,2),de=ce[0],xe=ce[1];f.exports.useEffect(function(){xe(am())},[]);var he=f.exports.useRef(null),ke=f.exports.useRef(null),we=f.exports.useRef(null),ge=f.exports.useRef(null),Pe=f.exports.useRef(null),Se=f.exports.useRef(!1),st=Z_(),nt=G(st,3),Ne=nt[0],Ee=nt[1],_e=nt[2];f.exports.useImperativeHandle(t,function(){var Fe,Ye;return{focus:(Fe=ge.current)===null||Fe===void 0?void 0:Fe.focus,blur:(Ye=ge.current)===null||Ye===void 0?void 0:Ye.blur,scrollTo:function(Bt){var It;return(It=Pe.current)===null||It===void 0?void 0:It.scrollTo(Bt)}}});var Be=f.exports.useMemo(function(){var Fe;if(m!=="combobox")return z;var Ye=(Fe=d[0])===null||Fe===void 0?void 0:Fe.value;return typeof Ye=="string"||typeof Ye=="number"?String(Ye):""},[z,m,d]),qe=m==="combobox"&&typeof x=="function"&&x()||null,it=typeof $=="function"&&$(),ft=Fi(ke,it==null||(n=it.props)===null||n===void 0?void 0:n.ref),ut=f.exports.useState(!1),Ue=G(ut,2),He=Ue[0],Xe=Ue[1];Nt(function(){Xe(!0)},[]);var Le=kt(!1,{defaultValue:w,value:E}),Re=G(Le,2),be=Re[0],Ae=Re[1],Me=He?be:!1,$e=!p&&h;(y||$e&&Me&&m==="combobox")&&(Me=!1);var Te=$e?!1:Me,ye=f.exports.useCallback(function(Fe){var Ye=Fe!==void 0?Fe:!Me;y||(Ae(Ye),Me!==Ye&&(R==null||R(Ye)))},[y,Me,Ae,R]),Ge=f.exports.useMemo(function(){return(_||[]).some(function(Fe){return[`
+`,`\r
+`].includes(Fe)})},[_]),Ze=f.exports.useContext(lm)||{},et=Ze.maxCount,ht=Ze.rawValues,mt=function(Ye,yt,Bt){if(!((ht==null?void 0:ht.size)>=et)){var It=!0,Kt=Ye;N==null||N(null);var sn=jA(Ye,_,et&&et-ht.size),Pn=Bt?null:sn;return m!=="combobox"&&Pn&&(Kt="",D==null||D(Pn),ye(!1),It=!1),T&&Be!==Kt&&T(Kt,{source:yt?"typing":"effect"}),It}},ct=function(Ye){!Ye||!Ye.trim()||T(Ye,{source:"submit"})};f.exports.useEffect(function(){!Me&&!oe&&m!=="combobox"&&mt("",!1,!1)},[Me]),f.exports.useEffect(function(){be&&y&&Ae(!1),y&&!Se.current&&Ee(!1)},[y]);var We=Bw(),Ve=G(We,2),vt=Ve[0],Ie=Ve[1],ze=function(Ye){var yt=vt(),Bt=Ye.which;if(Bt===ue.ENTER&&(m!=="combobox"&&Ye.preventDefault(),Me||ye(!0)),Ie(!!Be),Bt===ue.BACKSPACE&&!yt&&oe&&!Be&&d.length){for(var It=Oe(d),Kt=null,sn=It.length-1;sn>=0;sn-=1){var Pn=It[sn];if(!Pn.disabled){It.splice(sn,1),Kt=Pn;break}}Kt&&v(It,{type:"remove",values:[Kt]})}for(var cn=arguments.length,Tn=new Array(cn>1?cn-1:0),jn=1;jn1?yt-1:0),It=1;It1?sn-1:0),cn=1;cn0&&arguments[0]!==void 0?arguments[0]:!1;u();var g=function(){l.current.forEach(function(b,m){if(b&&b.offsetParent){var y=ql(b),S=y.offsetHeight;s.current.get(m)!==S&&s.current.set(m,y.offsetHeight)}}),a(function(b){return b+1})};h?g():c.current=St(g)}function v(h,g){var p=e(h),b=l.current.get(p);g?(l.current.set(p,g),d()):l.current.delete(p),!b!=!g&&(g?t==null||t(h):n==null||n(h))}return f.exports.useEffect(function(){return u},[]),[v,d,s.current,i]}var qA=10;function XA(e,t,n,r,o,i,a,l){var s=f.exports.useRef(),c=f.exports.useState(null),u=G(c,2),d=u[0],v=u[1];return Nt(function(){if(d&&d.times=0;T-=1){var D=o(t[T]),_=n.get(D);if(_===void 0){y=!0;break}if(F-=_,F<=0)break}switch($){case"top":x=w-b;break;case"bottom":x=R-m+b;break;default:{var O=e.current.scrollTop,M=O+m;wM&&(S="bottom")}}x!==null&&a(x),x!==d.lastTop&&(y=!0)}y&&v(U(U({},d),{},{times:d.times+1,targetAlign:S,lastTop:x}))}},[d,e.current]),function(h){if(h==null){l();return}if(St.cancel(s.current),typeof h=="number")a(h);else if(h&&Qe(h)==="object"){var g,p=h.align;"index"in h?g=h.index:g=t.findIndex(function(y){return o(y)===h.key});var b=h.offset,m=b===void 0?0:b;v({times:0,index:g,offset:m,originAlign:p})}}}function QA(e,t,n){var r=e.length,o=t.length,i,a;if(r===0&&o===0)return null;r"u"?"undefined":Qe(navigator))==="object"&&/Firefox/i.test(navigator.userAgent);const qw=function(e,t){var n=f.exports.useRef(!1),r=f.exports.useRef(null);function o(){clearTimeout(r.current),n.current=!0,r.current=setTimeout(function(){n.current=!1},50)}var i=f.exports.useRef({top:e,bottom:t});return i.current.top=e,i.current.bottom=t,function(a){var l=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,s=a<0&&i.current.top||a>0&&i.current.bottom;return l&&s?(clearTimeout(r.current),n.current=!1):(!s||n.current)&&o(),!n.current&&s}};function JA(e,t,n,r,o){var i=f.exports.useRef(0),a=f.exports.useRef(null),l=f.exports.useRef(null),s=f.exports.useRef(!1),c=qw(t,n);function u(b,m){St.cancel(a.current),i.current+=m,l.current=m,!c(m)&&(Ob||b.preventDefault(),a.current=St(function(){var y=s.current?10:1;o(i.current*y),i.current=0}))}function d(b,m){o(m,!0),Ob||b.preventDefault()}var v=f.exports.useRef(null),h=f.exports.useRef(null);function g(b){if(!!e){St.cancel(h.current),h.current=St(function(){v.current=null},2);var m=b.deltaX,y=b.deltaY,S=b.shiftKey,x=m,$=y;(v.current==="sx"||!v.current&&(S||!1)&&y&&!m)&&(x=y,$=0,v.current="sx");var E=Math.abs(x),w=Math.abs($);v.current===null&&(v.current=r&&E>w?"x":"y"),v.current==="y"?u(b,$):d(b,x)}}function p(b){!e||(s.current=b.detail===l.current)}return[g,p]}var e8=14/15;function t8(e,t,n){var r=f.exports.useRef(!1),o=f.exports.useRef(0),i=f.exports.useRef(null),a=f.exports.useRef(null),l,s=function(v){if(r.current){var h=Math.ceil(v.touches[0].pageY),g=o.current-h;o.current=h,n(g)&&v.preventDefault(),clearInterval(a.current),a.current=setInterval(function(){g*=e8,(!n(g,!0)||Math.abs(g)<=.1)&&clearInterval(a.current)},16)}},c=function(){r.current=!1,l()},u=function(v){l(),v.touches.length===1&&!r.current&&(r.current=!0,o.current=Math.ceil(v.touches[0].pageY),i.current=v.target,i.current.addEventListener("touchmove",s),i.current.addEventListener("touchend",c))};l=function(){i.current&&(i.current.removeEventListener("touchmove",s),i.current.removeEventListener("touchend",c))},Nt(function(){return e&&t.current.addEventListener("touchstart",u),function(){var d;(d=t.current)===null||d===void 0||d.removeEventListener("touchstart",u),l(),clearInterval(a.current)}},[e])}var n8=20;function Rb(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=e/t*e;return isNaN(n)&&(n=0),n=Math.max(n,n8),Math.floor(n)}function r8(e,t,n,r){var o=f.exports.useMemo(function(){return[new Map,[]]},[e,n.id,r]),i=G(o,2),a=i[0],l=i[1],s=function(u){var d=arguments.length>1&&arguments[1]!==void 0?arguments[1]:u,v=a.get(u),h=a.get(d);if(v===void 0||h===void 0)for(var g=e.length,p=l.length;pi||!!p),I=g==="rtl",z=te(r,V({},"".concat(r,"-rtl"),I),o),F=u||i8,T=f.exports.useRef(),D=f.exports.useRef(),_=f.exports.useState(0),O=G(_,2),M=O[0],L=O[1],A=f.exports.useState(0),B=G(A,2),k=B[0],j=B[1],H=f.exports.useState(!1),W=G(H,2),Y=W[0],K=W[1],q=function(){K(!0)},ee=function(){K(!1)},Z=f.exports.useCallback(function(Ie){return typeof v=="function"?v(Ie):Ie==null?void 0:Ie[v]},[v]),Q={getKey:Z};function ne(Ie){L(function(ze){var Ke;typeof Ie=="function"?Ke=Ie(ze):Ke=Ie;var at=ft(Ke);return T.current.scrollTop=at,at})}var ae=f.exports.useRef({start:0,end:F.length}),J=f.exports.useRef(),re=ZA(F,Z),fe=G(re,1),ve=fe[0];J.current=ve;var pe=KA(Z,null,null),oe=G(pe,4),se=oe[0],le=oe[1],Ce=oe[2],ce=oe[3],de=f.exports.useMemo(function(){if(!P)return{scrollHeight:void 0,start:0,end:F.length-1,offset:void 0};if(!N){var Ie;return{scrollHeight:((Ie=D.current)===null||Ie===void 0?void 0:Ie.offsetHeight)||0,start:0,end:F.length-1,offset:void 0}}for(var ze=0,Ke,at,Gt,At=F.length,Zt=0;Zt=M&&Ke===void 0&&(Ke=Zt,at=ze),pn>M+i&&Gt===void 0&&(Gt=Zt),ze=pn}return Ke===void 0&&(Ke=0,at=0,Gt=Math.ceil(i/a)),Gt===void 0&&(Gt=F.length-1),Gt=Math.min(Gt+1,F.length-1),{scrollHeight:ze,start:Ke,end:Gt,offset:at}},[N,P,M,F,ce,i]),xe=de.scrollHeight,he=de.start,ke=de.end,we=de.offset;ae.current.start=he,ae.current.end=ke;var ge=f.exports.useState({width:0,height:i}),Pe=G(ge,2),Se=Pe[0],st=Pe[1],nt=function(ze){st({width:ze.width||ze.offsetWidth,height:ze.height||ze.offsetHeight})},Ne=f.exports.useRef(),Ee=f.exports.useRef(),_e=f.exports.useMemo(function(){return Rb(Se.width,p)},[Se.width,p]),Be=f.exports.useMemo(function(){return Rb(Se.height,xe)},[Se.height,xe]),qe=xe-i,it=f.exports.useRef(qe);it.current=qe;function ft(Ie){var ze=Ie;return Number.isNaN(it.current)||(ze=Math.min(ze,it.current)),ze=Math.max(ze,0),ze}var ut=M<=0,Ue=M>=qe,He=qw(ut,Ue),Xe=function(){return{x:I?-k:k,y:M}},Le=f.exports.useRef(Xe()),Re=hn(function(){if(S){var Ie=Xe();(Le.current.x!==Ie.x||Le.current.y!==Ie.y)&&(S(Ie),Le.current=Ie)}});function be(Ie,ze){var Ke=Ie;ze?(Gn.exports.flushSync(function(){j(Ke)}),Re()):ne(Ke)}function Ae(Ie){var ze=Ie.currentTarget.scrollTop;ze!==M&&ne(ze),y==null||y(Ie),Re()}var Me=function(ze){var Ke=ze,at=p-Se.width;return Ke=Math.max(Ke,0),Ke=Math.min(Ke,at),Ke},$e=hn(function(Ie,ze){ze?(Gn.exports.flushSync(function(){j(function(Ke){var at=Ke+(I?-Ie:Ie);return Me(at)})}),Re()):ne(function(Ke){var at=Ke+Ie;return at})}),Te=JA(P,ut,Ue,!!p,$e),ye=G(Te,2),Ge=ye[0],Ze=ye[1];t8(P,T,function(Ie,ze){return He(Ie,ze)?!1:(Ge({preventDefault:function(){},deltaY:Ie}),!0)}),Nt(function(){function Ie(Ke){P&&Ke.preventDefault()}var ze=T.current;return ze.addEventListener("wheel",Ge),ze.addEventListener("DOMMouseScroll",Ze),ze.addEventListener("MozMousePixelScroll",Ie),function(){ze.removeEventListener("wheel",Ge),ze.removeEventListener("DOMMouseScroll",Ze),ze.removeEventListener("MozMousePixelScroll",Ie)}},[P]),Nt(function(){p&&j(function(Ie){return Me(Ie)})},[Se.width,p]);var et=function(){var ze,Ke;(ze=Ne.current)===null||ze===void 0||ze.delayHidden(),(Ke=Ee.current)===null||Ke===void 0||Ke.delayHidden()},ht=XA(T,F,Ce,a,Z,function(){return le(!0)},ne,et);f.exports.useImperativeHandle(t,function(){return{getScrollInfo:Xe,scrollTo:function(ze){function Ke(at){return at&&Qe(at)==="object"&&("left"in at||"top"in at)}Ke(ze)?(ze.left!==void 0&&j(Me(ze.left)),ht(ze.top)):ht(ze)}}}),Nt(function(){if(x){var Ie=F.slice(he,ke+1);x(Ie,F)}},[he,ke,F]);var mt=r8(F,Z,Ce,a),ct=E==null?void 0:E({start:he,end:ke,virtual:N,offsetX:k,offsetY:we,rtl:I,getSize:mt}),We=YA(F,he,ke,p,se,d,Q),Ve=null;i&&(Ve=U(V({},s?"height":"maxHeight",i),a8),P&&(Ve.overflowY="hidden",p&&(Ve.overflowX="hidden"),Y&&(Ve.pointerEvents="none")));var vt={};return I&&(vt.dir="rtl"),ie("div",{style:U(U({},c),{},{position:"relative"}),className:z,...vt,...R,children:[C(mr,{onResize:nt,children:C(m,{className:"".concat(r,"-holder"),style:Ve,ref:T,onScroll:Ae,onMouseEnter:et,children:C(Kw,{prefixCls:r,height:xe,offsetX:k,offsetY:we,scrollWidth:p,onInnerResize:le,ref:D,innerProps:$,rtl:I,extra:ct,children:We})})}),N&&xe>i&&C(Mb,{ref:Ne,prefixCls:r,scrollOffset:M,scrollRange:xe,rtl:I,onScroll:be,onStartMove:q,onStopMove:ee,spinSize:Be,containerSize:Se.height,style:w==null?void 0:w.verticalScrollBar,thumbStyle:w==null?void 0:w.verticalScrollBarThumb}),N&&p>Se.width&&C(Mb,{ref:Ee,prefixCls:r,scrollOffset:k,scrollRange:p,rtl:I,onScroll:be,onStartMove:q,onStopMove:ee,spinSize:_e,containerSize:Se.width,horizontal:!0,style:w==null?void 0:w.horizontalScrollBar,thumbStyle:w==null?void 0:w.horizontalScrollBarThumb})]})}var Xw=f.exports.forwardRef(l8);Xw.displayName="List";function s8(){return/(mac\sos|macintosh)/i.test(navigator.appVersion)}var c8=["disabled","title","children","style","className"];function Ib(e){return typeof e=="string"||typeof e=="number"}var u8=function(t,n){var r=Q_(),o=r.prefixCls,i=r.id,a=r.open,l=r.multiple,s=r.mode,c=r.searchValue,u=r.toggleOpen,d=r.notFoundContent,v=r.onPopupScroll,h=f.exports.useContext(lm),g=h.maxCount,p=h.flattenOptions,b=h.onActiveValue,m=h.defaultActiveFirstOption,y=h.onSelect,S=h.menuItemSelectedIcon,x=h.rawValues,$=h.fieldNames,E=h.virtual,w=h.direction,R=h.listHeight,P=h.listItemHeight,N=h.optionRender,I="".concat(o,"-item"),z=Hs(function(){return p},[a,p],function(Z,Q){return Q[0]&&Z[1]!==Q[1]}),F=f.exports.useRef(null),T=f.exports.useMemo(function(){return l&&typeof g<"u"&&(x==null?void 0:x.size)>=g},[l,g,x==null?void 0:x.size]),D=function(Q){Q.preventDefault()},_=function(Q){var ne;(ne=F.current)===null||ne===void 0||ne.scrollTo(typeof Q=="number"?{index:Q}:Q)},O=function(Q){for(var ne=arguments.length>1&&arguments[1]!==void 0?arguments[1]:1,ae=z.length,J=0;J1&&arguments[1]!==void 0?arguments[1]:!1;B(Q);var ae={source:ne?"keyboard":"mouse"},J=z[Q];if(!J){b(null,-1,ae);return}b(J.value,Q,ae)};f.exports.useEffect(function(){k(m!==!1?O(0):-1)},[z.length,c]);var j=f.exports.useCallback(function(Z){return x.has(Z)&&s!=="combobox"},[s,Oe(x).toString(),x.size]);f.exports.useEffect(function(){var Z=setTimeout(function(){if(!l&&a&&x.size===1){var ne=Array.from(x)[0],ae=z.findIndex(function(J){var re=J.data;return re.value===ne});ae!==-1&&(k(ae),_(ae))}});if(a){var Q;(Q=F.current)===null||Q===void 0||Q.scrollTo(void 0)}return function(){return clearTimeout(Z)}},[a,c]);var H=function(Q){Q!==void 0&&y(Q,{selected:!x.has(Q)}),l||u(!1)};if(f.exports.useImperativeHandle(n,function(){return{onKeyDown:function(Q){var ne=Q.which,ae=Q.ctrlKey;switch(ne){case ue.N:case ue.P:case ue.UP:case ue.DOWN:{var J=0;if(ne===ue.UP?J=-1:ne===ue.DOWN?J=1:s8()&&ae&&(ne===ue.N?J=1:ne===ue.P&&(J=-1)),J!==0){var re=O(A+J,J);_(re),k(re,!0)}break}case ue.ENTER:{var fe,ve=z[A];ve&&!(ve!=null&&(fe=ve.data)!==null&&fe!==void 0&&fe.disabled)&&!T?H(ve.value):H(void 0),a&&Q.preventDefault();break}case ue.ESC:u(!1),a&&Q.stopPropagation()}},onKeyUp:function(){},scrollTo:function(Q){_(Q)}}}),z.length===0)return C("div",{role:"listbox",id:"".concat(i,"_list"),className:"".concat(I,"-empty"),onMouseDown:D,children:d});var W=Object.keys($).map(function(Z){return $[Z]}),Y=function(Q){return Q.label};function K(Z,Q){var ne=Z.group;return{role:ne?"presentation":"option",id:"".concat(i,"_list_").concat(Q)}}var q=function(Q){var ne=z[Q];if(!ne)return null;var ae=ne.data||{},J=ae.value,re=ne.group,fe=Ka(ae,!0),ve=Y(ne);return ne?f.exports.createElement("div",{"aria-label":typeof ve=="string"&&!re?ve:null,...fe,key:Q,...K(ne,Q),"aria-selected":j(J)},J):null},ee={role:"listbox",id:"".concat(i,"_list")};return ie(Tt,{children:[E&&ie("div",{...ee,style:{height:0,width:0,overflow:"hidden"},children:[q(A-1),q(A),q(A+1)]}),C(Xw,{itemKey:"key",ref:F,data:z,height:R,itemHeight:P,fullHeight:!1,onMouseDown:D,onScroll:v,virtual:E,direction:w,innerProps:E?null:ee,children:function(Z,Q){var ne,ae=Z.group,J=Z.groupOption,re=Z.data,fe=Z.label,ve=Z.value,pe=re.key;if(ae){var oe,se=(oe=re.title)!==null&&oe!==void 0?oe:Ib(fe)?fe.toString():void 0;return C("div",{className:te(I,"".concat(I,"-group")),title:se,children:fe!==void 0?fe:pe})}var le=re.disabled,Ce=re.title;re.children;var ce=re.style,de=re.className,xe=Je(re,c8),he=lr(xe,W),ke=j(ve),we=le||!ke&&T,ge="".concat(I,"-option"),Pe=te(I,ge,de,(ne={},V(ne,"".concat(ge,"-grouped"),J),V(ne,"".concat(ge,"-active"),A===Q&&!we),V(ne,"".concat(ge,"-disabled"),we),V(ne,"".concat(ge,"-selected"),ke),ne)),Se=Y(Z),st=!S||typeof S=="function"||ke,nt=typeof Se=="number"?Se:Se||ve,Ne=Ib(nt)?nt.toString():void 0;return Ce!==void 0&&(Ne=Ce),ie("div",{...Ka(he),...E?{}:K(Z,Q),"aria-selected":ke,className:Pe,title:Ne,onMouseMove:function(){A===Q||we||k(Q)},onClick:function(){we||H(ve)},style:ce,children:[C("div",{className:"".concat(ge,"-content"),children:typeof N=="function"?N(Z,{index:Q}):nt}),f.exports.isValidElement(S)||ke,st&&C(af,{className:"".concat(I,"-option-state"),customizeIcon:S,customizeIconProps:{value:ve,disabled:we,isSelected:ke},children:ke?"\u2713":null})]})}})]})},d8=f.exports.forwardRef(u8);const f8=function(e,t){var n=f.exports.useRef({values:new Map,options:new Map}),r=f.exports.useMemo(function(){var i=n.current,a=i.values,l=i.options,s=e.map(function(d){if(d.label===void 0){var v;return U(U({},d),{},{label:(v=a.get(d.value))===null||v===void 0?void 0:v.label})}return d}),c=new Map,u=new Map;return s.forEach(function(d){c.set(d.value,d),u.set(d.value,t.get(d.value)||l.get(d.value))}),n.current.values=c,n.current.options=u,s},[e,t]),o=f.exports.useCallback(function(i){return t.get(i)||n.current.options.get(i)},[t]);return[r,o]};function gv(e,t){return Uw(e).join("").toUpperCase().includes(t)}const v8=function(e,t,n,r,o){return f.exports.useMemo(function(){if(!n||r===!1)return e;var i=t.options,a=t.label,l=t.value,s=[],c=typeof r=="function",u=n.toUpperCase(),d=c?r:function(h,g){return o?gv(g[o],u):g[i]?gv(g[a!=="children"?a:"label"],u):gv(g[l],u)},v=c?function(h){return bg(h)}:function(h){return h};return e.forEach(function(h){if(h[i]){var g=d(n,v(h));if(g)s.push(h);else{var p=h[i].filter(function(b){return d(n,v(b))});p.length&&s.push(U(U({},h),{},V({},i,p)))}return}d(n,v(h))&&s.push(h)}),s},[e,r,o,n,t])};var Pb=0,p8=Rn();function g8(){var e;return p8?(e=Pb,Pb+=1):e="TEST_OR_SSR",e}function h8(e){var t=f.exports.useState(),n=G(t,2),r=n[0],o=n[1];return f.exports.useEffect(function(){o("rc_select_".concat(g8()))},[]),e||r}var m8=["children","value"],y8=["children"];function b8(e){var t=e,n=t.key,r=t.props,o=r.children,i=r.value,a=Je(r,m8);return U({key:n,value:i!==void 0?i:n,children:o},a)}function Qw(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;return Qo(e).map(function(n,r){if(!f.exports.isValidElement(n)||!n.type)return null;var o=n,i=o.type.isSelectOptGroup,a=o.key,l=o.props,s=l.children,c=Je(l,y8);return t||!i?b8(n):U(U({key:"__RC_SELECT_GRP__".concat(a===null?r:a,"__"),label:a},c),{},{options:Qw(s)})}).filter(function(n){return n})}var S8=function(t,n,r,o,i){return f.exports.useMemo(function(){var a=t,l=!t;l&&(a=Qw(n));var s=new Map,c=new Map,u=function(h,g,p){p&&typeof p=="string"&&h.set(g[p],g)},d=function v(h){for(var g=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,p=0;p2&&arguments[2]!==void 0?arguments[2]:{},Ge=ye.source,Ze=Ge===void 0?"keyboard":Ge;ut(Te),a&&r==="combobox"&&$e!==null&&Ze==="keyboard"&&Be(String($e))},[a,r]),Xe=function(Te,ye,Ge){var Ze=function(){var Ke,at=de(Te);return[M?{label:at==null?void 0:at[Y.label],value:Te,key:(Ke=at==null?void 0:at.key)!==null&&Ke!==void 0?Ke:Te}:Te,bg(at)]};if(ye&&h){var et=Ze(),ht=G(et,2),mt=ht[0],ct=ht[1];h(mt,ct)}else if(!ye&&g&&Ge!=="clear"){var We=Ze(),Ve=G(We,2),vt=Ve[0],Ie=Ve[1];g(vt,Ie)}},Le=Tb(function($e,Te){var ye,Ge=j?Te.selected:!0;Ge?ye=j?[].concat(Oe(ce),[$e]):[$e]:ye=ce.filter(function(Ze){return Ze.value!==$e}),nt(ye),Xe($e,Ge),r==="combobox"?Be(""):(!Sg||v)&&(Z(""),Be(""))}),Re=function(Te,ye){nt(Te);var Ge=ye.type,Ze=ye.values;(Ge==="remove"||Ge==="clear")&&Ze.forEach(function(et){Xe(et.value,!1,Ge)})},be=function(Te,ye){if(Z(Te),Be(null),ye.source==="submit"){var Ge=(Te||"").trim();if(Ge){var Ze=Array.from(new Set([].concat(Oe(he),[Ge])));nt(Ze),Xe(Ge,!0),Z("")}return}ye.source!=="blur"&&(r==="combobox"&&nt(Te),u==null||u(Te))},Ae=function(Te){var ye=Te;r!=="tags"&&(ye=Te.map(function(Ze){var et=ae.get(Ze);return et==null?void 0:et.value}).filter(function(Ze){return Ze!==void 0}));var Ge=Array.from(new Set([].concat(Oe(he),Oe(ye))));nt(Ge),Ge.forEach(function(Ze){Xe(Ze,!0)})},Me=f.exports.useMemo(function(){var $e=N!==!1&&b!==!1;return U(U({},Q),{},{flattenOptions:st,onActiveValue:He,defaultActiveFirstOption:Ue,onSelect:Le,menuItemSelectedIcon:P,rawValues:he,fieldNames:Y,virtual:$e,direction:I,listHeight:F,listItemHeight:D,childrenAsData:H,maxCount:A,optionRender:E})},[A,Q,st,He,Ue,Le,P,he,Y,N,b,I,F,D,H,E]);return C(lm.Provider,{value:Me,children:C(VA,{...B,id:k,prefixCls:i,ref:t,omitDomProps:x8,mode:r,displayValues:xe,onDisplayValuesChange:Re,direction:I,searchValue:ee,onSearch:be,autoClearSearchValue:v,onSearchSplit:Ae,dropdownMatchSelectWidth:b,OptionList:d8,emptyOptions:!st.length,activeValue:_e,activeDescendantId:"".concat(k,"_list_").concat(ft)})})}),um=$8;um.Option=cm;um.OptGroup=sm;function ed(e,t,n){return te({[`${e}-status-success`]:t==="success",[`${e}-status-warning`]:t==="warning",[`${e}-status-error`]:t==="error",[`${e}-status-validating`]:t==="validating",[`${e}-has-feedback`]:n})}const dm=(e,t)=>t||e,E8=()=>{const[,e]=Kn(),n=new Mt(e.colorBgBase).toHsl().l<.5?{opacity:.65}:{};return C("svg",{style:n,width:"184",height:"152",viewBox:"0 0 184 152",xmlns:"http://www.w3.org/2000/svg",children:ie("g",{fill:"none",fillRule:"evenodd",children:[ie("g",{transform:"translate(24 31.67)",children:[C("ellipse",{fillOpacity:".8",fill:"#F5F5F7",cx:"67.797",cy:"106.89",rx:"67.797",ry:"12.668"}),C("path",{d:"M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z",fill:"#AEB8C2"}),C("path",{d:"M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z",fill:"url(#linearGradient-1)",transform:"translate(13.56)"}),C("path",{d:"M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z",fill:"#F5F5F7"}),C("path",{d:"M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z",fill:"#DCE0E6"})]}),C("path",{d:"M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z",fill:"#DCE0E6"}),ie("g",{transform:"translate(149.65 15.383)",fill:"#FFF",children:[C("ellipse",{cx:"20.654",cy:"3.167",rx:"2.849",ry:"2.815"}),C("path",{d:"M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z"})]})]})})},M8=E8,O8=()=>{const[,e]=Kn(),{colorFill:t,colorFillTertiary:n,colorFillQuaternary:r,colorBgContainer:o}=e,{borderColor:i,shadowColor:a,contentColor:l}=f.exports.useMemo(()=>({borderColor:new Mt(t).onBackground(o).toHexShortString(),shadowColor:new Mt(n).onBackground(o).toHexShortString(),contentColor:new Mt(r).onBackground(o).toHexShortString()}),[t,n,r,o]);return C("svg",{width:"64",height:"41",viewBox:"0 0 64 41",xmlns:"http://www.w3.org/2000/svg",children:ie("g",{transform:"translate(0 1)",fill:"none",fillRule:"evenodd",children:[C("ellipse",{fill:a,cx:"32",cy:"33",rx:"32",ry:"7"}),ie("g",{fillRule:"nonzero",stroke:i,children:[C("path",{d:"M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"}),C("path",{d:"M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z",fill:l})]})]})})},R8=O8,I8=e=>{const{componentCls:t,margin:n,marginXS:r,marginXL:o,fontSize:i,lineHeight:a}=e;return{[t]:{marginInline:r,fontSize:i,lineHeight:a,textAlign:"center",[`${t}-image`]:{height:e.emptyImgHeight,marginBottom:r,opacity:e.opacityImage,img:{height:"100%"},svg:{maxWidth:"100%",height:"100%",margin:"auto"}},[`${t}-description`]:{color:e.colorText},[`${t}-footer`]:{marginTop:n},"&-normal":{marginBlock:o,color:e.colorTextDisabled,[`${t}-description`]:{color:e.colorTextDisabled},[`${t}-image`]:{height:e.emptyImgHeightMD}},"&-small":{marginBlock:r,color:e.colorTextDisabled,[`${t}-image`]:{height:e.emptyImgHeightSM}}}}},P8=vn("Empty",e=>{const{componentCls:t,controlHeightLG:n,calc:r}=e,o=$t(e,{emptyImgCls:`${t}-img`,emptyImgHeight:r(n).mul(2.5).equal(),emptyImgHeightMD:n,emptyImgHeightSM:r(n).mul(.875).equal()});return[I8(o)]});var T8=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var{className:t,rootClassName:n,prefixCls:r,image:o=Zw,description:i,children:a,imageStyle:l,style:s}=e,c=T8(e,["className","rootClassName","prefixCls","image","description","children","imageStyle","style"]);const{getPrefixCls:u,direction:d,empty:v}=f.exports.useContext(ot),h=u("empty",r),[g,p,b]=P8(h),[m]=Wx("Empty"),y=typeof i<"u"?i:m==null?void 0:m.description,S=typeof y=="string"?y:"empty";let x=null;return typeof o=="string"?x=C("img",{alt:S,src:o}):x=o,g(ie("div",{...Object.assign({className:te(p,b,h,v==null?void 0:v.className,{[`${h}-normal`]:o===Jw,[`${h}-rtl`]:d==="rtl"},t,n),style:Object.assign(Object.assign({},v==null?void 0:v.style),s)},c),children:[C("div",{className:`${h}-image`,style:l,children:x}),y&&C("div",{className:`${h}-description`,children:y}),a&&C("div",{className:`${h}-footer`,children:a})]}))};fm.PRESENTED_IMAGE_DEFAULT=Zw;fm.PRESENTED_IMAGE_SIMPLE=Jw;const wl=fm,N8=e=>{const{componentName:t}=e,{getPrefixCls:n}=f.exports.useContext(ot),r=n("empty");switch(t){case"Table":case"List":return C(wl,{image:wl.PRESENTED_IMAGE_SIMPLE});case"Select":case"TreeSelect":case"Cascader":case"Transfer":case"Mentions":return C(wl,{image:wl.PRESENTED_IMAGE_SIMPLE,className:`${r}-small`});default:return C(wl,{})}},_8=N8,A8=["outlined","borderless","filled"],D8=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:void 0;const n=f.exports.useContext(v_);let r;typeof e<"u"?r=e:t===!1?r="borderless":r=n!=null?n:"outlined";const o=A8.includes(r);return[r,o]},vm=D8,L8=e=>{const n={overflow:{adjustX:!0,adjustY:!0,shiftY:!0},htmlRegion:e==="scroll"?"scroll":"visible",dynamicInset:!0};return{bottomLeft:Object.assign(Object.assign({},n),{points:["tl","bl"],offset:[0,4]}),bottomRight:Object.assign(Object.assign({},n),{points:["tr","br"],offset:[0,4]}),topLeft:Object.assign(Object.assign({},n),{points:["bl","tl"],offset:[0,-4]}),topRight:Object.assign(Object.assign({},n),{points:["br","tr"],offset:[0,-4]})}};function z8(e,t){return e||L8(t)}const Nb=e=>{const{optionHeight:t,optionFontSize:n,optionLineHeight:r,optionPadding:o}=e;return{position:"relative",display:"block",minHeight:t,padding:o,color:e.colorText,fontWeight:"normal",fontSize:n,lineHeight:r,boxSizing:"border-box"}},F8=e=>{const{antCls:t,componentCls:n}=e,r=`${n}-item`,o=`&${t}-slide-up-enter${t}-slide-up-enter-active`,i=`&${t}-slide-up-appear${t}-slide-up-appear-active`,a=`&${t}-slide-up-leave${t}-slide-up-leave-active`,l=`${n}-dropdown-placement-`;return[{[`${n}-dropdown`]:Object.assign(Object.assign({},Qt(e)),{position:"absolute",top:-9999,zIndex:e.zIndexPopup,boxSizing:"border-box",padding:e.paddingXXS,overflow:"hidden",fontSize:e.fontSize,fontVariant:"initial",backgroundColor:e.colorBgElevated,borderRadius:e.borderRadiusLG,outline:"none",boxShadow:e.boxShadowSecondary,[`
+ ${o}${l}bottomLeft,
+ ${i}${l}bottomLeft
+ `]:{animationName:nm},[`
+ ${o}${l}topLeft,
+ ${i}${l}topLeft,
+ ${o}${l}topRight,
+ ${i}${l}topRight
+ `]:{animationName:om},[`${a}${l}bottomLeft`]:{animationName:rm},[`
+ ${a}${l}topLeft,
+ ${a}${l}topRight
+ `]:{animationName:im},"&-hidden":{display:"none"},[`${r}`]:Object.assign(Object.assign({},Nb(e)),{cursor:"pointer",transition:`background ${e.motionDurationSlow} ease`,borderRadius:e.borderRadiusSM,"&-group":{color:e.colorTextDescription,fontSize:e.fontSizeSM,cursor:"default"},"&-option":{display:"flex","&-content":Object.assign({flex:"auto"},ei),"&-state":{flex:"none",display:"flex",alignItems:"center"},[`&-active:not(${r}-option-disabled)`]:{backgroundColor:e.optionActiveBg},[`&-selected:not(${r}-option-disabled)`]:{color:e.optionSelectedColor,fontWeight:e.optionSelectedFontWeight,backgroundColor:e.optionSelectedBg,[`${r}-option-state`]:{color:e.colorPrimary},[`&:has(+ ${r}-option-selected:not(${r}-option-disabled))`]:{borderEndStartRadius:0,borderEndEndRadius:0,[`& + ${r}-option-selected:not(${r}-option-disabled)`]:{borderStartStartRadius:0,borderStartEndRadius:0}}},"&-disabled":{[`&${r}-option-selected`]:{backgroundColor:e.colorBgContainerDisabled},color:e.colorTextDisabled,cursor:"not-allowed"},"&-grouped":{paddingInlineStart:e.calc(e.controlPaddingHorizontal).mul(2).equal()}},"&-empty":Object.assign(Object.assign({},Nb(e)),{color:e.colorTextDisabled})}),"&-rtl":{direction:"rtl"}})},Xa(e,"slide-up"),Xa(e,"slide-down"),Zu(e,"move-up"),Zu(e,"move-down")]},k8=F8,Qi=2,B8=e=>{const{multipleSelectItemHeight:t,selectHeight:n,lineWidth:r}=e;return e.calc(n).sub(t).div(2).sub(r).equal()},pm=(e,t)=>{const{componentCls:n,iconCls:r}=e,o=`${n}-selection-overflow`,i=e.multipleSelectItemHeight,a=B8(e),l=t?`${n}-${t}`:"";return{[`${n}-multiple${l}`]:{[o]:{position:"relative",display:"flex",flex:"auto",flexWrap:"wrap",maxWidth:"100%","&-item":{flex:"none",alignSelf:"center",maxWidth:"100%",display:"inline-flex"}},[`${n}-selector`]:{display:"flex",flexWrap:"wrap",alignItems:"center",height:"100%",paddingInline:e.calc(Qi).mul(2).equal(),paddingBlock:e.calc(a).sub(Qi).equal(),borderRadius:e.borderRadius,[`${n}-disabled&`]:{background:e.multipleSelectorBgDisabled,cursor:"not-allowed"},"&:after":{display:"inline-block",width:0,margin:`${X(Qi)} 0`,lineHeight:X(i),visibility:"hidden",content:'"\\a0"'}},[`${n}-selection-item`]:{display:"flex",alignSelf:"center",flex:"none",boxSizing:"border-box",maxWidth:"100%",height:i,marginTop:Qi,marginBottom:Qi,lineHeight:X(e.calc(i).sub(e.calc(e.lineWidth).mul(2)).equal()),borderRadius:e.borderRadiusSM,cursor:"default",transition:`font-size ${e.motionDurationSlow}, line-height ${e.motionDurationSlow}, height ${e.motionDurationSlow}`,marginInlineEnd:e.calc(Qi).mul(2).equal(),paddingInlineStart:e.paddingXS,paddingInlineEnd:e.calc(e.paddingXS).div(2).equal(),[`${n}-disabled&`]:{color:e.multipleItemColorDisabled,borderColor:e.multipleItemBorderColorDisabled,cursor:"not-allowed"},"&-content":{display:"inline-block",marginInlineEnd:e.calc(e.paddingXS).div(2).equal(),overflow:"hidden",whiteSpace:"pre",textOverflow:"ellipsis"},"&-remove":Object.assign(Object.assign({},Uh()),{display:"inline-flex",alignItems:"center",color:e.colorIcon,fontWeight:"bold",fontSize:10,lineHeight:"inherit",cursor:"pointer",[`> ${r}`]:{verticalAlign:"-0.2em"},"&:hover":{color:e.colorIconHover}})},[`${o}-item + ${o}-item`]:{[`${n}-selection-search`]:{marginInlineStart:0}},[`${o}-item-suffix`]:{height:"100%"},[`${n}-selection-search`]:{display:"inline-flex",position:"relative",maxWidth:"100%",marginInlineStart:e.calc(e.inputPaddingHorizontalBase).sub(a).equal(),[`
+ &-input,
+ &-mirror
+ `]:{height:i,fontFamily:e.fontFamily,lineHeight:X(i),transition:`all ${e.motionDurationSlow}`},"&-input":{width:"100%",minWidth:4.1},"&-mirror":{position:"absolute",top:0,insetInlineStart:0,insetInlineEnd:"auto",zIndex:999,whiteSpace:"pre",visibility:"hidden"}},[`${n}-selection-placeholder`]:{position:"absolute",top:"50%",insetInlineStart:e.inputPaddingHorizontalBase,insetInlineEnd:e.inputPaddingHorizontalBase,transform:"translateY(-50%)",transition:`all ${e.motionDurationSlow}`}}}};function hv(e,t){const{componentCls:n}=e,r=t?`${n}-${t}`:"",o={[`${n}-multiple${r}`]:{fontSize:e.fontSize,[`${n}-selector`]:{[`${n}-show-search&`]:{cursor:"text"}},[`
+ &${n}-show-arrow ${n}-selector,
+ &${n}-allow-clear ${n}-selector
+ `]:{paddingInlineEnd:e.calc(e.fontSizeIcon).add(e.controlPaddingHorizontal).equal()}}};return[pm(e,t),o]}const j8=e=>{const{componentCls:t}=e,n=$t(e,{selectHeight:e.controlHeightSM,multipleSelectItemHeight:e.controlHeightXS,borderRadius:e.borderRadiusSM,borderRadiusSM:e.borderRadiusXS}),r=$t(e,{fontSize:e.fontSizeLG,selectHeight:e.controlHeightLG,multipleSelectItemHeight:e.multipleItemHeightLG,borderRadius:e.borderRadiusLG,borderRadiusSM:e.borderRadius});return[hv(e),hv(n,"sm"),{[`${t}-multiple${t}-sm`]:{[`${t}-selection-placeholder`]:{insetInline:e.calc(e.controlPaddingHorizontalSM).sub(e.lineWidth).equal()},[`${t}-selection-search`]:{marginInlineStart:2}}},hv(r,"lg")]};function mv(e,t){const{componentCls:n,inputPaddingHorizontalBase:r,borderRadius:o}=e,i=e.calc(e.controlHeight).sub(e.calc(e.lineWidth).mul(2)).equal(),a=t?`${n}-${t}`:"";return{[`${n}-single${a}`]:{fontSize:e.fontSize,height:e.controlHeight,[`${n}-selector`]:Object.assign(Object.assign({},Qt(e,!0)),{display:"flex",borderRadius:o,[`${n}-selection-search`]:{position:"absolute",top:0,insetInlineStart:r,insetInlineEnd:r,bottom:0,"&-input":{width:"100%",WebkitAppearance:"textfield"}},[`
+ ${n}-selection-item,
+ ${n}-selection-placeholder
+ `]:{padding:0,lineHeight:X(i),transition:`all ${e.motionDurationSlow}, visibility 0s`,alignSelf:"center"},[`${n}-selection-placeholder`]:{transition:"none",pointerEvents:"none"},[["&:after",`${n}-selection-item:empty:after`,`${n}-selection-placeholder:empty:after`].join(",")]:{display:"inline-block",width:0,visibility:"hidden",content:'"\\a0"'}}),[`
+ &${n}-show-arrow ${n}-selection-item,
+ &${n}-show-arrow ${n}-selection-placeholder
+ `]:{paddingInlineEnd:e.showArrowPaddingInlineEnd},[`&${n}-open ${n}-selection-item`]:{color:e.colorTextPlaceholder},[`&:not(${n}-customize-input)`]:{[`${n}-selector`]:{width:"100%",height:"100%",padding:`0 ${X(r)}`,[`${n}-selection-search-input`]:{height:i},"&:after":{lineHeight:X(i)}}},[`&${n}-customize-input`]:{[`${n}-selector`]:{"&:after":{display:"none"},[`${n}-selection-search`]:{position:"static",width:"100%"},[`${n}-selection-placeholder`]:{position:"absolute",insetInlineStart:0,insetInlineEnd:0,padding:`0 ${X(r)}`,"&:after":{display:"none"}}}}}}}function H8(e){const{componentCls:t}=e,n=e.calc(e.controlPaddingHorizontalSM).sub(e.lineWidth).equal();return[mv(e),mv($t(e,{controlHeight:e.controlHeightSM,borderRadius:e.borderRadiusSM}),"sm"),{[`${t}-single${t}-sm`]:{[`&:not(${t}-customize-input)`]:{[`${t}-selection-search`]:{insetInlineStart:n,insetInlineEnd:n},[`${t}-selector`]:{padding:`0 ${X(n)}`},[`&${t}-show-arrow ${t}-selection-search`]:{insetInlineEnd:e.calc(n).add(e.calc(e.fontSize).mul(1.5)).equal()},[`
+ &${t}-show-arrow ${t}-selection-item,
+ &${t}-show-arrow ${t}-selection-placeholder
+ `]:{paddingInlineEnd:e.calc(e.fontSize).mul(1.5).equal()}}}},mv($t(e,{controlHeight:e.singleItemHeightLG,fontSize:e.fontSizeLG,borderRadius:e.borderRadiusLG}),"lg")]}const W8=e=>{const{fontSize:t,lineHeight:n,controlHeight:r,controlPaddingHorizontal:o,zIndexPopupBase:i,colorText:a,fontWeightStrong:l,controlItemBgActive:s,controlItemBgHover:c,colorBgContainer:u,colorFillSecondary:d,controlHeightLG:v,controlHeightSM:h,colorBgContainerDisabled:g,colorTextDisabled:p}=e;return{zIndexPopup:i+50,optionSelectedColor:a,optionSelectedFontWeight:l,optionSelectedBg:s,optionActiveBg:c,optionPadding:`${(r-t*n)/2}px ${o}px`,optionFontSize:t,optionLineHeight:n,optionHeight:r,selectorBg:u,clearBg:u,singleItemHeightLG:v,multipleItemBg:d,multipleItemBorderColor:"transparent",multipleItemHeight:h,multipleItemHeightLG:r,multipleSelectorBgDisabled:g,multipleItemColorDisabled:p,multipleItemBorderColorDisabled:"transparent",showArrowPaddingInlineEnd:Math.ceil(e.fontSize*1.25)}},e2=(e,t)=>{const{componentCls:n,antCls:r,controlOutlineWidth:o}=e;return{[`&:not(${n}-customize-input) ${n}-selector`]:{border:`${X(e.lineWidth)} ${e.lineType} ${t.borderColor}`,background:e.selectorBg},[`&:not(${n}-disabled):not(${n}-customize-input):not(${r}-pagination-size-changer)`]:{[`&:hover ${n}-selector`]:{borderColor:t.hoverBorderHover},[`${n}-focused& ${n}-selector`]:{borderColor:t.activeBorderColor,boxShadow:`0 0 0 ${X(o)} ${t.activeShadowColor}`,outline:0}}}},_b=(e,t)=>({[`&${e.componentCls}-status-${t.status}`]:Object.assign({},e2(e,t))}),V8=e=>({"&-outlined":Object.assign(Object.assign(Object.assign(Object.assign({},e2(e,{borderColor:e.colorBorder,hoverBorderHover:e.colorPrimaryHover,activeBorderColor:e.colorPrimary,activeShadowColor:e.controlOutline})),_b(e,{status:"error",borderColor:e.colorError,hoverBorderHover:e.colorErrorHover,activeBorderColor:e.colorError,activeShadowColor:e.colorErrorOutline})),_b(e,{status:"warning",borderColor:e.colorWarning,hoverBorderHover:e.colorWarningHover,activeBorderColor:e.colorWarning,activeShadowColor:e.colorWarningOutline})),{[`&${e.componentCls}-disabled`]:{[`&:not(${e.componentCls}-customize-input) ${e.componentCls}-selector`]:{background:e.colorBgContainerDisabled,color:e.colorTextDisabled}},[`&${e.componentCls}-multiple ${e.componentCls}-selection-item`]:{background:e.multipleItemBg,border:`${X(e.lineWidth)} ${e.lineType} ${e.multipleItemBorderColor}`}})}),t2=(e,t)=>{const{componentCls:n,antCls:r}=e;return{[`&:not(${n}-customize-input) ${n}-selector`]:{background:t.bg,border:`${X(e.lineWidth)} ${e.lineType} transparent`,color:t.color},[`&:not(${n}-disabled):not(${n}-customize-input):not(${r}-pagination-size-changer)`]:{[`&:hover ${n}-selector`]:{background:t.hoverBg},[`${n}-focused& ${n}-selector`]:{background:e.selectorBg,borderColor:t.activeBorderColor,outline:0}}}},Ab=(e,t)=>({[`&${e.componentCls}-status-${t.status}`]:Object.assign({},t2(e,t))}),U8=e=>({"&-filled":Object.assign(Object.assign(Object.assign(Object.assign({},t2(e,{bg:e.colorFillTertiary,hoverBg:e.colorFillSecondary,activeBorderColor:e.colorPrimary,color:e.colorText})),Ab(e,{status:"error",bg:e.colorErrorBg,hoverBg:e.colorErrorBgHover,activeBorderColor:e.colorError,color:e.colorError})),Ab(e,{status:"warning",bg:e.colorWarningBg,hoverBg:e.colorWarningBgHover,activeBorderColor:e.colorWarning,color:e.colorWarning})),{[`&${e.componentCls}-disabled`]:{[`&:not(${e.componentCls}-customize-input) ${e.componentCls}-selector`]:{borderColor:e.colorBorder,background:e.colorBgContainerDisabled,color:e.colorTextDisabled}},[`&${e.componentCls}-multiple ${e.componentCls}-selection-item`]:{background:e.colorBgContainer,border:`${X(e.lineWidth)} ${e.lineType} ${e.colorSplit}`}})}),Y8=e=>({"&-borderless":{[`${e.componentCls}-selector`]:{background:"transparent",borderColor:"transparent"},[`&${e.componentCls}-disabled`]:{[`&:not(${e.componentCls}-customize-input) ${e.componentCls}-selector`]:{color:e.colorTextDisabled}},[`&${e.componentCls}-multiple ${e.componentCls}-selection-item`]:{background:e.multipleItemBg,border:`${X(e.lineWidth)} ${e.lineType} ${e.multipleItemBorderColor}`}}}),G8=e=>({[e.componentCls]:Object.assign(Object.assign(Object.assign({},V8(e)),U8(e)),Y8(e))}),K8=G8,q8=e=>{const{componentCls:t}=e;return{position:"relative",transition:`all ${e.motionDurationMid} ${e.motionEaseInOut}`,input:{cursor:"pointer"},[`${t}-show-search&`]:{cursor:"text",input:{cursor:"auto",color:"inherit",height:"100%"}},[`${t}-disabled&`]:{cursor:"not-allowed",input:{cursor:"not-allowed"}}}},X8=e=>{const{componentCls:t}=e;return{[`${t}-selection-search-input`]:{margin:0,padding:0,background:"transparent",border:"none",outline:"none",appearance:"none",fontFamily:"inherit","&::-webkit-search-cancel-button":{display:"none","-webkit-appearance":"none"}}}},Q8=e=>{const{antCls:t,componentCls:n,inputPaddingHorizontalBase:r,iconCls:o}=e;return{[n]:Object.assign(Object.assign({},Qt(e)),{position:"relative",display:"inline-block",cursor:"pointer",[`&:not(${n}-customize-input) ${n}-selector`]:Object.assign(Object.assign({},q8(e)),X8(e)),[`${n}-selection-item`]:Object.assign(Object.assign({flex:1,fontWeight:"normal",position:"relative",userSelect:"none"},ei),{[`> ${t}-typography`]:{display:"inline"}}),[`${n}-selection-placeholder`]:Object.assign(Object.assign({},ei),{flex:1,color:e.colorTextPlaceholder,pointerEvents:"none"}),[`${n}-arrow`]:Object.assign(Object.assign({},Uh()),{position:"absolute",top:"50%",insetInlineStart:"auto",insetInlineEnd:r,height:e.fontSizeIcon,marginTop:e.calc(e.fontSizeIcon).mul(-1).div(2).equal(),color:e.colorTextQuaternary,fontSize:e.fontSizeIcon,lineHeight:1,textAlign:"center",pointerEvents:"none",display:"flex",alignItems:"center",transition:`opacity ${e.motionDurationSlow} ease`,[o]:{verticalAlign:"top",transition:`transform ${e.motionDurationSlow}`,"> svg":{verticalAlign:"top"},[`&:not(${n}-suffix)`]:{pointerEvents:"auto"}},[`${n}-disabled &`]:{cursor:"not-allowed"},"> *:not(:last-child)":{marginInlineEnd:8}}),[`${n}-clear`]:{position:"absolute",top:"50%",insetInlineStart:"auto",insetInlineEnd:r,zIndex:1,display:"inline-block",width:e.fontSizeIcon,height:e.fontSizeIcon,marginTop:e.calc(e.fontSizeIcon).mul(-1).div(2).equal(),color:e.colorTextQuaternary,fontSize:e.fontSizeIcon,fontStyle:"normal",lineHeight:1,textAlign:"center",textTransform:"none",cursor:"pointer",opacity:0,transition:`color ${e.motionDurationMid} ease, opacity ${e.motionDurationSlow} ease`,textRendering:"auto","&:before":{display:"block"},"&:hover":{color:e.colorTextTertiary}},"&:hover":{[`${n}-clear`]:{opacity:1},[`${n}-arrow:not(:last-child)`]:{opacity:0}}}),[`${n}-has-feedback`]:{[`${n}-clear`]:{insetInlineEnd:e.calc(r).add(e.fontSize).add(e.paddingXS).equal()}}}},Z8=e=>{const{componentCls:t}=e;return[{[t]:{[`&${t}-in-form-item`]:{width:"100%"}}},Q8(e),H8(e),j8(e),k8(e),{[`${t}-rtl`]:{direction:"rtl"}},tf(e,{borderElCls:`${t}-selector`,focusElCls:`${t}-focused`})]},J8=vn("Select",(e,t)=>{let{rootPrefixCls:n}=t;const r=$t(e,{rootPrefixCls:n,inputPaddingHorizontalBase:e.calc(e.paddingSM).sub(1).equal(),multipleSelectItemHeight:e.multipleItemHeight,selectHeight:e.controlHeight});return[Z8(r),K8(r)]},W8,{unitless:{optionLineHeight:!0,optionSelectedFontWeight:!0}});function eD(e){let{suffixIcon:t,clearIcon:n,menuItemSelectedIcon:r,removeIcon:o,loading:i,multiple:a,hasFeedback:l,prefixCls:s,showSuffixIcon:c,feedbackIcon:u,showArrow:d,componentName:v}=e;const h=n!=null?n:C(Nd,{}),g=y=>t===null&&!l&&!d?null:ie(Tt,{children:[c!==!1&&y,l&&u]});let p=null;if(t!==void 0)p=g(t);else if(i)p=g(C(ux,{spin:!0}));else{const y=`${s}-suffix`;p=S=>{let{open:x,showSearch:$}=S;return g(x&&$?C(_d,{className:y}):C(qI,{className:y}))}}let b=null;r!==void 0?b=r:a?b=C(lx,{}):b=null;let m=null;return o!==void 0?m=o:m=C(eo,{}),{clearIcon:h,suffixIcon:p,itemIcon:b,removeIcon:m}}function tD(e,t){return t!==void 0?t:e!==null}var nD=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var n;const{prefixCls:r,bordered:o,className:i,rootClassName:a,getPopupContainer:l,popupClassName:s,dropdownClassName:c,listHeight:u=256,placement:d,listItemHeight:v,size:h,disabled:g,notFoundContent:p,status:b,builtinPlacements:m,dropdownMatchSelectWidth:y,popupMatchSelectWidth:S,direction:x,style:$,allowClear:E,variant:w,dropdownStyle:R,transitionName:P,tagRender:N,maxCount:I}=e,z=nD(e,["prefixCls","bordered","className","rootClassName","getPopupContainer","popupClassName","dropdownClassName","listHeight","placement","listItemHeight","size","disabled","notFoundContent","status","builtinPlacements","dropdownMatchSelectWidth","popupMatchSelectWidth","direction","style","allowClear","variant","dropdownStyle","transitionName","tagRender","maxCount"]),{getPopupContainer:F,getPrefixCls:T,renderEmpty:D,direction:_,virtual:O,popupMatchSelectWidth:M,popupOverflow:L,select:A}=f.exports.useContext(ot),[,B]=Kn(),k=v!=null?v:B==null?void 0:B.controlHeight,j=T("select",r),H=T(),W=x!=null?x:_,{compactSize:Y,compactItemClassnames:K}=ef(j,W),[q,ee]=vm(w,o),Z=no(j),[Q,ne,ae]=J8(j,Z),J=f.exports.useMemo(()=>{const{mode:Be}=e;if(Be!=="combobox")return Be===n2?"combobox":Be},[e.mode]),re=J==="multiple"||J==="tags",fe=tD(e.suffixIcon,e.showArrow),ve=(n=S!=null?S:y)!==null&&n!==void 0?n:M,{status:pe,hasFeedback:oe,isFormItemInput:se,feedbackIcon:le}=f.exports.useContext(Jr),Ce=dm(pe,b);let ce;p!==void 0?ce=p:J==="combobox"?ce=null:ce=(D==null?void 0:D("Select"))||C(_8,{componentName:"Select"});const{suffixIcon:de,itemIcon:xe,removeIcon:he,clearIcon:ke}=eD(Object.assign(Object.assign({},z),{multiple:re,hasFeedback:oe,feedbackIcon:le,showSuffixIcon:fe,prefixCls:j,componentName:"Select"})),we=E===!0?{clearIcon:ke}:E,ge=lr(z,["suffixIcon","itemIcon"]),Pe=te(s||c,{[`${j}-dropdown-${W}`]:W==="rtl"},a,ae,Z,ne),Se=So(Be=>{var qe;return(qe=h!=null?h:Y)!==null&&qe!==void 0?qe:Be}),st=f.exports.useContext(rl),nt=g!=null?g:st,Ne=te({[`${j}-lg`]:Se==="large",[`${j}-sm`]:Se==="small",[`${j}-rtl`]:W==="rtl",[`${j}-${q}`]:ee,[`${j}-in-form-item`]:se},ed(j,Ce,oe),K,A==null?void 0:A.className,i,a,ae,Z,ne),Ee=f.exports.useMemo(()=>d!==void 0?d:W==="rtl"?"bottomRight":"bottomLeft",[d,W]),[_e]=Qd("SelectLike",R==null?void 0:R.zIndex);return Q(C(um,{...Object.assign({ref:t,virtual:O,showSearch:A==null?void 0:A.showSearch},ge,{style:Object.assign(Object.assign({},A==null?void 0:A.style),$),dropdownMatchSelectWidth:ve,transitionName:ni(H,"slide-up",P),builtinPlacements:z8(m,L),listHeight:u,listItemHeight:k,mode:J,prefixCls:j,placement:Ee,direction:W,suffixIcon:de,menuItemSelectedIcon:xe,removeIcon:he,allowClear:we,notFoundContent:ce,className:Ne,getPopupContainer:l||F,dropdownClassName:Pe,disabled:nt,dropdownStyle:Object.assign(Object.assign({},R),{zIndex:_e}),maxCount:re?I:void 0,tagRender:re?N:void 0})}))},ol=f.exports.forwardRef(rD),oD=q_(ol);ol.SECRET_COMBOBOX_MODE_DO_NOT_USE=n2;ol.Option=cm;ol.OptGroup=sm;ol._InternalPanelDoNotUseOrYouWillBeFired=oD;const r2=ol,o2=["xxl","xl","lg","md","sm","xs"],iD=e=>({xs:`(max-width: ${e.screenXSMax}px)`,sm:`(min-width: ${e.screenSM}px)`,md:`(min-width: ${e.screenMD}px)`,lg:`(min-width: ${e.screenLG}px)`,xl:`(min-width: ${e.screenXL}px)`,xxl:`(min-width: ${e.screenXXL}px)`}),aD=e=>{const t=e,n=[].concat(o2).reverse();return n.forEach((r,o)=>{const i=r.toUpperCase(),a=`screen${i}Min`,l=`screen${i}`;if(!(t[a]<=t[l]))throw new Error(`${a}<=${l} fails : !(${t[a]}<=${t[l]})`);if(o{const n=new Map;let r=-1,o={};return{matchHandlers:{},dispatch(i){return o=i,n.forEach(a=>a(o)),n.size>=1},subscribe(i){return n.size||this.register(),r+=1,n.set(r,i),i(o),r},unsubscribe(i){n.delete(i),n.size||this.unregister()},unregister(){Object.keys(t).forEach(i=>{const a=t[i],l=this.matchHandlers[a];l==null||l.mql.removeListener(l==null?void 0:l.listener)}),n.clear()},register(){Object.keys(t).forEach(i=>{const a=t[i],l=c=>{let{matches:u}=c;this.dispatch(Object.assign(Object.assign({},o),{[i]:u}))},s=window.matchMedia(a);s.addListener(l),this.matchHandlers[a]={mql:s,listener:l},l(s)})},responsiveMap:t}},[e])}function sD(){const[,e]=f.exports.useReducer(t=>t+1,0);return e}function cD(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0;const t=f.exports.useRef({}),n=sD(),r=lD();return Nt(()=>{const o=r.subscribe(i=>{t.current=i,e&&n()});return()=>r.unsubscribe(o)},[]),t.current}const uD=f.exports.createContext({}),Cg=uD,dD=e=>{const{antCls:t,componentCls:n,iconCls:r,avatarBg:o,avatarColor:i,containerSize:a,containerSizeLG:l,containerSizeSM:s,textFontSize:c,textFontSizeLG:u,textFontSizeSM:d,borderRadius:v,borderRadiusLG:h,borderRadiusSM:g,lineWidth:p,lineType:b}=e,m=(y,S,x)=>({width:y,height:y,borderRadius:"50%",[`&${n}-square`]:{borderRadius:x},[`&${n}-icon`]:{fontSize:S,[`> ${r}`]:{margin:0}}});return{[n]:Object.assign(Object.assign(Object.assign(Object.assign({},Qt(e)),{position:"relative",display:"inline-flex",justifyContent:"center",alignItems:"center",overflow:"hidden",color:i,whiteSpace:"nowrap",textAlign:"center",verticalAlign:"middle",background:o,border:`${X(p)} ${b} transparent`,["&-image"]:{background:"transparent"},[`${t}-image-img`]:{display:"block"}}),m(a,c,v)),{["&-lg"]:Object.assign({},m(l,u,h)),["&-sm"]:Object.assign({},m(s,d,g)),"> img":{display:"block",width:"100%",height:"100%",objectFit:"cover"}})}},fD=e=>{const{componentCls:t,groupBorderColor:n,groupOverlapping:r,groupSpace:o}=e;return{[`${t}-group`]:{display:"inline-flex",[`${t}`]:{borderColor:n},["> *:not(:first-child)"]:{marginInlineStart:r}},[`${t}-group-popover`]:{[`${t} + ${t}`]:{marginInlineStart:o}}}},vD=e=>{const{controlHeight:t,controlHeightLG:n,controlHeightSM:r,fontSize:o,fontSizeLG:i,fontSizeXL:a,fontSizeHeading3:l,marginXS:s,marginXXS:c,colorBorderBg:u}=e;return{containerSize:t,containerSizeLG:n,containerSizeSM:r,textFontSize:Math.round((i+a)/2),textFontSizeLG:l,textFontSizeSM:o,groupSpace:c,groupOverlapping:-s,groupBorderColor:u}},i2=vn("Avatar",e=>{const{colorTextLightSolid:t,colorTextPlaceholder:n}=e,r=$t(e,{avatarBg:n,avatarColor:t});return[dD(r),fD(r)]},vD);var pD=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const[n,r]=f.exports.useState(1),[o,i]=f.exports.useState(!1),[a,l]=f.exports.useState(!0),s=f.exports.useRef(null),c=f.exports.useRef(null),u=xr(t,s),{getPrefixCls:d,avatar:v}=f.exports.useContext(ot),h=f.exports.useContext(Cg),g=()=>{if(!c.current||!s.current)return;const q=c.current.offsetWidth,ee=s.current.offsetWidth;if(q!==0&&ee!==0){const{gap:Z=4}=e;Z*2{i(!0)},[]),f.exports.useEffect(()=>{l(!0),r(1)},[e.src]),f.exports.useEffect(g,[e.gap]);const p=()=>{const{onError:q}=e;(q==null?void 0:q())!==!1&&l(!1)},{prefixCls:b,shape:m,size:y,src:S,srcSet:x,icon:$,className:E,rootClassName:w,alt:R,draggable:P,children:N,crossOrigin:I}=e,z=pD(e,["prefixCls","shape","size","src","srcSet","icon","className","rootClassName","alt","draggable","children","crossOrigin"]),F=So(q=>{var ee,Z;return(Z=(ee=y!=null?y:h==null?void 0:h.size)!==null&&ee!==void 0?ee:q)!==null&&Z!==void 0?Z:"default"}),T=Object.keys(typeof F=="object"?F||{}:{}).some(q=>["xs","sm","md","lg","xl","xxl"].includes(q)),D=cD(T),_=f.exports.useMemo(()=>{if(typeof F!="object")return{};const q=o2.find(Z=>D[Z]),ee=F[q];return ee?{width:ee,height:ee,fontSize:ee&&($||N)?ee/2:18}:{}},[D,F]),O=d("avatar",b),M=no(O),[L,A,B]=i2(O,M),k=te({[`${O}-lg`]:F==="large",[`${O}-sm`]:F==="small"}),j=f.exports.isValidElement(S),H=m||(h==null?void 0:h.shape)||"circle",W=te(O,k,v==null?void 0:v.className,`${O}-${H}`,{[`${O}-image`]:j||S&&a,[`${O}-icon`]:!!$},B,M,E,w,A),Y=typeof F=="number"?{width:F,height:F,fontSize:$?F/2:18}:{};let K;if(typeof S=="string"&&a)K=C("img",{src:S,draggable:P,srcSet:x,onError:p,alt:R,crossOrigin:I});else if(j)K=S;else if($)K=$;else if(o||n!==1){const q=`scale(${n})`,ee={msTransform:q,WebkitTransform:q,transform:q};K=C(mr,{onResize:g,children:C("span",{className:`${O}-string`,ref:c,style:Object.assign({},ee),children:N})})}else K=C("span",{className:`${O}-string`,style:{opacity:0},ref:c,children:N});return delete z.onError,delete z.gap,L(C("span",{...Object.assign({},z,{style:Object.assign(Object.assign(Object.assign(Object.assign({},Y),_),v==null?void 0:v.style),z.style),className:W,ref:u}),children:K}))},hD=f.exports.forwardRef(gD),a2=hD,td=e=>e?typeof e=="function"?e():e:null;function gm(e){var t=e.children,n=e.prefixCls,r=e.id,o=e.overlayInnerStyle,i=e.className,a=e.style;return C("div",{className:te("".concat(n,"-content"),i),style:a,children:C("div",{className:"".concat(n,"-inner"),id:r,role:"tooltip",style:o,children:typeof t=="function"?t():t})})}var Zi={shiftX:64,adjustY:1},Ji={adjustX:1,shiftY:!0},ur=[0,0],mD={left:{points:["cr","cl"],overflow:Ji,offset:[-4,0],targetOffset:ur},right:{points:["cl","cr"],overflow:Ji,offset:[4,0],targetOffset:ur},top:{points:["bc","tc"],overflow:Zi,offset:[0,-4],targetOffset:ur},bottom:{points:["tc","bc"],overflow:Zi,offset:[0,4],targetOffset:ur},topLeft:{points:["bl","tl"],overflow:Zi,offset:[0,-4],targetOffset:ur},leftTop:{points:["tr","tl"],overflow:Ji,offset:[-4,0],targetOffset:ur},topRight:{points:["br","tr"],overflow:Zi,offset:[0,-4],targetOffset:ur},rightTop:{points:["tl","tr"],overflow:Ji,offset:[4,0],targetOffset:ur},bottomRight:{points:["tr","br"],overflow:Zi,offset:[0,4],targetOffset:ur},rightBottom:{points:["bl","br"],overflow:Ji,offset:[4,0],targetOffset:ur},bottomLeft:{points:["tl","bl"],overflow:Zi,offset:[0,4],targetOffset:ur},leftBottom:{points:["br","bl"],overflow:Ji,offset:[-4,0],targetOffset:ur}},yD=["overlayClassName","trigger","mouseEnterDelay","mouseLeaveDelay","overlayStyle","prefixCls","children","onVisibleChange","afterVisibleChange","transitionName","animation","motion","placement","align","destroyTooltipOnHide","defaultVisible","getTooltipContainer","overlayInnerStyle","arrowContent","overlay","id","showArrow"],bD=function(t,n){var r=t.overlayClassName,o=t.trigger,i=o===void 0?["hover"]:o,a=t.mouseEnterDelay,l=a===void 0?0:a,s=t.mouseLeaveDelay,c=s===void 0?.1:s,u=t.overlayStyle,d=t.prefixCls,v=d===void 0?"rc-tooltip":d,h=t.children,g=t.onVisibleChange,p=t.afterVisibleChange,b=t.transitionName,m=t.animation,y=t.motion,S=t.placement,x=S===void 0?"right":S,$=t.align,E=$===void 0?{}:$,w=t.destroyTooltipOnHide,R=w===void 0?!1:w,P=t.defaultVisible,N=t.getTooltipContainer,I=t.overlayInnerStyle;t.arrowContent;var z=t.overlay,F=t.id,T=t.showArrow,D=T===void 0?!0:T,_=Je(t,yD),O=f.exports.useRef(null);f.exports.useImperativeHandle(n,function(){return O.current});var M=U({},_);"visible"in t&&(M.popupVisible=t.visible);var L=function(){return C(gm,{prefixCls:v,id:F,overlayInnerStyle:I,children:z},"content")};return C(lf,{popupClassName:r,prefixCls:v,popup:L,action:i,builtinPlacements:mD,popupPlacement:x,ref:O,popupAlign:E,getPopupContainer:N,onPopupVisibleChange:g,afterPopupVisibleChange:p,popupTransitionName:b,popupAnimation:m,popupMotion:y,defaultPopupVisible:P,autoDestroy:R,mouseLeaveDelay:c,popupStyle:u,mouseEnterDelay:l,arrow:D,...M,children:h})};const SD=f.exports.forwardRef(bD);function hm(e){const{sizePopupArrow:t,borderRadiusXS:n,borderRadiusOuter:r}=e,o=t/2,i=0,a=o,l=r*1/Math.sqrt(2),s=o-r*(1-1/Math.sqrt(2)),c=o-n*(1/Math.sqrt(2)),u=r*(Math.sqrt(2)-1)+n*(1/Math.sqrt(2)),d=2*o-c,v=u,h=2*o-l,g=s,p=2*o-i,b=a,m=o*Math.sqrt(2)+r*(Math.sqrt(2)-2),y=r*(Math.sqrt(2)-1),S=`polygon(${y}px 100%, 50% ${y}px, ${2*o-y}px 100%, ${y}px 100%)`,x=`path('M ${i} ${a} A ${r} ${r} 0 0 0 ${l} ${s} L ${c} ${u} A ${n} ${n} 0 0 1 ${d} ${v} L ${h} ${g} A ${r} ${r} 0 0 0 ${p} ${b} Z')`;return{arrowShadowWidth:m,arrowPath:x,arrowPolygon:S}}const l2=(e,t,n)=>{const{sizePopupArrow:r,arrowPolygon:o,arrowPath:i,arrowShadowWidth:a,borderRadiusXS:l,calc:s}=e;return{pointerEvents:"none",width:r,height:r,overflow:"hidden","&::before":{position:"absolute",bottom:0,insetInlineStart:0,width:r,height:s(r).div(2).equal(),background:t,clipPath:{_multi_value_:!0,value:[o,i]},content:'""'},"&::after":{content:'""',position:"absolute",width:a,height:a,bottom:0,insetInline:0,margin:"auto",borderRadius:{_skip_check_:!0,value:`0 0 ${X(l)} 0`},transform:"translateY(50%) rotate(-135deg)",boxShadow:n,zIndex:0,background:"transparent"}}},s2=8;function mm(e){const{contentRadius:t,limitVerticalRadius:n}=e,r=t>12?t+2:12;return{arrowOffsetHorizontal:r,arrowOffsetVertical:n?s2:r}}function _c(e,t){return e?t:{}}function c2(e,t,n){const{componentCls:r,boxShadowPopoverArrow:o,arrowOffsetVertical:i,arrowOffsetHorizontal:a}=e,{arrowDistance:l=0,arrowPlacement:s={left:!0,right:!0,top:!0,bottom:!0}}=n||{};return{[r]:Object.assign(Object.assign(Object.assign(Object.assign({[`${r}-arrow`]:[Object.assign(Object.assign({position:"absolute",zIndex:1,display:"block"},l2(e,t,o)),{"&:before":{background:t}})]},_c(!!s.top,{[[`&-placement-top > ${r}-arrow`,`&-placement-topLeft > ${r}-arrow`,`&-placement-topRight > ${r}-arrow`].join(",")]:{bottom:l,transform:"translateY(100%) rotate(180deg)"},[`&-placement-top > ${r}-arrow`]:{left:{_skip_check_:!0,value:"50%"},transform:"translateX(-50%) translateY(100%) rotate(180deg)"},[`&-placement-topLeft > ${r}-arrow`]:{left:{_skip_check_:!0,value:a}},[`&-placement-topRight > ${r}-arrow`]:{right:{_skip_check_:!0,value:a}}})),_c(!!s.bottom,{[[`&-placement-bottom > ${r}-arrow`,`&-placement-bottomLeft > ${r}-arrow`,`&-placement-bottomRight > ${r}-arrow`].join(",")]:{top:l,transform:"translateY(-100%)"},[`&-placement-bottom > ${r}-arrow`]:{left:{_skip_check_:!0,value:"50%"},transform:"translateX(-50%) translateY(-100%)"},[`&-placement-bottomLeft > ${r}-arrow`]:{left:{_skip_check_:!0,value:a}},[`&-placement-bottomRight > ${r}-arrow`]:{right:{_skip_check_:!0,value:a}}})),_c(!!s.left,{[[`&-placement-left > ${r}-arrow`,`&-placement-leftTop > ${r}-arrow`,`&-placement-leftBottom > ${r}-arrow`].join(",")]:{right:{_skip_check_:!0,value:l},transform:"translateX(100%) rotate(90deg)"},[`&-placement-left > ${r}-arrow`]:{top:{_skip_check_:!0,value:"50%"},transform:"translateY(-50%) translateX(100%) rotate(90deg)"},[`&-placement-leftTop > ${r}-arrow`]:{top:i},[`&-placement-leftBottom > ${r}-arrow`]:{bottom:i}})),_c(!!s.right,{[[`&-placement-right > ${r}-arrow`,`&-placement-rightTop > ${r}-arrow`,`&-placement-rightBottom > ${r}-arrow`].join(",")]:{left:{_skip_check_:!0,value:l},transform:"translateX(-100%) rotate(-90deg)"},[`&-placement-right > ${r}-arrow`]:{top:{_skip_check_:!0,value:"50%"},transform:"translateY(-50%) translateX(-100%) rotate(-90deg)"},[`&-placement-rightTop > ${r}-arrow`]:{top:i},[`&-placement-rightBottom > ${r}-arrow`]:{bottom:i}}))}}function CD(e,t,n,r){if(r===!1)return{adjustX:!1,adjustY:!1};const o=r&&typeof r=="object"?r:{},i={};switch(e){case"top":case"bottom":i.shiftX=t.arrowOffsetHorizontal*2+n,i.shiftY=!0,i.adjustY=!0;break;case"left":case"right":i.shiftY=t.arrowOffsetVertical*2+n,i.shiftX=!0,i.adjustX=!0;break}const a=Object.assign(Object.assign({},i),o);return a.shiftX||(a.adjustX=!0),a.shiftY||(a.adjustY=!0),a}const Db={left:{points:["cr","cl"]},right:{points:["cl","cr"]},top:{points:["bc","tc"]},bottom:{points:["tc","bc"]},topLeft:{points:["bl","tl"]},leftTop:{points:["tr","tl"]},topRight:{points:["br","tr"]},rightTop:{points:["tl","tr"]},bottomRight:{points:["tr","br"]},rightBottom:{points:["bl","br"]},bottomLeft:{points:["tl","bl"]},leftBottom:{points:["br","bl"]}},xD={topLeft:{points:["bl","tc"]},leftTop:{points:["tr","cl"]},topRight:{points:["br","tc"]},rightTop:{points:["tl","cr"]},bottomRight:{points:["tr","bc"]},rightBottom:{points:["bl","cr"]},bottomLeft:{points:["tl","bc"]},leftBottom:{points:["br","cl"]}},wD=new Set(["topLeft","topRight","bottomLeft","bottomRight","leftTop","leftBottom","rightTop","rightBottom"]);function $D(e){const{arrowWidth:t,autoAdjustOverflow:n,arrowPointAtCenter:r,offset:o,borderRadius:i,visibleFirst:a}=e,l=t/2,s={};return Object.keys(Db).forEach(c=>{const u=r&&xD[c]||Db[c],d=Object.assign(Object.assign({},u),{offset:[0,0],dynamicInset:!0});switch(s[c]=d,wD.has(c)&&(d.autoArrow=!1),c){case"top":case"topLeft":case"topRight":d.offset[1]=-l-o;break;case"bottom":case"bottomLeft":case"bottomRight":d.offset[1]=l+o;break;case"left":case"leftTop":case"leftBottom":d.offset[0]=-l-o;break;case"right":case"rightTop":case"rightBottom":d.offset[0]=l+o;break}const v=mm({contentRadius:i,limitVerticalRadius:!0});if(r)switch(c){case"topLeft":case"bottomLeft":d.offset[0]=-v.arrowOffsetHorizontal-l;break;case"topRight":case"bottomRight":d.offset[0]=v.arrowOffsetHorizontal+l;break;case"leftTop":case"rightTop":d.offset[1]=-v.arrowOffsetHorizontal-l;break;case"leftBottom":case"rightBottom":d.offset[1]=v.arrowOffsetHorizontal+l;break}d.overflow=CD(c,v,t,n),a&&(d.htmlRegion="visibleFirst")}),s}const ED=e=>{const{componentCls:t,tooltipMaxWidth:n,tooltipColor:r,tooltipBg:o,tooltipBorderRadius:i,zIndexPopup:a,controlHeight:l,boxShadowSecondary:s,paddingSM:c,paddingXS:u}=e;return[{[t]:Object.assign(Object.assign(Object.assign(Object.assign({},Qt(e)),{position:"absolute",zIndex:a,display:"block",width:"max-content",maxWidth:n,visibility:"visible",transformOrigin:"var(--arrow-x, 50%) var(--arrow-y, 50%)","&-hidden":{display:"none"},"--antd-arrow-background-color":o,[`${t}-inner`]:{minWidth:l,minHeight:l,padding:`${X(e.calc(c).div(2).equal())} ${X(u)}`,color:r,textAlign:"start",textDecoration:"none",wordWrap:"break-word",backgroundColor:o,borderRadius:i,boxShadow:s,boxSizing:"border-box"},[["&-placement-left","&-placement-leftTop","&-placement-leftBottom","&-placement-right","&-placement-rightTop","&-placement-rightBottom"].join(",")]:{[`${t}-inner`]:{borderRadius:e.min(i,s2)}},[`${t}-content`]:{position:"relative"}}),ow(e,(d,v)=>{let{darkColor:h}=v;return{[`&${t}-${d}`]:{[`${t}-inner`]:{backgroundColor:h},[`${t}-arrow`]:{"--antd-arrow-background-color":h}}}})),{"&-rtl":{direction:"rtl"}})},c2(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow}}]},MD=e=>Object.assign(Object.assign({zIndexPopup:e.zIndexPopupBase+70},mm({contentRadius:e.borderRadius,limitVerticalRadius:!0})),hm($t(e,{borderRadiusOuter:Math.min(e.borderRadiusOuter,4)}))),u2=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0;return vn("Tooltip",r=>{const{borderRadius:o,colorTextLightSolid:i,colorBgSpotlight:a}=r,l=$t(r,{tooltipMaxWidth:250,tooltipColor:i,tooltipBorderRadius:o,tooltipBg:a});return[ED(l),of(r,"zoom-big-fast")]},MD,{resetStyle:!1,injectStyle:t})(e)},OD=$s.map(e=>`${e}-inverse`),RD=["success","processing","error","default","warning"];function d2(e){return(arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0)?[].concat(Oe(OD),Oe($s)).includes(e):$s.includes(e)}function ID(e){return RD.includes(e)}function f2(e,t){const n=d2(t),r=te({[`${e}-${t}`]:t&&n}),o={},i={};return t&&!n&&(o.background=t,i["--antd-arrow-background-color"]=t),{className:r,overlayStyle:o,arrowStyle:i}}const PD=e=>{const{prefixCls:t,className:n,placement:r="top",title:o,color:i,overlayInnerStyle:a}=e,{getPrefixCls:l}=f.exports.useContext(ot),s=l("tooltip",t),[c,u,d]=u2(s),v=f2(s,i),h=v.arrowStyle,g=Object.assign(Object.assign({},a),v.overlayStyle),p=te(u,d,s,`${s}-pure`,`${s}-placement-${r}`,n,v.className);return c(ie("div",{className:p,style:h,children:[C("div",{className:`${s}-arrow`}),C(gm,{...Object.assign({},e,{className:u,prefixCls:s,overlayInnerStyle:g}),children:o})]}))},TD=PD;var ND=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var n,r;const{prefixCls:o,openClassName:i,getTooltipContainer:a,overlayClassName:l,color:s,overlayInnerStyle:c,children:u,afterOpenChange:d,afterVisibleChange:v,destroyTooltipOnHide:h,arrow:g=!0,title:p,overlay:b,builtinPlacements:m,arrowPointAtCenter:y=!1,autoAdjustOverflow:S=!0}=e,x=!!g,[,$]=Kn(),{getPopupContainer:E,getPrefixCls:w,direction:R}=f.exports.useContext(ot),P=jx(),N=f.exports.useRef(null),I=()=>{var ce;(ce=N.current)===null||ce===void 0||ce.forceAlign()};f.exports.useImperativeHandle(t,()=>({forceAlign:I,forcePopupAlign:()=>{P.deprecated(!1,"forcePopupAlign","forceAlign"),I()}}));const[z,F]=kt(!1,{value:(n=e.open)!==null&&n!==void 0?n:e.visible,defaultValue:(r=e.defaultOpen)!==null&&r!==void 0?r:e.defaultVisible}),T=!p&&!b&&p!==0,D=ce=>{var de,xe;F(T?!1:ce),T||((de=e.onOpenChange)===null||de===void 0||de.call(e,ce),(xe=e.onVisibleChange)===null||xe===void 0||xe.call(e,ce))},_=f.exports.useMemo(()=>{var ce,de;let xe=y;return typeof g=="object"&&(xe=(de=(ce=g.pointAtCenter)!==null&&ce!==void 0?ce:g.arrowPointAtCenter)!==null&&de!==void 0?de:y),m||$D({arrowPointAtCenter:xe,autoAdjustOverflow:S,arrowWidth:x?$.sizePopupArrow:0,borderRadius:$.borderRadius,offset:$.marginXXS,visibleFirst:!0})},[y,g,m,$]),O=f.exports.useMemo(()=>p===0?p:b||p||"",[b,p]),M=C(ig,{children:typeof O=="function"?O():O}),{getPopupContainer:L,placement:A="top",mouseEnterDelay:B=.1,mouseLeaveDelay:k=.1,overlayStyle:j,rootClassName:H}=e,W=ND(e,["getPopupContainer","placement","mouseEnterDelay","mouseLeaveDelay","overlayStyle","rootClassName"]),Y=w("tooltip",o),K=w(),q=e["data-popover-inject"];let ee=z;!("open"in e)&&!("visible"in e)&&T&&(ee=!1);const Z=Es(u)&&!hw(u)?u:C("span",{children:u}),Q=Z.props,ne=!Q.className||typeof Q.className=="string"?te(Q.className,i||`${Y}-open`):Q.className,[ae,J,re]=u2(Y,!q),fe=f2(Y,s),ve=fe.arrowStyle,pe=Object.assign(Object.assign({},c),fe.overlayStyle),oe=te(l,{[`${Y}-rtl`]:R==="rtl"},fe.className,H,J,re),[se,le]=Qd("Tooltip",W.zIndex),Ce=C(SD,{...Object.assign({},W,{zIndex:se,showArrow:x,placement:A,mouseEnterDelay:B,mouseLeaveDelay:k,prefixCls:Y,overlayClassName:oe,overlayStyle:Object.assign(Object.assign({},ve),j),getTooltipContainer:L||a||E,ref:N,builtinPlacements:_,overlay:M,visible:ee,onVisibleChange:D,afterVisibleChange:d!=null?d:v,overlayInnerStyle:pe,arrowContent:C("span",{className:`${Y}-arrow-content`}),motion:{motionName:ni(K,"zoom-big-fast",e.transitionName),motionDeadline:1e3},destroyTooltipOnHide:!!h}),children:ee?ti(Z,{className:ne}):Z});return ae(f.exports.createElement(mw.Provider,{value:le},Ce))});v2._InternalPanelDoNotUseOrYouWillBeFired=TD;const p2=v2,_D=e=>{const{componentCls:t,popoverColor:n,titleMinWidth:r,fontWeightStrong:o,innerPadding:i,boxShadowSecondary:a,colorTextHeading:l,borderRadiusLG:s,zIndexPopup:c,titleMarginBottom:u,colorBgElevated:d,popoverBg:v,titleBorderBottom:h,innerContentPadding:g,titlePadding:p}=e;return[{[t]:Object.assign(Object.assign({},Qt(e)),{position:"absolute",top:0,left:{_skip_check_:!0,value:0},zIndex:c,fontWeight:"normal",whiteSpace:"normal",textAlign:"start",cursor:"auto",userSelect:"text",transformOrigin:"var(--arrow-x, 50%) var(--arrow-y, 50%)","--antd-arrow-background-color":d,"&-rtl":{direction:"rtl"},"&-hidden":{display:"none"},[`${t}-content`]:{position:"relative"},[`${t}-inner`]:{backgroundColor:v,backgroundClip:"padding-box",borderRadius:s,boxShadow:a,padding:i},[`${t}-title`]:{minWidth:r,marginBottom:u,color:l,fontWeight:o,borderBottom:h,padding:p},[`${t}-inner-content`]:{color:n,padding:g}})},c2(e,"var(--antd-arrow-background-color)"),{[`${t}-pure`]:{position:"relative",maxWidth:"none",margin:e.sizePopupArrow,display:"inline-block",[`${t}-content`]:{display:"inline-block"}}}]},AD=e=>{const{componentCls:t}=e;return{[t]:$s.map(n=>{const r=e[`${n}6`];return{[`&${t}-${n}`]:{"--antd-arrow-background-color":r,[`${t}-inner`]:{backgroundColor:r},[`${t}-arrow`]:{background:"transparent"}}}})}},DD=e=>{const{lineWidth:t,controlHeight:n,fontHeight:r,padding:o,wireframe:i,zIndexPopupBase:a,borderRadiusLG:l,marginXS:s,lineType:c,colorSplit:u,paddingSM:d}=e,v=n-r,h=v/2,g=v/2-t,p=o;return Object.assign(Object.assign(Object.assign({titleMinWidth:177,zIndexPopup:a+30},hm(e)),mm({contentRadius:l,limitVerticalRadius:!0})),{innerPadding:i?0:12,titleMarginBottom:i?0:s,titlePadding:i?`${h}px ${p}px ${g}px`:0,titleBorderBottom:i?`${t}px ${c} ${u}`:"none",innerContentPadding:i?`${d}px ${p}px`:0})},g2=vn("Popover",e=>{const{colorBgElevated:t,colorText:n}=e,r=$t(e,{popoverBg:t,popoverColor:n});return[_D(r),AD(r),of(r,"zoom-big")]},DD,{resetStyle:!1,deprecatedTokens:[["width","titleMinWidth"],["minWidth","titleMinWidth"]]});var LD=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o!t&&!n?null:ie(Tt,{children:[t&&C("div",{className:`${e}-title`,children:td(t)}),C("div",{className:`${e}-inner-content`,children:td(n)})]}),FD=e=>{const{hashId:t,prefixCls:n,className:r,style:o,placement:i="top",title:a,content:l,children:s}=e;return ie("div",{className:te(t,n,`${n}-pure`,`${n}-placement-${i}`,r),style:o,children:[C("div",{className:`${n}-arrow`}),C(gm,{...Object.assign({},e,{className:t,prefixCls:n}),children:s||zD(n,a,l)})]})},kD=e=>{const{prefixCls:t,className:n}=e,r=LD(e,["prefixCls","className"]),{getPrefixCls:o}=f.exports.useContext(ot),i=o("popover",t),[a,l,s]=g2(i);return a(C(FD,{...Object.assign({},r,{prefixCls:i,hashId:l,className:te(n,s)})}))},BD=kD;var jD=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{let{title:t,content:n,prefixCls:r}=e;return ie(Tt,{children:[t&&C("div",{className:`${r}-title`,children:td(t)}),C("div",{className:`${r}-inner-content`,children:td(n)})]})},h2=f.exports.forwardRef((e,t)=>{const{prefixCls:n,title:r,content:o,overlayClassName:i,placement:a="top",trigger:l="hover",mouseEnterDelay:s=.1,mouseLeaveDelay:c=.1,overlayStyle:u={}}=e,d=jD(e,["prefixCls","title","content","overlayClassName","placement","trigger","mouseEnterDelay","mouseLeaveDelay","overlayStyle"]),{getPrefixCls:v}=f.exports.useContext(ot),h=v("popover",n),[g,p,b]=g2(h),m=v(),y=te(i,p,b);return g(C(p2,{...Object.assign({placement:a,trigger:l,mouseEnterDelay:s,mouseLeaveDelay:c,overlayStyle:u},d,{prefixCls:h,overlayClassName:y,ref:t,overlay:r||o?C(HD,{prefixCls:h,title:r,content:o}):null,transitionName:ni(m,"zoom-big",d.transitionName),"data-popover-inject":!0})}))});h2._InternalPanelDoNotUseOrYouWillBeFired=BD;const WD=h2,Lb=e=>{const{size:t,shape:n}=f.exports.useContext(Cg),r=f.exports.useMemo(()=>({size:e.size||t,shape:e.shape||n}),[e.size,e.shape,t,n]);return C(Cg.Provider,{value:r,children:e.children})},VD=e=>{const{getPrefixCls:t,direction:n}=f.exports.useContext(ot),{prefixCls:r,className:o,rootClassName:i,style:a,maxCount:l,maxStyle:s,size:c,shape:u,maxPopoverPlacement:d="top",maxPopoverTrigger:v="hover",children:h}=e,g=t("avatar",r),p=`${g}-group`,b=no(g),[m,y,S]=i2(g,b),x=te(p,{[`${p}-rtl`]:n==="rtl"},S,b,o,i,y),$=Qo(h).map((w,R)=>ti(w,{key:`avatar-key-${R}`})),E=$.length;if(l&&l1&&arguments[1]!==void 0?arguments[1]:!1;if(Jd(e)){var n=e.nodeName.toLowerCase(),r=["input","select","textarea","button"].includes(n)||e.isContentEditable||n==="a"&&!!e.getAttribute("href"),o=e.getAttribute("tabindex"),i=Number(o),a=null;return o&&!Number.isNaN(i)?a=i:r&&a===null&&(a=0),r&&e.disabled&&(a=null),a!==null&&(a>=0||t&&a<0)}return!1}function rL(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=Oe(e.querySelectorAll("*")).filter(function(r){return zb(r,t)});return zb(e,t)&&n.unshift(e),n}var xg=ue.LEFT,wg=ue.RIGHT,$g=ue.UP,au=ue.DOWN,lu=ue.ENTER,$2=ue.ESC,$l=ue.HOME,El=ue.END,Fb=[$g,au,xg,wg];function oL(e,t,n,r){var o,i,a,l,s="prev",c="next",u="children",d="parent";if(e==="inline"&&r===lu)return{inlineTrigger:!0};var v=(o={},V(o,$g,s),V(o,au,c),o),h=(i={},V(i,xg,n?c:s),V(i,wg,n?s:c),V(i,au,u),V(i,lu,u),i),g=(a={},V(a,$g,s),V(a,au,c),V(a,lu,u),V(a,$2,d),V(a,xg,n?u:d),V(a,wg,n?d:u),a),p={inline:v,horizontal:h,vertical:g,inlineSub:v,horizontalSub:g,verticalSub:g},b=(l=p["".concat(e).concat(t?"":"Sub")])===null||l===void 0?void 0:l[r];switch(b){case s:return{offset:-1,sibling:!0};case c:return{offset:1,sibling:!0};case d:return{offset:-1,sibling:!1};case u:return{offset:1,sibling:!1};default:return null}}function iL(e){for(var t=e;t;){if(t.getAttribute("data-menu-list"))return t;t=t.parentElement}return null}function aL(e,t){for(var n=e||document.activeElement;n;){if(t.has(n))return n;n=n.parentElement}return null}function bm(e,t){var n=rL(e,!0);return n.filter(function(r){return t.has(r)})}function kb(e,t,n){var r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:1;if(!e)return null;var o=bm(e,t),i=o.length,a=o.findIndex(function(l){return n===l});return r<0?a===-1?a=i-1:a-=1:r>0&&(a+=1),a=(a+i)%i,o[a]}var Eg=function(t,n){var r=new Set,o=new Map,i=new Map;return t.forEach(function(a){var l=document.querySelector("[data-menu-id='".concat(b2(n,a),"']"));l&&(r.add(l),i.set(l,a),o.set(a,l))}),{elements:r,key2element:o,element2key:i}};function lL(e,t,n,r,o,i,a,l,s,c){var u=f.exports.useRef(),d=f.exports.useRef();d.current=t;var v=function(){St.cancel(u.current)};return f.exports.useEffect(function(){return function(){v()}},[]),function(h){var g=h.which;if([].concat(Fb,[lu,$2,$l,El]).includes(g)){var p=i(),b=Eg(p,r),m=b,y=m.elements,S=m.key2element,x=m.element2key,$=S.get(t),E=aL($,y),w=x.get(E),R=oL(e,a(w,!0).length===1,n,g);if(!R&&g!==$l&&g!==El)return;(Fb.includes(g)||[$l,El].includes(g))&&h.preventDefault();var P=function(O){if(O){var M=O,L=O.querySelector("a");L!=null&&L.getAttribute("href")&&(M=L);var A=x.get(O);l(A),v(),u.current=St(function(){d.current===A&&M.focus()})}};if([$l,El].includes(g)||R.sibling||!E){var N;!E||e==="inline"?N=o.current:N=iL(E);var I,z=bm(N,y);g===$l?I=z[0]:g===El?I=z[z.length-1]:I=kb(N,y,E,R.offset),P(I)}else if(R.inlineTrigger)s(w);else if(R.offset>0)s(w,!0),v(),u.current=St(function(){b=Eg(p,r);var _=E.getAttribute("aria-controls"),O=document.getElementById(_),M=kb(O,b.elements);P(M)},5);else if(R.offset<0){var F=a(w,!0),T=F[F.length-2],D=S.get(T);s(T,!1),P(D)}}c==null||c(h)}}function sL(e){Promise.resolve().then(e)}var Sm="__RC_UTIL_PATH_SPLIT__",Bb=function(t){return t.join(Sm)},cL=function(t){return t.split(Sm)},Mg="rc-menu-more";function uL(){var e=f.exports.useState({}),t=G(e,2),n=t[1],r=f.exports.useRef(new Map),o=f.exports.useRef(new Map),i=f.exports.useState([]),a=G(i,2),l=a[0],s=a[1],c=f.exports.useRef(0),u=f.exports.useRef(!1),d=function(){u.current||n({})},v=f.exports.useCallback(function(S,x){var $=Bb(x);o.current.set($,S),r.current.set(S,$),c.current+=1;var E=c.current;sL(function(){E===c.current&&d()})},[]),h=f.exports.useCallback(function(S,x){var $=Bb(x);o.current.delete($),r.current.delete(S)},[]),g=f.exports.useCallback(function(S){s(S)},[]),p=f.exports.useCallback(function(S,x){var $=r.current.get(S)||"",E=cL($);return x&&l.includes(E[0])&&E.unshift(Mg),E},[l]),b=f.exports.useCallback(function(S,x){return S.some(function($){var E=p($,!0);return E.includes(x)})},[p]),m=function(){var x=Oe(r.current.keys());return l.length&&x.push(Mg),x},y=f.exports.useCallback(function(S){var x="".concat(r.current.get(S)).concat(Sm),$=new Set;return Oe(o.current.keys()).forEach(function(E){E.startsWith(x)&&$.add(o.current.get(E))}),$},[]);return f.exports.useEffect(function(){return function(){u.current=!0}},[]),{registerPath:v,unregisterPath:h,refreshOverflowKeys:g,isSubPathKey:b,getKeyPath:p,getKeys:m,getSubPathKeys:y}}function _l(e){var t=f.exports.useRef(e);t.current=e;var n=f.exports.useCallback(function(){for(var r,o=arguments.length,i=new Array(o),a=0;a1&&(y.motionAppear=!1);var S=y.onVisibleChanged;return y.onVisibleChanged=function(x){return!v.current&&!x&&b(!0),S==null?void 0:S(x)},p?null:C(Is,{mode:i,locked:!v.current,children:C(to,{visible:m,...y,forceRender:s,removeOnLeave:!1,leavedClassName:"".concat(l,"-hidden"),children:function(x){var $=x.className,E=x.style;return C(Cm,{id:t,className:$,style:E,children:o})}})})}var OL=["style","className","title","eventKey","warnKey","disabled","internalPopupClose","children","itemIcon","expandIcon","popupClassName","popupOffset","popupStyle","onClick","onMouseEnter","onMouseLeave","onTitleClick","onTitleMouseEnter","onTitleMouseLeave"],RL=["active"],IL=function(t){var n,r=t.style,o=t.className,i=t.title,a=t.eventKey;t.warnKey;var l=t.disabled,s=t.internalPopupClose,c=t.children,u=t.itemIcon,d=t.expandIcon,v=t.popupClassName,h=t.popupOffset,g=t.popupStyle,p=t.onClick,b=t.onMouseEnter,m=t.onMouseLeave,y=t.onTitleClick,S=t.onTitleMouseEnter,x=t.onTitleMouseLeave,$=Je(t,OL),E=S2(a),w=f.exports.useContext(jr),R=w.prefixCls,P=w.mode,N=w.openKeys,I=w.disabled,z=w.overflowDisabled,F=w.activeKey,T=w.selectedKeys,D=w.itemIcon,_=w.expandIcon,O=w.onItemClick,M=w.onOpenChange,L=w.onActive,A=f.exports.useContext(ym),B=A._internalRenderSubMenuItem,k=f.exports.useContext(w2),j=k.isSubPathKey,H=Xs(),W="".concat(R,"-submenu"),Y=I||l,K=f.exports.useRef(),q=f.exports.useRef(),ee=u!=null?u:D,Z=d!=null?d:_,Q=N.includes(a),ne=!z&&Q,ae=j(T,a),J=E2(a,Y,S,x),re=J.active,fe=Je(J,RL),ve=f.exports.useState(!1),pe=G(ve,2),oe=pe[0],se=pe[1],le=function(_e){Y||se(_e)},Ce=function(_e){le(!0),b==null||b({key:a,domEvent:_e})},ce=function(_e){le(!1),m==null||m({key:a,domEvent:_e})},de=f.exports.useMemo(function(){return re||(P!=="inline"?oe||j([F],a):!1)},[P,re,F,oe,a,j]),xe=M2(H.length),he=function(_e){Y||(y==null||y({key:a,domEvent:_e}),P==="inline"&&M(a,!Q))},ke=_l(function(Ee){p==null||p(nd(Ee)),O(Ee)}),we=function(_e){P!=="inline"&&M(a,_e)},ge=function(){L(a)},Pe=E&&"".concat(E,"-popup"),Se=ie("div",{role:"menuitem",style:xe,className:"".concat(W,"-title"),tabIndex:Y?null:-1,ref:K,title:typeof i=="string"?i:null,"data-menu-id":z&&E?null:E,"aria-expanded":ne,"aria-haspopup":!0,"aria-controls":Pe,"aria-disabled":Y,onClick:he,onFocus:ge,...fe,children:[i,C(O2,{icon:P!=="horizontal"?Z:void 0,props:U(U({},t),{},{isOpen:ne,isSubMenu:!0}),children:C("i",{className:"".concat(W,"-arrow")})})]}),st=f.exports.useRef(P);if(P!=="inline"&&H.length>1?st.current="vertical":st.current=P,!z){var nt=st.current;Se=C(EL,{mode:nt,prefixCls:W,visible:!s&&ne&&P!=="inline",popupClassName:v,popupOffset:h,popupStyle:g,popup:C(Is,{mode:nt==="horizontal"?"vertical":nt,children:C(Cm,{id:Pe,ref:q,children:c})}),disabled:Y,onVisibleChange:we,children:Se})}var Ne=ie(Zr.Item,{role:"none",...$,component:"li",style:r,className:te(W,"".concat(W,"-").concat(P),o,(n={},V(n,"".concat(W,"-open"),ne),V(n,"".concat(W,"-active"),de),V(n,"".concat(W,"-selected"),ae),V(n,"".concat(W,"-disabled"),Y),n)),onMouseEnter:Ce,onMouseLeave:ce,children:[Se,!z&&C(ML,{id:Pe,open:ne,keyPath:H,children:c})]});return B&&(Ne=B(Ne,t,{selected:ae,active:de,open:ne,disabled:Y})),C(Is,{onItemClick:ke,mode:P==="horizontal"?"vertical":P,itemIcon:ee,expandIcon:Z,children:Ne})};function wm(e){var t=e.eventKey,n=e.children,r=Xs(t),o=xm(n,r),i=sf();f.exports.useEffect(function(){if(i)return i.registerPath(t,r),function(){i.unregisterPath(t,r)}},[r]);var a;return i?a=o:a=C(IL,{...e,children:o}),C(x2.Provider,{value:r,children:a})}var PL=["className","title","eventKey","children"],TL=["children"],NL=function(t){var n=t.className,r=t.title;t.eventKey;var o=t.children,i=Je(t,PL),a=f.exports.useContext(jr),l=a.prefixCls,s="".concat(l,"-item-group");return ie("li",{role:"presentation",...i,onClick:function(u){return u.stopPropagation()},className:te(s,n),children:[C("div",{role:"presentation",className:"".concat(s,"-title"),title:typeof r=="string"?r:void 0,children:r}),C("ul",{role:"group",className:"".concat(s,"-list"),children:o})]})};function I2(e){var t=e.children,n=Je(e,TL),r=Xs(n.eventKey),o=xm(t,r),i=sf();return i?o:C(NL,{...lr(n,["warnKey"]),children:o})}function P2(e){var t=e.className,n=e.style,r=f.exports.useContext(jr),o=r.prefixCls,i=sf();return i?null:C("li",{role:"separator",className:te("".concat(o,"-item-divider"),t),style:n})}var _L=["label","children","key","type"];function Og(e){return(e||[]).map(function(t,n){if(t&&Qe(t)==="object"){var r=t,o=r.label,i=r.children,a=r.key,l=r.type,s=Je(r,_L),c=a!=null?a:"tmp-".concat(n);return i||l==="group"?l==="group"?C(I2,{...s,title:o,children:Og(i)},c):C(wm,{...s,title:o,children:Og(i)},c):l==="divider"?C(P2,{...s},c):C(cf,{...s,children:o},c)}return null}).filter(function(t){return t})}function AL(e,t,n){var r=e;return t&&(r=Og(t)),xm(r,n)}var DL=["prefixCls","rootClassName","style","className","tabIndex","items","children","direction","id","mode","inlineCollapsed","disabled","disabledOverflow","subMenuOpenDelay","subMenuCloseDelay","forceSubMenuRender","defaultOpenKeys","openKeys","activeKey","defaultActiveFirst","selectable","multiple","defaultSelectedKeys","selectedKeys","onSelect","onDeselect","inlineIndent","motion","defaultMotions","triggerSubMenuAction","builtinPlacements","itemIcon","expandIcon","overflowedIndicator","overflowedIndicatorPopupClassName","getPopupContainer","onClick","onOpenChange","onKeyDown","openAnimation","openTransitionName","_internalRenderMenuItem","_internalRenderSubMenuItem"],na=[],LL=f.exports.forwardRef(function(e,t){var n,r,o=e,i=o.prefixCls,a=i===void 0?"rc-menu":i,l=o.rootClassName,s=o.style,c=o.className,u=o.tabIndex,d=u===void 0?0:u,v=o.items,h=o.children,g=o.direction,p=o.id,b=o.mode,m=b===void 0?"vertical":b,y=o.inlineCollapsed,S=o.disabled,x=o.disabledOverflow,$=o.subMenuOpenDelay,E=$===void 0?.1:$,w=o.subMenuCloseDelay,R=w===void 0?.1:w,P=o.forceSubMenuRender,N=o.defaultOpenKeys,I=o.openKeys,z=o.activeKey,F=o.defaultActiveFirst,T=o.selectable,D=T===void 0?!0:T,_=o.multiple,O=_===void 0?!1:_,M=o.defaultSelectedKeys,L=o.selectedKeys,A=o.onSelect,B=o.onDeselect,k=o.inlineIndent,j=k===void 0?24:k,H=o.motion,W=o.defaultMotions,Y=o.triggerSubMenuAction,K=Y===void 0?"hover":Y,q=o.builtinPlacements,ee=o.itemIcon,Z=o.expandIcon,Q=o.overflowedIndicator,ne=Q===void 0?"...":Q,ae=o.overflowedIndicatorPopupClassName,J=o.getPopupContainer,re=o.onClick,fe=o.onOpenChange,ve=o.onKeyDown;o.openAnimation,o.openTransitionName;var pe=o._internalRenderMenuItem,oe=o._internalRenderSubMenuItem,se=Je(o,DL),le=f.exports.useMemo(function(){return AL(h,v,na)},[h,v]),Ce=f.exports.useState(!1),ce=G(Ce,2),de=ce[0],xe=ce[1],he=f.exports.useRef(),ke=fL(p),we=g==="rtl",ge=kt(N,{value:I,postState:function(dt){return dt||na}}),Pe=G(ge,2),Se=Pe[0],st=Pe[1],nt=function(dt){var Fe=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;function Ye(){st(dt),fe==null||fe(dt)}Fe?Gn.exports.flushSync(Ye):Ye()},Ne=f.exports.useState(Se),Ee=G(Ne,2),_e=Ee[0],Be=Ee[1],qe=f.exports.useRef(!1),it=f.exports.useMemo(function(){return(m==="inline"||m==="vertical")&&y?["vertical",y]:[m,!1]},[m,y]),ft=G(it,2),ut=ft[0],Ue=ft[1],He=ut==="inline",Xe=f.exports.useState(ut),Le=G(Xe,2),Re=Le[0],be=Le[1],Ae=f.exports.useState(Ue),Me=G(Ae,2),$e=Me[0],Te=Me[1];f.exports.useEffect(function(){be(ut),Te(Ue),qe.current&&(He?st(_e):nt(na))},[ut,Ue]);var ye=f.exports.useState(0),Ge=G(ye,2),Ze=Ge[0],et=Ge[1],ht=Ze>=le.length-1||Re!=="horizontal"||x;f.exports.useEffect(function(){He&&Be(Se)},[Se]),f.exports.useEffect(function(){return qe.current=!0,function(){qe.current=!1}},[]);var mt=uL(),ct=mt.registerPath,We=mt.unregisterPath,Ve=mt.refreshOverflowKeys,vt=mt.isSubPathKey,Ie=mt.getKeyPath,ze=mt.getKeys,Ke=mt.getSubPathKeys,at=f.exports.useMemo(function(){return{registerPath:ct,unregisterPath:We}},[ct,We]),Gt=f.exports.useMemo(function(){return{isSubPathKey:vt}},[vt]);f.exports.useEffect(function(){Ve(ht?na:le.slice(Ze+1).map(function(bt){return bt.key}))},[Ze,ht]);var At=kt(z||F&&((n=le[0])===null||n===void 0?void 0:n.key),{value:z}),Zt=G(At,2),Jt=Zt[0],kn=Zt[1],qn=_l(function(bt){kn(bt)}),pn=_l(function(){kn(void 0)});f.exports.useImperativeHandle(t,function(){return{list:he.current,focus:function(dt){var Fe,Ye=ze(),yt=Eg(Ye,ke),Bt=yt.elements,It=yt.key2element,Kt=yt.element2key,sn=bm(he.current,Bt),Pn=Jt!=null?Jt:sn[0]?Kt.get(sn[0]):(Fe=le.find(function(jn){return!jn.props.disabled}))===null||Fe===void 0?void 0:Fe.key,cn=It.get(Pn);if(Pn&&cn){var Tn;cn==null||(Tn=cn.focus)===null||Tn===void 0||Tn.call(cn,dt)}}}});var Co=kt(M||[],{value:L,postState:function(dt){return Array.isArray(dt)?dt:dt==null?na:[dt]}}),xo=G(Co,2),In=xo[0],wo=xo[1],wr=function(dt){if(D){var Fe=dt.key,Ye=In.includes(Fe),yt;O?Ye?yt=In.filter(function(It){return It!==Fe}):yt=[].concat(Oe(In),[Fe]):yt=[Fe],wo(yt);var Bt=U(U({},dt),{},{selectedKeys:yt});Ye?B==null||B(Bt):A==null||A(Bt)}!O&&Se.length&&Re!=="inline"&&nt(na)},Bn=_l(function(bt){re==null||re(nd(bt)),wr(bt)}),sr=_l(function(bt,dt){var Fe=Se.filter(function(yt){return yt!==bt});if(dt)Fe.push(bt);else if(Re!=="inline"){var Ye=Ke(bt);Fe=Fe.filter(function(yt){return!Ye.has(yt)})}Vs(Se,Fe,!0)||nt(Fe,!0)}),$r=function(dt,Fe){var Ye=Fe!=null?Fe:!Se.includes(dt);sr(dt,Ye)},Ur=lL(Re,Jt,we,ke,he,ze,Ie,kn,$r,ve);f.exports.useEffect(function(){xe(!0)},[]);var Xn=f.exports.useMemo(function(){return{_internalRenderMenuItem:pe,_internalRenderSubMenuItem:oe}},[pe,oe]),$o=Re!=="horizontal"||x?le:le.map(function(bt,dt){return C(Is,{overflowDisabled:dt>Ze,children:bt},bt.key)}),Er=C(Zr,{id:p,ref:he,prefixCls:"".concat(a,"-overflow"),component:"ul",itemComponent:cf,className:te(a,"".concat(a,"-root"),"".concat(a,"-").concat(Re),c,(r={},V(r,"".concat(a,"-inline-collapsed"),$e),V(r,"".concat(a,"-rtl"),we),r),l),dir:g,style:s,role:"menu",tabIndex:d,data:$o,renderRawItem:function(dt){return dt},renderRawRest:function(dt){var Fe=dt.length,Ye=Fe?le.slice(-Fe):null;return C(wm,{eventKey:Mg,title:ne,disabled:ht,internalPopupClose:Fe===0,popupClassName:ae,children:Ye})},maxCount:Re!=="horizontal"||x?Zr.INVALIDATE:Zr.RESPONSIVE,ssr:"full","data-menu-list":!0,onVisibleChange:function(dt){et(dt)},onKeyDown:Ur,...se});return C(ym.Provider,{value:Xn,children:C(y2.Provider,{value:ke,children:ie(Is,{prefixCls:a,rootClassName:l,mode:Re,openKeys:Se,rtl:we,disabled:S,motion:de?H:null,defaultMotions:de?W:null,activeKey:Jt,onActive:qn,onInactive:pn,selectedKeys:In,inlineIndent:j,subMenuOpenDelay:E,subMenuCloseDelay:R,forceSubMenuRender:P,builtinPlacements:q,triggerSubMenuAction:K,getPopupContainer:J,itemIcon:ee,expandIcon:Z,onItemClick:Bn,onOpenChange:sr,children:[C(w2.Provider,{value:Gt,children:Er}),C("div",{style:{display:"none"},"aria-hidden":!0,children:C(C2.Provider,{value:at,children:le})})]})})})}),Qs=LL;Qs.Item=cf;Qs.SubMenu=wm;Qs.ItemGroup=I2;Qs.Divider=P2;var $m={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(Hr,function(){var n=1e3,r=6e4,o=36e5,i="millisecond",a="second",l="minute",s="hour",c="day",u="week",d="month",v="quarter",h="year",g="date",p="Invalid Date",b=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,m=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,y={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(T){var D=["th","st","nd","rd"],_=T%100;return"["+T+(D[(_-20)%10]||D[_]||D[0])+"]"}},S=function(T,D,_){var O=String(T);return!O||O.length>=D?T:""+Array(D+1-O.length).join(_)+T},x={s:S,z:function(T){var D=-T.utcOffset(),_=Math.abs(D),O=Math.floor(_/60),M=_%60;return(D<=0?"+":"-")+S(O,2,"0")+":"+S(M,2,"0")},m:function T(D,_){if(D.date()<_.date())return-T(_,D);var O=12*(_.year()-D.year())+(_.month()-D.month()),M=D.clone().add(O,d),L=_-M<0,A=D.clone().add(O+(L?-1:1),d);return+(-(O+(_-M)/(L?M-A:A-M))||0)},a:function(T){return T<0?Math.ceil(T)||0:Math.floor(T)},p:function(T){return{M:d,y:h,w:u,d:c,D:g,h:s,m:l,s:a,ms:i,Q:v}[T]||String(T||"").toLowerCase().replace(/s$/,"")},u:function(T){return T===void 0}},$="en",E={};E[$]=y;var w="$isDayjsObject",R=function(T){return T instanceof z||!(!T||!T[w])},P=function T(D,_,O){var M;if(!D)return $;if(typeof D=="string"){var L=D.toLowerCase();E[L]&&(M=L),_&&(E[L]=_,M=L);var A=D.split("-");if(!M&&A.length>1)return T(A[0])}else{var B=D.name;E[B]=D,M=B}return!O&&M&&($=M),M||!O&&$},N=function(T,D){if(R(T))return T.clone();var _=typeof D=="object"?D:{};return _.date=T,_.args=arguments,new z(_)},I=x;I.l=P,I.i=R,I.w=function(T,D){return N(T,{locale:D.$L,utc:D.$u,x:D.$x,$offset:D.$offset})};var z=function(){function T(_){this.$L=P(_.locale,null,!0),this.parse(_),this.$x=this.$x||_.x||{},this[w]=!0}var D=T.prototype;return D.parse=function(_){this.$d=function(O){var M=O.date,L=O.utc;if(M===null)return new Date(NaN);if(I.u(M))return new Date;if(M instanceof Date)return new Date(M);if(typeof M=="string"&&!/Z$/i.test(M)){var A=M.match(b);if(A){var B=A[2]-1||0,k=(A[7]||"0").substring(0,3);return L?new Date(Date.UTC(A[1],B,A[3]||1,A[4]||0,A[5]||0,A[6]||0,k)):new Date(A[1],B,A[3]||1,A[4]||0,A[5]||0,A[6]||0,k)}}return new Date(M)}(_),this.init()},D.init=function(){var _=this.$d;this.$y=_.getFullYear(),this.$M=_.getMonth(),this.$D=_.getDate(),this.$W=_.getDay(),this.$H=_.getHours(),this.$m=_.getMinutes(),this.$s=_.getSeconds(),this.$ms=_.getMilliseconds()},D.$utils=function(){return I},D.isValid=function(){return this.$d.toString()!==p},D.isSame=function(_,O){var M=N(_);return this.startOf(O)<=M&&M<=this.endOf(O)},D.isAfter=function(_,O){return N(_)25){var u=a(this).startOf(r).add(1,r).date(c),d=a(this).endOf(n);if(u.isBefore(d))return 1}var v=a(this).startOf(r).date(c).startOf(n).subtract(1,"millisecond"),h=this.diff(v,n,!0);return h<0?a(this).startOf("week").week():Math.ceil(h)},l.weeks=function(s){return s===void 0&&(s=null),this.week(s)}}})})(_2);const kL=_2.exports;var A2={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(Hr,function(){return function(n,r){r.prototype.weekYear=function(){var o=this.month(),i=this.week(),a=this.year();return i===1&&o===11?a+1:o===0&&i>=52?a-1:a}}})})(A2);const BL=A2.exports;var D2={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(Hr,function(){return function(n,r){var o=r.prototype,i=o.format;o.format=function(a){var l=this,s=this.$locale();if(!this.isValid())return i.bind(this)(a);var c=this.$utils(),u=(a||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(d){switch(d){case"Q":return Math.ceil((l.$M+1)/3);case"Do":return s.ordinal(l.$D);case"gggg":return l.weekYear();case"GGGG":return l.isoWeekYear();case"wo":return s.ordinal(l.week(),"W");case"w":case"ww":return c.s(l.week(),d==="w"?1:2,"0");case"W":case"WW":return c.s(l.isoWeek(),d==="W"?1:2,"0");case"k":case"kk":return c.s(String(l.$H===0?24:l.$H),d==="k"?1:2,"0");case"X":return Math.floor(l.$d.getTime()/1e3);case"x":return l.$d.getTime();case"z":return"["+l.offsetName()+"]";case"zzz":return"["+l.offsetName("long")+"]";default:return d}});return i.bind(this)(u)}}})})(D2);const jL=D2.exports;var L2={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(Hr,function(){var n={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},r=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,o=/\d\d/,i=/\d\d?/,a=/\d*[^-_:/,()\s\d]+/,l={},s=function(p){return(p=+p)+(p>68?1900:2e3)},c=function(p){return function(b){this[p]=+b}},u=[/[+-]\d\d:?(\d\d)?|Z/,function(p){(this.zone||(this.zone={})).offset=function(b){if(!b||b==="Z")return 0;var m=b.match(/([+-]|\d\d)/g),y=60*m[1]+(+m[2]||0);return y===0?0:m[0]==="+"?-y:y}(p)}],d=function(p){var b=l[p];return b&&(b.indexOf?b:b.s.concat(b.f))},v=function(p,b){var m,y=l.meridiem;if(y){for(var S=1;S<=24;S+=1)if(p.indexOf(y(S,0,b))>-1){m=S>12;break}}else m=p===(b?"pm":"PM");return m},h={A:[a,function(p){this.afternoon=v(p,!1)}],a:[a,function(p){this.afternoon=v(p,!0)}],S:[/\d/,function(p){this.milliseconds=100*+p}],SS:[o,function(p){this.milliseconds=10*+p}],SSS:[/\d{3}/,function(p){this.milliseconds=+p}],s:[i,c("seconds")],ss:[i,c("seconds")],m:[i,c("minutes")],mm:[i,c("minutes")],H:[i,c("hours")],h:[i,c("hours")],HH:[i,c("hours")],hh:[i,c("hours")],D:[i,c("day")],DD:[o,c("day")],Do:[a,function(p){var b=l.ordinal,m=p.match(/\d+/);if(this.day=m[0],b)for(var y=1;y<=31;y+=1)b(y).replace(/\[|\]/g,"")===p&&(this.day=y)}],M:[i,c("month")],MM:[o,c("month")],MMM:[a,function(p){var b=d("months"),m=(d("monthsShort")||b.map(function(y){return y.slice(0,3)})).indexOf(p)+1;if(m<1)throw new Error;this.month=m%12||m}],MMMM:[a,function(p){var b=d("months").indexOf(p)+1;if(b<1)throw new Error;this.month=b%12||b}],Y:[/[+-]?\d+/,c("year")],YY:[o,function(p){this.year=s(p)}],YYYY:[/\d{4}/,c("year")],Z:u,ZZ:u};function g(p){var b,m;b=p,m=l&&l.formats;for(var y=(p=b.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(P,N,I){var z=I&&I.toUpperCase();return N||m[I]||n[I]||m[z].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(F,T,D){return T||D.slice(1)})})).match(r),S=y.length,x=0;x-1)return new Date((O==="X"?1e3:1)*_);var L=g(O)(_),A=L.year,B=L.month,k=L.day,j=L.hours,H=L.minutes,W=L.seconds,Y=L.milliseconds,K=L.zone,q=new Date,ee=k||(A||B?1:q.getDate()),Z=A||q.getFullYear(),Q=0;A&&!B||(Q=B>0?B-1:q.getMonth());var ne=j||0,ae=H||0,J=W||0,re=Y||0;return K?new Date(Date.UTC(Z,Q,ee,ne,ae,J,re+60*K.offset*1e3)):M?new Date(Date.UTC(Z,Q,ee,ne,ae,J,re)):new Date(Z,Q,ee,ne,ae,J,re)}catch{return new Date("")}}($,R,E),this.init(),z&&z!==!0&&(this.$L=this.locale(z).$L),I&&$!=this.format(R)&&(this.$d=new Date("")),l={}}else if(R instanceof Array)for(var F=R.length,T=1;T<=F;T+=1){w[1]=R[T-1];var D=m.apply(this,w);if(D.isValid()){this.$d=D.$d,this.$L=D.$L,this.init();break}T===F&&(this.$d=new Date(""))}else S.call(this,x)}}})})(L2);const HL=L2.exports;Lt.extend(HL);Lt.extend(jL);Lt.extend(zL);Lt.extend(FL);Lt.extend(kL);Lt.extend(BL);Lt.extend(function(e,t){var n=t.prototype,r=n.format;n.format=function(i){var a=(i||"").replace("Wo","wo");return r.bind(this)(a)}});var WL={bn_BD:"bn-bd",by_BY:"be",en_GB:"en-gb",en_US:"en",fr_BE:"fr",fr_CA:"fr-ca",hy_AM:"hy-am",kmr_IQ:"ku",nl_BE:"nl-be",pt_BR:"pt-br",zh_CN:"zh-cn",zh_HK:"zh-hk",zh_TW:"zh-tw"},ci=function(t){var n=WL[t];return n||t.split("_")[0]},Hb=function(){nx(!1,"Not match any format. Please help to fire a issue about this.")},VL={getNow:function(){return Lt()},getFixedDate:function(t){return Lt(t,["YYYY-M-DD","YYYY-MM-DD"])},getEndDate:function(t){return t.endOf("month")},getWeekDay:function(t){var n=t.locale("en");return n.weekday()+n.localeData().firstDayOfWeek()},getYear:function(t){return t.year()},getMonth:function(t){return t.month()},getDate:function(t){return t.date()},getHour:function(t){return t.hour()},getMinute:function(t){return t.minute()},getSecond:function(t){return t.second()},getMillisecond:function(t){return t.millisecond()},addYear:function(t,n){return t.add(n,"year")},addMonth:function(t,n){return t.add(n,"month")},addDate:function(t,n){return t.add(n,"day")},setYear:function(t,n){return t.year(n)},setMonth:function(t,n){return t.month(n)},setDate:function(t,n){return t.date(n)},setHour:function(t,n){return t.hour(n)},setMinute:function(t,n){return t.minute(n)},setSecond:function(t,n){return t.second(n)},setMillisecond:function(t,n){return t.millisecond(n)},isAfter:function(t,n){return t.isAfter(n)},isValidate:function(t){return t.isValid()},locale:{getWeekFirstDay:function(t){return Lt().locale(ci(t)).localeData().firstDayOfWeek()},getWeekFirstDate:function(t,n){return n.locale(ci(t)).weekday(0)},getWeek:function(t,n){return n.locale(ci(t)).week()},getShortWeekDays:function(t){return Lt().locale(ci(t)).localeData().weekdaysMin()},getShortMonths:function(t){return Lt().locale(ci(t)).localeData().monthsShort()},format:function(t,n,r){return n.locale(ci(t)).format(r)},parse:function(t,n,r){for(var o=ci(t),i=0;i2&&arguments[2]!==void 0?arguments[2]:"0",r=String(e);r.length1&&(a=t.addDate(a,-7)),a}function mn(e,t){var n=t.generateConfig,r=t.locale,o=t.format;return e?typeof o=="function"?o(e):n.locale.format(r.locale,e,o):""}function Vb(e,t,n){var r=t,o=["getHour","getMinute","getSecond","getMillisecond"],i=["setHour","setMinute","setSecond","setMillisecond"];return i.forEach(function(a,l){n?r=e[a](r,e[o[l]](n)):r=e[a](r,0)}),r}function oz(e,t,n,r,o,i){var a=e;function l(d,v,h){var g=i[d](a),p=h.find(function(S){return S.value===g});if(!p||p.disabled){var b=h.filter(function(S){return!S.disabled}),m=Oe(b).reverse(),y=m.find(function(S){return S.value<=g})||b[0];y&&(g=y.value,a=i[v](a,g))}return g}var s=l("getHour","setHour",t()),c=l("getMinute","setMinute",n(s)),u=l("getSecond","setSecond",r(s,c));return l("getMillisecond","setMillisecond",o(s,c,u)),a}function Dc(){return[]}function Lc(e,t){for(var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1,o=arguments.length>4&&arguments[4]!==void 0?arguments[4]:[],i=arguments.length>5&&arguments[5]!==void 0?arguments[5]:2,a=[],l=n>=1?n|0:1,s=e;s<=t;s+=l){var c=o.includes(s);(!c||!r)&&a.push({label:z2(s,i),value:s,disabled:c})}return a}function H2(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0,r=t||{},o=r.use12Hours,i=r.hourStep,a=i===void 0?1:i,l=r.minuteStep,s=l===void 0?1:l,c=r.secondStep,u=c===void 0?1:c,d=r.millisecondStep,v=d===void 0?100:d,h=r.hideDisabledOptions,g=r.disabledTime,p=r.disabledHours,b=r.disabledMinutes,m=r.disabledSeconds,y=f.exports.useMemo(function(){return n||e.getNow()},[n,e]),S=f.exports.useCallback(function(M){var L=(g==null?void 0:g(M))||{};return[L.disabledHours||p||Dc,L.disabledMinutes||b||Dc,L.disabledSeconds||m||Dc,L.disabledMilliseconds||Dc]},[g,p,b,m]),x=f.exports.useMemo(function(){return S(y)},[y,S]),$=G(x,4),E=$[0],w=$[1],R=$[2],P=$[3],N=f.exports.useCallback(function(M,L,A,B){var k=Lc(0,23,a,h,M()),j=o?k.map(function(K){return U(U({},K),{},{label:z2(K.value%12||12,2)})}):k,H=function(q){return Lc(0,59,s,h,L(q))},W=function(q,ee){return Lc(0,59,u,h,A(q,ee))},Y=function(q,ee,Z){return Lc(0,999,v,h,B(q,ee,Z),3)};return[j,H,W,Y]},[h,a,o,v,s,u]),I=f.exports.useMemo(function(){return N(E,w,R,P)},[N,E,w,R,P]),z=G(I,4),F=z[0],T=z[1],D=z[2],_=z[3],O=function(L,A){var B=function(){return F},k=T,j=D,H=_;if(A){var W=S(A),Y=G(W,4),K=Y[0],q=Y[1],ee=Y[2],Z=Y[3],Q=N(K,q,ee,Z),ne=G(Q,4),ae=ne[0],J=ne[1],re=ne[2],fe=ne[3];B=function(){return ae},k=J,j=re,H=fe}var ve=oz(L,B,k,j,H,e);return ve};return[O,F,T,D,_]}function iz(e,t,n){function r(o,i){var a=o.findIndex(function(s){return xi(e,t,s,i,n)});if(a===-1)return[].concat(Oe(o),[i]);var l=Oe(o);return l.splice(a,1),l}return r}var Hi=f.exports.createContext(null);function df(){return f.exports.useContext(Hi)}function il(e,t){var n=e.prefixCls,r=e.generateConfig,o=e.locale,i=e.disabledDate,a=e.minDate,l=e.maxDate,s=e.cellRender,c=e.hoverValue,u=e.hoverRangeValue,d=e.onHover,v=e.values,h=e.pickerValue,g=e.onSelect,p=e.prevIcon,b=e.nextIcon,m=e.superPrevIcon,y=e.superNextIcon,S=r.getNow(),x={now:S,values:v,pickerValue:h,prefixCls:n,disabledDate:i,minDate:a,maxDate:l,cellRender:s,hoverValue:c,hoverRangeValue:u,onHover:d,locale:o,generateConfig:r,onSelect:g,panelType:t,prevIcon:p,nextIcon:b,superPrevIcon:m,superNextIcon:y};return[x,S]}var Ps=f.exports.createContext({});function Zs(e){for(var t=e.rowNum,n=e.colNum,r=e.baseDate,o=e.getCellDate,i=e.prefixColumn,a=e.rowClassName,l=e.titleFormat,s=e.getCellText,c=e.getCellClassName,u=e.headerCells,d=e.cellSelection,v=d===void 0?!0:d,h=e.disabledDate,g=df(),p=g.prefixCls,b=g.panelType,m=g.now,y=g.disabledDate,S=g.cellRender,x=g.onHover,$=g.hoverValue,E=g.hoverRangeValue,w=g.generateConfig,R=g.values,P=g.locale,N=g.onSelect,I=h||y,z="".concat(p,"-cell"),F=f.exports.useContext(Ps),T=F.onCellDblClick,D=function(j){return R.some(function(H){return H&&xi(w,P,j,H,b)})},_=[],O=0;O1&&arguments[1]!==void 0?arguments[1]:!1;Ce(Ee),b==null||b(Ee),_e&&ce(Ee)},xe=function(Ee,_e){ee(Ee),_e&&de(_e),ce(_e,Ee)},he=function(Ee){if(pe(Ee),de(Ee),q!==x){var _e=["decade","year"],Be=[].concat(_e,["month"]),qe={quarter:[].concat(_e,["quarter"]),week:[].concat(Oe(Be),["week"]),date:[].concat(Oe(Be),["date"])},it=qe[x]||Be,ft=it.indexOf(q),ut=it[ft+1];ut&&xe(ut,Ee)}},ke=f.exports.useMemo(function(){var Ne,Ee;if(Array.isArray(w)){var _e=G(w,2);Ne=_e[0],Ee=_e[1]}else Ne=w;return!Ne&&!Ee?null:(Ne=Ne||Ee,Ee=Ee||Ne,o.isAfter(Ne,Ee)?[Ee,Ne]:[Ne,Ee])},[w,o]),we=GL(R,P,N),ge=z[Z]||hz[Z]||ff,Pe=f.exports.useContext(Ps),Se=f.exports.useMemo(function(){return U(U({},Pe),{},{hideHeader:F})},[Pe,F]),st="".concat(T,"-panel"),nt=k2(e,["showWeek","prevIcon","nextIcon","superPrevIcon","superNextIcon","disabledDate","minDate","maxDate","onHover"]);return C(Ps.Provider,{value:Se,children:C("div",{ref:D,tabIndex:s,className:te(st,V({},"".concat(st,"-rtl"),i==="rtl")),children:C(ge,{...nt,showTime:H,prefixCls:T,locale:k,generateConfig:o,onModeChange:xe,pickerValue:le,onPickerValueChange:function(Ee){de(Ee,!0)},value:fe[0],onSelect:he,values:fe,cellRender:we,hoverRangeValue:ke,hoverValue:E})})})}var yz=f.exports.memo(f.exports.forwardRef(mz));const V2=f.exports.createContext(null),bz=V2.Provider,U2=f.exports.createContext(null),Sz=U2.Provider;var Cz=["prefixCls","className","style","checked","disabled","defaultChecked","type","title","onChange"],xz=f.exports.forwardRef(function(e,t){var n,r=e.prefixCls,o=r===void 0?"rc-checkbox":r,i=e.className,a=e.style,l=e.checked,s=e.disabled,c=e.defaultChecked,u=c===void 0?!1:c,d=e.type,v=d===void 0?"checkbox":d,h=e.title,g=e.onChange,p=Je(e,Cz),b=f.exports.useRef(null),m=kt(u,{value:l}),y=G(m,2),S=y[0],x=y[1];f.exports.useImperativeHandle(t,function(){return{focus:function(){var R;(R=b.current)===null||R===void 0||R.focus()},blur:function(){var R;(R=b.current)===null||R===void 0||R.blur()},input:b.current}});var $=te(o,i,(n={},V(n,"".concat(o,"-checked"),S),V(n,"".concat(o,"-disabled"),s),n)),E=function(R){s||("checked"in e||x(R.target.checked),g==null||g({target:U(U({},e),{},{type:v,checked:R.target.checked}),stopPropagation:function(){R.stopPropagation()},preventDefault:function(){R.preventDefault()},nativeEvent:R.nativeEvent}))};return ie("span",{className:$,title:h,style:a,children:[C("input",{...p,className:"".concat(o,"-input"),ref:b,onChange:E,disabled:s,checked:!!S,type:v}),C("span",{className:"".concat(o,"-inner")})]})});const wz=e=>{const{componentCls:t,antCls:n}=e,r=`${t}-group`;return{[r]:Object.assign(Object.assign({},Qt(e)),{display:"inline-block",fontSize:0,[`&${r}-rtl`]:{direction:"rtl"},[`${n}-badge ${n}-badge-count`]:{zIndex:1},[`> ${n}-badge:not(:first-child) > ${n}-button-wrapper`]:{borderInlineStart:"none"}})}},$z=e=>{const{componentCls:t,wrapperMarginInlineEnd:n,colorPrimary:r,radioSize:o,motionDurationSlow:i,motionDurationMid:a,motionEaseInOutCirc:l,colorBgContainer:s,colorBorder:c,lineWidth:u,colorBgContainerDisabled:d,colorTextDisabled:v,paddingXS:h,dotColorDisabled:g,lineType:p,radioColor:b,radioBgColor:m,calc:y}=e,S=`${t}-inner`,x=4,$=y(o).sub(y(x).mul(2)),E=y(1).mul(o).equal();return{[`${t}-wrapper`]:Object.assign(Object.assign({},Qt(e)),{display:"inline-flex",alignItems:"baseline",marginInlineStart:0,marginInlineEnd:n,cursor:"pointer",[`&${t}-wrapper-rtl`]:{direction:"rtl"},"&-disabled":{cursor:"not-allowed",color:e.colorTextDisabled},"&::after":{display:"inline-block",width:0,overflow:"hidden",content:'"\\a0"'},[`${t}-checked::after`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,width:"100%",height:"100%",border:`${X(u)} ${p} ${r}`,borderRadius:"50%",visibility:"hidden",content:'""'},[t]:Object.assign(Object.assign({},Qt(e)),{position:"relative",display:"inline-block",outline:"none",cursor:"pointer",alignSelf:"center",borderRadius:"50%"}),[`${t}-wrapper:hover &,
+ &:hover ${S}`]:{borderColor:r},[`${t}-input:focus-visible + ${S}`]:Object.assign({},Yh(e)),[`${t}:hover::after, ${t}-wrapper:hover &::after`]:{visibility:"visible"},[`${t}-inner`]:{"&::after":{boxSizing:"border-box",position:"absolute",insetBlockStart:"50%",insetInlineStart:"50%",display:"block",width:E,height:E,marginBlockStart:y(1).mul(o).div(-2).equal(),marginInlineStart:y(1).mul(o).div(-2).equal(),backgroundColor:b,borderBlockStart:0,borderInlineStart:0,borderRadius:E,transform:"scale(0)",opacity:0,transition:`all ${i} ${l}`,content:'""'},boxSizing:"border-box",position:"relative",insetBlockStart:0,insetInlineStart:0,display:"block",width:E,height:E,backgroundColor:s,borderColor:c,borderStyle:"solid",borderWidth:u,borderRadius:"50%",transition:`all ${a}`},[`${t}-input`]:{position:"absolute",inset:0,zIndex:1,cursor:"pointer",opacity:0},[`${t}-checked`]:{[S]:{borderColor:r,backgroundColor:m,"&::after":{transform:`scale(${e.calc(e.dotSize).div(o).equal()})`,opacity:1,transition:`all ${i} ${l}`}}},[`${t}-disabled`]:{cursor:"not-allowed",[S]:{backgroundColor:d,borderColor:c,cursor:"not-allowed","&::after":{backgroundColor:g}},[`${t}-input`]:{cursor:"not-allowed"},[`${t}-disabled + span`]:{color:v,cursor:"not-allowed"},[`&${t}-checked`]:{[S]:{"&::after":{transform:`scale(${y($).div(o).equal({unit:!1})})`}}}},[`span${t} + *`]:{paddingInlineStart:h,paddingInlineEnd:h}})}},Ez=e=>{const{buttonColor:t,controlHeight:n,componentCls:r,lineWidth:o,lineType:i,colorBorder:a,motionDurationSlow:l,motionDurationMid:s,buttonPaddingInline:c,fontSize:u,buttonBg:d,fontSizeLG:v,controlHeightLG:h,controlHeightSM:g,paddingXS:p,borderRadius:b,borderRadiusSM:m,borderRadiusLG:y,buttonCheckedBg:S,buttonSolidCheckedColor:x,colorTextDisabled:$,colorBgContainerDisabled:E,buttonCheckedBgDisabled:w,buttonCheckedColorDisabled:R,colorPrimary:P,colorPrimaryHover:N,colorPrimaryActive:I,buttonSolidCheckedBg:z,buttonSolidCheckedHoverBg:F,buttonSolidCheckedActiveBg:T,calc:D}=e;return{[`${r}-button-wrapper`]:{position:"relative",display:"inline-block",height:n,margin:0,paddingInline:c,paddingBlock:0,color:t,fontSize:u,lineHeight:X(D(n).sub(D(o).mul(2)).equal()),background:d,border:`${X(o)} ${i} ${a}`,borderBlockStartWidth:D(o).add(.02).equal(),borderInlineStartWidth:0,borderInlineEndWidth:o,cursor:"pointer",transition:[`color ${s}`,`background ${s}`,`box-shadow ${s}`].join(","),a:{color:t},[`> ${r}-button`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,zIndex:-1,width:"100%",height:"100%"},"&:not(:first-child)":{"&::before":{position:"absolute",insetBlockStart:D(o).mul(-1).equal(),insetInlineStart:D(o).mul(-1).equal(),display:"block",boxSizing:"content-box",width:1,height:"100%",paddingBlock:o,paddingInline:0,backgroundColor:a,transition:`background-color ${l}`,content:'""'}},"&:first-child":{borderInlineStart:`${X(o)} ${i} ${a}`,borderStartStartRadius:b,borderEndStartRadius:b},"&:last-child":{borderStartEndRadius:b,borderEndEndRadius:b},"&:first-child:last-child":{borderRadius:b},[`${r}-group-large &`]:{height:h,fontSize:v,lineHeight:X(D(h).sub(D(o).mul(2)).equal()),"&:first-child":{borderStartStartRadius:y,borderEndStartRadius:y},"&:last-child":{borderStartEndRadius:y,borderEndEndRadius:y}},[`${r}-group-small &`]:{height:g,paddingInline:D(p).sub(o).equal(),paddingBlock:0,lineHeight:X(D(g).sub(D(o).mul(2)).equal()),"&:first-child":{borderStartStartRadius:m,borderEndStartRadius:m},"&:last-child":{borderStartEndRadius:m,borderEndEndRadius:m}},"&:hover":{position:"relative",color:P},"&:has(:focus-visible)":Object.assign({},Yh(e)),[`${r}-inner, input[type='checkbox'], input[type='radio']`]:{width:0,height:0,opacity:0,pointerEvents:"none"},[`&-checked:not(${r}-button-wrapper-disabled)`]:{zIndex:1,color:P,background:S,borderColor:P,"&::before":{backgroundColor:P},"&:first-child":{borderColor:P},"&:hover":{color:N,borderColor:N,"&::before":{backgroundColor:N}},"&:active":{color:I,borderColor:I,"&::before":{backgroundColor:I}}},[`${r}-group-solid &-checked:not(${r}-button-wrapper-disabled)`]:{color:x,background:z,borderColor:z,"&:hover":{color:x,background:F,borderColor:F},"&:active":{color:x,background:T,borderColor:T}},"&-disabled":{color:$,backgroundColor:E,borderColor:a,cursor:"not-allowed","&:first-child, &:hover":{color:$,backgroundColor:E,borderColor:a}},[`&-disabled${r}-button-wrapper-checked`]:{color:R,backgroundColor:w,borderColor:a,boxShadow:"none"}}}},Mz=e=>{const{wireframe:t,padding:n,marginXS:r,lineWidth:o,fontSizeLG:i,colorText:a,colorBgContainer:l,colorTextDisabled:s,controlItemBgActiveDisabled:c,colorTextLightSolid:u,colorPrimary:d,colorPrimaryHover:v,colorPrimaryActive:h,colorWhite:g}=e,p=4,b=i,m=t?b-p*2:b-(p+o)*2;return{radioSize:b,dotSize:m,dotColorDisabled:s,buttonSolidCheckedColor:u,buttonSolidCheckedBg:d,buttonSolidCheckedHoverBg:v,buttonSolidCheckedActiveBg:h,buttonBg:l,buttonCheckedBg:l,buttonColor:a,buttonCheckedBgDisabled:c,buttonCheckedColorDisabled:s,buttonPaddingInline:n-o,wrapperMarginInlineEnd:r,radioColor:t?d:g,radioBgColor:t?l:d}},Y2=vn("Radio",e=>{const{controlOutline:t,controlOutlineWidth:n}=e,r=`0 0 0 ${X(n)} ${t}`,i=$t(e,{radioFocusShadow:r,radioButtonFocusShadow:r});return[wz(i),$z(i),Ez(i)]},Mz,{unitless:{radioSize:!0,dotSize:!0}});var Oz=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var n,r;const o=f.exports.useContext(V2),i=f.exports.useContext(U2),{getPrefixCls:a,direction:l,radio:s}=f.exports.useContext(ot),c=f.exports.useRef(null),u=xr(t,c),{isFormItemInput:d}=f.exports.useContext(Jr),v=T=>{var D,_;(D=e.onChange)===null||D===void 0||D.call(e,T),(_=o==null?void 0:o.onChange)===null||_===void 0||_.call(o,T)},{prefixCls:h,className:g,rootClassName:p,children:b,style:m,title:y}=e,S=Oz(e,["prefixCls","className","rootClassName","children","style","title"]),x=a("radio",h),$=((o==null?void 0:o.optionType)||i)==="button",E=$?`${x}-button`:x,w=no(x),[R,P,N]=Y2(x,w),I=Object.assign({},S),z=f.exports.useContext(rl);o&&(I.name=o.name,I.onChange=v,I.checked=e.value===o.value,I.disabled=(n=I.disabled)!==null&&n!==void 0?n:o.disabled),I.disabled=(r=I.disabled)!==null&&r!==void 0?r:z;const F=te(`${E}-wrapper`,{[`${E}-wrapper-checked`]:I.checked,[`${E}-wrapper-disabled`]:I.disabled,[`${E}-wrapper-rtl`]:l==="rtl",[`${E}-wrapper-in-form-item`]:d},s==null?void 0:s.className,g,p,P,N,w);return R(C(Qh,{component:"Radio",disabled:I.disabled,children:ie("label",{className:F,style:Object.assign(Object.assign({},s==null?void 0:s.style),m),onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave,title:y,children:[C(xz,{...Object.assign({},I,{className:te(I.className,!$&&Xh),type:"radio",prefixCls:E,ref:u})}),b!==void 0?C("span",{children:b}):null]})}))},Iz=f.exports.forwardRef(Rz),rd=Iz,Pz=f.exports.forwardRef((e,t)=>{const{getPrefixCls:n,direction:r}=f.exports.useContext(ot),[o,i]=kt(e.defaultValue,{value:e.value}),a=T=>{const D=o,_=T.target.value;"value"in e||i(_);const{onChange:O}=e;O&&_!==D&&O(T)},{prefixCls:l,className:s,rootClassName:c,options:u,buttonStyle:d="outline",disabled:v,children:h,size:g,style:p,id:b,onMouseEnter:m,onMouseLeave:y,onFocus:S,onBlur:x}=e,$=n("radio",l),E=`${$}-group`,w=no($),[R,P,N]=Y2($,w);let I=h;u&&u.length>0&&(I=u.map(T=>typeof T=="string"||typeof T=="number"?C(rd,{prefixCls:$,disabled:v,value:T,checked:o===T,children:T},T.toString()):C(rd,{prefixCls:$,disabled:T.disabled||v,value:T.value,checked:o===T.value,title:T.title,style:T.style,id:T.id,required:T.required,children:T.label},`radio-group-value-options-${T.value}`)));const z=So(g),F=te(E,`${E}-${d}`,{[`${E}-${z}`]:z,[`${E}-rtl`]:r==="rtl"},s,c,P,N,w);return R(C("div",{...Object.assign({},Ka(e,{aria:!0,data:!0}),{className:F,style:p,onMouseEnter:m,onMouseLeave:y,onFocus:S,onBlur:x,id:b,ref:t}),children:C(bz,{value:{onChange:a,value:o,disabled:e.disabled,name:e.name,optionType:e.optionType},children:I})}))}),G2=f.exports.memo(Pz);var Tz=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{getPrefixCls:n}=f.exports.useContext(ot),{prefixCls:r}=e,o=Tz(e,["prefixCls"]),i=n("radio",r);return C(Sz,{value:"button",children:C(rd,{...Object.assign({prefixCls:i},o,{type:"radio",ref:t})})})},Ig=f.exports.forwardRef(Nz),Om=rd;Om.Button=Ig;Om.Group=G2;Om.__ANT_RADIO=!0;const _z=10,Az=20;function Dz(e){const{fullscreen:t,validRange:n,generateConfig:r,locale:o,prefixCls:i,value:a,onChange:l,divRef:s}=e,c=r.getYear(a||r.getNow());let u=c-_z,d=u+Az;n&&(u=r.getYear(n[0]),d=r.getYear(n[1])+1);const v=o&&o.year==="\u5E74"?"\u5E74":"",h=[];for(let g=u;g{let p=r.setYear(a,g);if(n){const[b,m]=n,y=r.getYear(p),S=r.getMonth(p);y===r.getYear(m)&&S>r.getMonth(m)&&(p=r.setMonth(p,r.getMonth(m))),y===r.getYear(b)&&Ss.current})}function Lz(e){const{prefixCls:t,fullscreen:n,validRange:r,value:o,generateConfig:i,locale:a,onChange:l,divRef:s}=e,c=i.getMonth(o||i.getNow());let u=0,d=11;if(r){const[g,p]=r,b=i.getYear(o);i.getYear(p)===b&&(d=i.getMonth(p)),i.getYear(g)===b&&(u=i.getMonth(g))}const v=a.shortMonths||i.locale.getShortMonths(a.locale),h=[];for(let g=u;g<=d;g+=1)h.push({label:v[g],value:g});return C(r2,{size:n?void 0:"small",className:`${t}-month-select`,value:c,options:h,onChange:g=>{l(i.setMonth(o,g))},getPopupContainer:()=>s.current})}function zz(e){const{prefixCls:t,locale:n,mode:r,fullscreen:o,onModeChange:i}=e;return ie(G2,{onChange:a=>{let{target:{value:l}}=a;i(l)},value:r,size:o?void 0:"small",className:`${t}-mode-switch`,children:[C(Ig,{value:"month",children:n.month}),C(Ig,{value:"year",children:n.year})]})}function Fz(e){const{prefixCls:t,fullscreen:n,mode:r,onChange:o,onModeChange:i}=e,a=f.exports.useRef(null),l=f.exports.useContext(Jr),s=f.exports.useMemo(()=>Object.assign(Object.assign({},l),{isFormItemInput:!1}),[l]),c=Object.assign(Object.assign({},e),{fullscreen:n,divRef:a});return ie("div",{className:`${t}-header`,ref:a,children:[ie(Jr.Provider,{value:s,children:[C(Dz,{...Object.assign({},c,{onChange:u=>{o(u,"year")}})}),r==="month"&&C(Lz,{...Object.assign({},c,{onChange:u=>{o(u,"month")}})})]}),C(zz,{...Object.assign({},c,{onModeChange:i})})]})}function K2(e){return $t(e,{inputAffixPadding:e.paddingXXS})}const q2=e=>{const{controlHeight:t,fontSize:n,lineHeight:r,lineWidth:o,controlHeightSM:i,controlHeightLG:a,fontSizeLG:l,lineHeightLG:s,paddingSM:c,controlPaddingHorizontalSM:u,controlPaddingHorizontal:d,colorFillAlter:v,colorPrimaryHover:h,colorPrimary:g,controlOutlineWidth:p,controlOutline:b,colorErrorOutline:m,colorWarningOutline:y,colorBgContainer:S}=e;return{paddingBlock:Math.max(Math.round((t-n*r)/2*10)/10-o,0),paddingBlockSM:Math.max(Math.round((i-n*r)/2*10)/10-o,0),paddingBlockLG:Math.ceil((a-l*s)/2*10)/10-o,paddingInline:c-o,paddingInlineSM:u-o,paddingInlineLG:d-o,addonBg:v,activeBorderColor:g,hoverBorderColor:h,activeShadow:`0 0 0 ${p}px ${b}`,errorActiveShadow:`0 0 0 ${p}px ${m}`,warningActiveShadow:`0 0 0 ${p}px ${y}`,hoverBg:S,activeBg:S,inputFontSize:n,inputFontSizeLG:l,inputFontSizeSM:n}},kz=e=>({borderColor:e.hoverBorderColor,backgroundColor:e.hoverBg}),Rm=e=>({color:e.colorTextDisabled,backgroundColor:e.colorBgContainerDisabled,borderColor:e.colorBorder,boxShadow:"none",cursor:"not-allowed",opacity:1,"input[disabled]":{cursor:"not-allowed"},"&:hover:not([disabled])":Object.assign({},kz($t(e,{hoverBorderColor:e.colorBorder,hoverBg:e.colorBgContainerDisabled})))}),X2=(e,t)=>({background:e.colorBgContainer,borderWidth:e.lineWidth,borderStyle:e.lineType,borderColor:t.borderColor,"&:hover":{borderColor:t.hoverBorderColor,backgroundColor:e.hoverBg},"&:focus, &:focus-within":{borderColor:t.activeBorderColor,boxShadow:t.activeShadow,outline:0,backgroundColor:e.activeBg}}),Ub=(e,t)=>({[`&${e.componentCls}-status-${t.status}:not(${e.componentCls}-disabled)`]:Object.assign(Object.assign({},X2(e,t)),{[`${e.componentCls}-prefix, ${e.componentCls}-suffix`]:{color:t.affixColor}})}),Q2=(e,t)=>({"&-outlined":Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},X2(e,{borderColor:e.colorBorder,hoverBorderColor:e.hoverBorderColor,activeBorderColor:e.activeBorderColor,activeShadow:e.activeShadow})),{[`&${e.componentCls}-disabled, &[disabled]`]:Object.assign({},Rm(e))}),Ub(e,{status:"error",borderColor:e.colorError,hoverBorderColor:e.colorErrorBorderHover,activeBorderColor:e.colorError,activeShadow:e.errorActiveShadow,affixColor:e.colorError})),Ub(e,{status:"warning",borderColor:e.colorWarning,hoverBorderColor:e.colorWarningBorderHover,activeBorderColor:e.colorWarning,activeShadow:e.warningActiveShadow,affixColor:e.colorWarning})),t)}),Yb=(e,t)=>({[`&${e.componentCls}-group-wrapper-status-${t.status}`]:{[`${e.componentCls}-group-addon`]:{borderColor:t.addonBorderColor,color:t.addonColor}}}),Bz=e=>({"&-outlined":Object.assign(Object.assign(Object.assign({[`${e.componentCls}-group`]:{"&-addon":{background:e.addonBg,border:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`},"&-addon:first-child":{borderInlineEnd:0},"&-addon:last-child":{borderInlineStart:0}}},Yb(e,{status:"error",addonBorderColor:e.colorError,addonColor:e.colorErrorText})),Yb(e,{status:"warning",addonBorderColor:e.colorWarning,addonColor:e.colorWarningText})),{[`&${e.componentCls}-group-wrapper-disabled`]:{[`${e.componentCls}-group-addon`]:Object.assign({},Rm(e))}})}),Z2=(e,t)=>({"&-borderless":Object.assign({background:"transparent",border:"none","&:focus, &:focus-within":{outline:"none"},[`&${e.componentCls}-disabled, &[disabled]`]:{color:e.colorTextDisabled}},t)}),J2=(e,t)=>({background:t.bg,borderWidth:e.lineWidth,borderStyle:e.lineType,borderColor:"transparent",["input&, & input, textarea&, & textarea"]:{color:t==null?void 0:t.inputColor},"&:hover":{background:t.hoverBg},"&:focus, &:focus-within":{outline:0,borderColor:t.activeBorderColor,backgroundColor:e.activeBg}}),Gb=(e,t)=>({[`&${e.componentCls}-status-${t.status}:not(${e.componentCls}-disabled)`]:Object.assign(Object.assign({},J2(e,t)),{[`${e.componentCls}-prefix, ${e.componentCls}-suffix`]:{color:t.affixColor}})}),e$=(e,t)=>({"&-filled":Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},J2(e,{bg:e.colorFillTertiary,hoverBg:e.colorFillSecondary,activeBorderColor:e.colorPrimary})),{[`&${e.componentCls}-disabled, &[disabled]`]:Object.assign({},Rm(e))}),Gb(e,{status:"error",bg:e.colorErrorBg,hoverBg:e.colorErrorBgHover,activeBorderColor:e.colorError,inputColor:e.colorErrorText,affixColor:e.colorError})),Gb(e,{status:"warning",bg:e.colorWarningBg,hoverBg:e.colorWarningBgHover,activeBorderColor:e.colorWarning,inputColor:e.colorWarningText,affixColor:e.colorWarning})),t)}),Kb=(e,t)=>({[`&${e.componentCls}-group-wrapper-status-${t.status}`]:{[`${e.componentCls}-group-addon`]:{background:t.addonBg,color:t.addonColor}}}),jz=e=>({"&-filled":Object.assign(Object.assign(Object.assign({[`${e.componentCls}-group`]:{"&-addon":{background:e.colorFillTertiary},[`${e.componentCls}-filled:not(:focus):not(:focus-within)`]:{"&:not(:first-child)":{borderInlineStart:`${X(e.lineWidth)} ${e.lineType} ${e.colorSplit}`},"&:not(:last-child)":{borderInlineEnd:`${X(e.lineWidth)} ${e.lineType} ${e.colorSplit}`}}}},Kb(e,{status:"error",addonBg:e.colorErrorBg,addonColor:e.colorErrorText})),Kb(e,{status:"warning",addonBg:e.colorWarningBg,addonColor:e.colorWarningText})),{[`&${e.componentCls}-group-wrapper-disabled`]:{[`${e.componentCls}-group`]:{"&-addon":{background:e.colorFillTertiary,color:e.colorTextDisabled},"&-addon:first-child":{borderInlineStart:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderTop:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderBottom:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`},"&-addon:last-child":{borderInlineEnd:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderTop:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderBottom:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`}}}})}),t$=e=>({"&::-moz-placeholder":{opacity:1},"&::placeholder":{color:e,userSelect:"none"},"&:placeholder-shown":{textOverflow:"ellipsis"}}),n$=e=>{const{paddingBlockLG:t,lineHeightLG:n,borderRadiusLG:r,paddingInlineLG:o}=e;return{padding:`${X(t)} ${X(o)}`,fontSize:e.inputFontSizeLG,lineHeight:n,borderRadius:r}},r$=e=>({padding:`${X(e.paddingBlockSM)} ${X(e.paddingInlineSM)}`,fontSize:e.inputFontSizeSM,borderRadius:e.borderRadiusSM}),o$=e=>Object.assign(Object.assign({position:"relative",display:"inline-block",width:"100%",minWidth:0,padding:`${X(e.paddingBlock)} ${X(e.paddingInline)}`,color:e.colorText,fontSize:e.inputFontSize,lineHeight:e.lineHeight,borderRadius:e.borderRadius,transition:`all ${e.motionDurationMid}`},t$(e.colorTextPlaceholder)),{"textarea&":{maxWidth:"100%",height:"auto",minHeight:e.controlHeight,lineHeight:e.lineHeight,verticalAlign:"bottom",transition:`all ${e.motionDurationSlow}, height 0s`,resize:"vertical"},"&-lg":Object.assign({},n$(e)),"&-sm":Object.assign({},r$(e)),"&-rtl":{direction:"rtl"},"&-textarea-rtl":{direction:"rtl"}}),Hz=e=>{const{componentCls:t,antCls:n}=e;return{position:"relative",display:"table",width:"100%",borderCollapse:"separate",borderSpacing:0,["&[class*='col-']"]:{paddingInlineEnd:e.paddingXS,"&:last-child":{paddingInlineEnd:0}},[`&-lg ${t}, &-lg > ${t}-group-addon`]:Object.assign({},n$(e)),[`&-sm ${t}, &-sm > ${t}-group-addon`]:Object.assign({},r$(e)),[`&-lg ${n}-select-single ${n}-select-selector`]:{height:e.controlHeightLG},[`&-sm ${n}-select-single ${n}-select-selector`]:{height:e.controlHeightSM},[`> ${t}`]:{display:"table-cell","&:not(:first-child):not(:last-child)":{borderRadius:0}},[`${t}-group`]:{["&-addon, &-wrap"]:{display:"table-cell",width:1,whiteSpace:"nowrap",verticalAlign:"middle","&:not(:first-child):not(:last-child)":{borderRadius:0}},"&-wrap > *":{display:"block !important"},"&-addon":{position:"relative",padding:`0 ${X(e.paddingInline)}`,color:e.colorText,fontWeight:"normal",fontSize:e.inputFontSize,textAlign:"center",borderRadius:e.borderRadius,transition:`all ${e.motionDurationSlow}`,lineHeight:1,[`${n}-select`]:{margin:`${X(e.calc(e.paddingBlock).add(1).mul(-1).equal())} ${X(e.calc(e.paddingInline).mul(-1).equal())}`,[`&${n}-select-single:not(${n}-select-customize-input):not(${n}-pagination-size-changer)`]:{[`${n}-select-selector`]:{backgroundColor:"inherit",border:`${X(e.lineWidth)} ${e.lineType} transparent`,boxShadow:"none"}},"&-open, &-focused":{[`${n}-select-selector`]:{color:e.colorPrimary}}},[`${n}-cascader-picker`]:{margin:`-9px ${X(e.calc(e.paddingInline).mul(-1).equal())}`,backgroundColor:"transparent",[`${n}-cascader-input`]:{textAlign:"start",border:0,boxShadow:"none"}}}},[`${t}`]:{width:"100%",marginBottom:0,textAlign:"inherit","&:focus":{zIndex:1,borderInlineEndWidth:1},"&:hover":{zIndex:1,borderInlineEndWidth:1,[`${t}-search-with-button &`]:{zIndex:0}}},[`> ${t}:first-child, ${t}-group-addon:first-child`]:{borderStartEndRadius:0,borderEndEndRadius:0,[`${n}-select ${n}-select-selector`]:{borderStartEndRadius:0,borderEndEndRadius:0}},[`> ${t}-affix-wrapper`]:{[`&:not(:first-child) ${t}`]:{borderStartStartRadius:0,borderEndStartRadius:0},[`&:not(:last-child) ${t}`]:{borderStartEndRadius:0,borderEndEndRadius:0}},[`> ${t}:last-child, ${t}-group-addon:last-child`]:{borderStartStartRadius:0,borderEndStartRadius:0,[`${n}-select ${n}-select-selector`]:{borderStartStartRadius:0,borderEndStartRadius:0}},[`${t}-affix-wrapper`]:{"&:not(:last-child)":{borderStartEndRadius:0,borderEndEndRadius:0,[`${t}-search &`]:{borderStartStartRadius:e.borderRadius,borderEndStartRadius:e.borderRadius}},[`&:not(:first-child), ${t}-search &:not(:first-child)`]:{borderStartStartRadius:0,borderEndStartRadius:0}},[`&${t}-group-compact`]:Object.assign(Object.assign({display:"block"},Us()),{[`${t}-group-addon, ${t}-group-wrap, > ${t}`]:{"&:not(:first-child):not(:last-child)":{borderInlineEndWidth:e.lineWidth,"&:hover":{zIndex:1},"&:focus":{zIndex:1}}},"& > *":{display:"inline-block",float:"none",verticalAlign:"top",borderRadius:0},[`
+ & > ${t}-affix-wrapper,
+ & > ${t}-number-affix-wrapper,
+ & > ${n}-picker-range
+ `]:{display:"inline-flex"},"& > *:not(:last-child)":{marginInlineEnd:e.calc(e.lineWidth).mul(-1).equal(),borderInlineEndWidth:e.lineWidth},[`${t}`]:{float:"none"},[`& > ${n}-select > ${n}-select-selector,
+ & > ${n}-select-auto-complete ${t},
+ & > ${n}-cascader-picker ${t},
+ & > ${t}-group-wrapper ${t}`]:{borderInlineEndWidth:e.lineWidth,borderRadius:0,"&:hover":{zIndex:1},"&:focus":{zIndex:1}},[`& > ${n}-select-focused`]:{zIndex:1},[`& > ${n}-select > ${n}-select-arrow`]:{zIndex:1},[`& > *:first-child,
+ & > ${n}-select:first-child > ${n}-select-selector,
+ & > ${n}-select-auto-complete:first-child ${t},
+ & > ${n}-cascader-picker:first-child ${t}`]:{borderStartStartRadius:e.borderRadius,borderEndStartRadius:e.borderRadius},[`& > *:last-child,
+ & > ${n}-select:last-child > ${n}-select-selector,
+ & > ${n}-cascader-picker:last-child ${t},
+ & > ${n}-cascader-picker-focused:last-child ${t}`]:{borderInlineEndWidth:e.lineWidth,borderStartEndRadius:e.borderRadius,borderEndEndRadius:e.borderRadius},[`& > ${n}-select-auto-complete ${t}`]:{verticalAlign:"top"},[`${t}-group-wrapper + ${t}-group-wrapper`]:{marginInlineStart:e.calc(e.lineWidth).mul(-1).equal(),[`${t}-affix-wrapper`]:{borderRadius:0}},[`${t}-group-wrapper:not(:last-child)`]:{[`&${t}-search > ${t}-group`]:{[`& > ${t}-group-addon > ${t}-search-button`]:{borderRadius:0},[`& > ${t}`]:{borderStartStartRadius:e.borderRadius,borderStartEndRadius:0,borderEndEndRadius:0,borderEndStartRadius:e.borderRadius}}}})}},Wz=e=>{const{componentCls:t,controlHeightSM:n,lineWidth:r,calc:o}=e,i=16,a=o(n).sub(o(r).mul(2)).sub(i).div(2).equal();return{[t]:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},Qt(e)),o$(e)),Q2(e)),e$(e)),Z2(e)),{'&[type="color"]':{height:e.controlHeight,[`&${t}-lg`]:{height:e.controlHeightLG},[`&${t}-sm`]:{height:n,paddingTop:a,paddingBottom:a}},'&[type="search"]::-webkit-search-cancel-button, &[type="search"]::-webkit-search-decoration':{"-webkit-appearance":"none"}})}},Vz=e=>{const{componentCls:t}=e;return{[`${t}-clear-icon`]:{margin:0,color:e.colorTextQuaternary,fontSize:e.fontSizeIcon,verticalAlign:-1,cursor:"pointer",transition:`color ${e.motionDurationSlow}`,"&:hover":{color:e.colorTextTertiary},"&:active":{color:e.colorText},"&-hidden":{visibility:"hidden"},"&-has-suffix":{margin:`0 ${X(e.inputAffixPadding)}`}}}},Uz=e=>{const{componentCls:t,inputAffixPadding:n,colorTextDescription:r,motionDurationSlow:o,colorIcon:i,colorIconHover:a,iconCls:l}=e;return{[`${t}-affix-wrapper`]:Object.assign(Object.assign(Object.assign(Object.assign({},o$(e)),{display:"inline-flex",[`&:not(${t}-disabled):hover`]:{zIndex:1,[`${t}-search-with-button &`]:{zIndex:0}},"&-focused, &:focus":{zIndex:1},[`> input${t}`]:{padding:0,fontSize:"inherit",border:"none",borderRadius:0,outline:"none",background:"transparent",color:"inherit","&::-ms-reveal":{display:"none"},"&:focus":{boxShadow:"none !important"}},"&::before":{display:"inline-block",width:0,visibility:"hidden",content:'"\\a0"'},[`${t}`]:{"&-prefix, &-suffix":{display:"flex",flex:"none",alignItems:"center","> *:not(:last-child)":{marginInlineEnd:e.paddingXS}},"&-show-count-suffix":{color:r},"&-show-count-has-suffix":{marginInlineEnd:e.paddingXXS},"&-prefix":{marginInlineEnd:n},"&-suffix":{marginInlineStart:n}}}),Vz(e)),{[`${l}${t}-password-icon`]:{color:i,cursor:"pointer",transition:`all ${o}`,"&:hover":{color:a}}})}},Yz=e=>{const{componentCls:t,borderRadiusLG:n,borderRadiusSM:r}=e;return{[`${t}-group`]:Object.assign(Object.assign(Object.assign({},Qt(e)),Hz(e)),{"&-rtl":{direction:"rtl"},"&-wrapper":Object.assign(Object.assign(Object.assign({display:"inline-block",width:"100%",textAlign:"start",verticalAlign:"top","&-rtl":{direction:"rtl"},"&-lg":{[`${t}-group-addon`]:{borderRadius:n,fontSize:e.inputFontSizeLG}},"&-sm":{[`${t}-group-addon`]:{borderRadius:r}}},Bz(e)),jz(e)),{[`&:not(${t}-compact-first-item):not(${t}-compact-last-item)${t}-compact-item`]:{[`${t}, ${t}-group-addon`]:{borderRadius:0}},[`&:not(${t}-compact-last-item)${t}-compact-first-item`]:{[`${t}, ${t}-group-addon`]:{borderStartEndRadius:0,borderEndEndRadius:0}},[`&:not(${t}-compact-first-item)${t}-compact-last-item`]:{[`${t}, ${t}-group-addon`]:{borderStartStartRadius:0,borderEndStartRadius:0}},[`&:not(${t}-compact-last-item)${t}-compact-item`]:{[`${t}-affix-wrapper`]:{borderStartEndRadius:0,borderEndEndRadius:0}}})})}},Gz=e=>{const{componentCls:t,antCls:n}=e,r=`${t}-search`;return{[r]:{[`${t}`]:{"&:hover, &:focus":{borderColor:e.colorPrimaryHover,[`+ ${t}-group-addon ${r}-button:not(${n}-btn-primary)`]:{borderInlineStartColor:e.colorPrimaryHover}}},[`${t}-affix-wrapper`]:{borderRadius:0},[`${t}-lg`]:{lineHeight:e.calc(e.lineHeightLG).sub(2e-4).equal({unit:!1})},[`> ${t}-group`]:{[`> ${t}-group-addon:last-child`]:{insetInlineStart:-1,padding:0,border:0,[`${r}-button`]:{marginInlineEnd:-1,paddingTop:0,paddingBottom:0,borderStartStartRadius:0,borderStartEndRadius:e.borderRadius,borderEndEndRadius:e.borderRadius,borderEndStartRadius:0,boxShadow:"none"},[`${r}-button:not(${n}-btn-primary)`]:{color:e.colorTextDescription,"&:hover":{color:e.colorPrimaryHover},"&:active":{color:e.colorPrimaryActive},[`&${n}-btn-loading::before`]:{insetInlineStart:0,insetInlineEnd:0,insetBlockStart:0,insetBlockEnd:0}}}},[`${r}-button`]:{height:e.controlHeight,"&:hover, &:focus":{zIndex:1}},[`&-large ${r}-button`]:{height:e.controlHeightLG},[`&-small ${r}-button`]:{height:e.controlHeightSM},"&-rtl":{direction:"rtl"},[`&${t}-compact-item`]:{[`&:not(${t}-compact-last-item)`]:{[`${t}-group-addon`]:{[`${t}-search-button`]:{marginInlineEnd:e.calc(e.lineWidth).mul(-1).equal(),borderRadius:0}}},[`&:not(${t}-compact-first-item)`]:{[`${t},${t}-affix-wrapper`]:{borderRadius:0}},[`> ${t}-group-addon ${t}-search-button,
+ > ${t},
+ ${t}-affix-wrapper`]:{"&:hover,&:focus,&:active":{zIndex:2}},[`> ${t}-affix-wrapper-focused`]:{zIndex:2}}}}},Kz=e=>{const{componentCls:t,paddingLG:n}=e,r=`${t}-textarea`;return{[r]:{position:"relative","&-show-count":{[`> ${t}`]:{height:"100%"},[`${t}-data-count`]:{position:"absolute",bottom:e.calc(e.fontSize).mul(e.lineHeight).mul(-1).equal(),insetInlineEnd:0,color:e.colorTextDescription,whiteSpace:"nowrap",pointerEvents:"none"}},"&-allow-clear":{[`> ${t}`]:{paddingInlineEnd:n}},[`&-affix-wrapper${r}-has-feedback`]:{[`${t}`]:{paddingInlineEnd:n}},[`&-affix-wrapper${t}-affix-wrapper`]:{padding:0,[`> textarea${t}`]:{fontSize:"inherit",border:"none",outline:"none",background:"transparent","&:focus":{boxShadow:"none !important"}},[`${t}-suffix`]:{margin:0,"> *:not(:last-child)":{marginInline:0},[`${t}-clear-icon`]:{position:"absolute",insetInlineEnd:e.paddingXS,insetBlockStart:e.paddingXS},[`${r}-suffix`]:{position:"absolute",top:0,insetInlineEnd:e.paddingInline,bottom:0,zIndex:1,display:"inline-flex",alignItems:"center",margin:"auto",pointerEvents:"none"}}}}}},qz=e=>{const{componentCls:t}=e;return{[`${t}-out-of-range`]:{[`&, & input, & textarea, ${t}-show-count-suffix, ${t}-data-count`]:{color:e.colorError}}}},Im=vn("Input",e=>{const t=$t(e,K2(e));return[Wz(t),Kz(t),Uz(t),Yz(t),Gz(t),qz(t),tf(t)]},q2),bv=(e,t)=>{const{componentCls:n,selectHeight:r,fontHeight:o,lineWidth:i,calc:a}=e,l=t?`${n}-${t}`:"",s=e.calc(o).add(2).equal(),c=()=>a(r).sub(s).sub(a(i).mul(2)),u=e.max(c().div(2).equal(),0),d=e.max(c().sub(u).equal(),0);return[pm(e,t),{[`${n}-multiple${l}`]:{paddingTop:u,paddingBottom:d,paddingInlineStart:u}}]},Xz=e=>{const{componentCls:t,calc:n,lineWidth:r}=e,o=$t(e,{fontHeight:e.fontSize,selectHeight:e.controlHeightSM,multipleSelectItemHeight:e.controlHeightXS,borderRadius:e.borderRadiusSM,borderRadiusSM:e.borderRadiusXS}),i=$t(e,{fontHeight:n(e.multipleItemHeightLG).sub(n(r).mul(2).equal()).equal(),fontSize:e.fontSizeLG,selectHeight:e.controlHeightLG,multipleSelectItemHeight:e.multipleItemHeightLG,borderRadius:e.borderRadiusLG,borderRadiusSM:e.borderRadius});return[bv(o,"small"),bv(e),bv(i,"large"),pm(e),{[`${t}${t}-multiple`]:{width:"100%",[`${t}-selector`]:{flex:"auto",padding:0,"&:after":{margin:0}},[`${t}-selection-item`]:{marginBlock:0},[`${t}-multiple-input`]:{width:0,height:0,border:0,visibility:"hidden",position:"absolute",zIndex:-1}}}]},Qz=Xz,Zz=e=>{const{pickerCellCls:t,pickerCellInnerCls:n,cellHeight:r,borderRadiusSM:o,motionDurationMid:i,cellHoverBg:a,lineWidth:l,lineType:s,colorPrimary:c,cellActiveWithRangeBg:u,colorTextLightSolid:d,colorTextDisabled:v,cellBgDisabled:h,colorFillSecondary:g}=e;return{"&::before":{position:"absolute",top:"50%",insetInlineStart:0,insetInlineEnd:0,zIndex:1,height:r,transform:"translateY(-50%)",content:'""'},[n]:{position:"relative",zIndex:2,display:"inline-block",minWidth:r,height:r,lineHeight:X(r),borderRadius:o,transition:`background ${i}`},[`&:hover:not(${t}-in-view),
+ &:hover:not(${t}-selected):not(${t}-range-start):not(${t}-range-end)`]:{[n]:{background:a}},[`&-in-view${t}-today ${n}`]:{"&::before":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:1,border:`${X(l)} ${s} ${c}`,borderRadius:o,content:'""'}},[`&-in-view${t}-in-range,
+ &-in-view${t}-range-start,
+ &-in-view${t}-range-end`]:{position:"relative",[`&:not(${t}-disabled):before`]:{background:u}},[`&-in-view${t}-selected,
+ &-in-view${t}-range-start,
+ &-in-view${t}-range-end`]:{[`&:not(${t}-disabled) ${n}`]:{color:d,background:c},[`&${t}-disabled ${n}`]:{background:g}},[`&-in-view${t}-range-start:not(${t}-disabled):before`]:{insetInlineStart:"50%"},[`&-in-view${t}-range-end:not(${t}-disabled):before`]:{insetInlineEnd:"50%"},[`&-in-view${t}-range-start:not(${t}-range-end) ${n}`]:{borderStartStartRadius:o,borderEndStartRadius:o,borderStartEndRadius:0,borderEndEndRadius:0},[`&-in-view${t}-range-end:not(${t}-range-start) ${n}`]:{borderStartStartRadius:0,borderEndStartRadius:0,borderStartEndRadius:o,borderEndEndRadius:o},"&-disabled":{color:v,pointerEvents:"none",[n]:{background:"transparent"},"&::before":{background:h}},[`&-disabled${t}-today ${n}::before`]:{borderColor:v}}},i$=e=>{const{componentCls:t,pickerCellCls:n,pickerCellInnerCls:r,pickerYearMonthCellWidth:o,pickerControlIconSize:i,cellWidth:a,paddingSM:l,paddingXS:s,paddingXXS:c,colorBgContainer:u,lineWidth:d,lineType:v,borderRadiusLG:h,colorPrimary:g,colorTextHeading:p,colorSplit:b,pickerControlIconBorderWidth:m,colorIcon:y,textHeight:S,motionDurationMid:x,colorIconHover:$,fontWeightStrong:E,cellHeight:w,pickerCellPaddingVertical:R,colorTextDisabled:P,colorText:N,fontSize:I,motionDurationSlow:z,withoutTimeCellHeight:F,pickerQuarterPanelContentHeight:T,borderRadiusSM:D,colorTextLightSolid:_,cellHoverBg:O,timeColumnHeight:M,timeColumnWidth:L,timeCellHeight:A,controlItemBgActive:B,marginXXS:k,pickerDatePanelPaddingHorizontal:j,pickerControlIconMargin:H}=e,W=e.calc(a).mul(7).add(e.calc(j).mul(2)).equal();return{[t]:{"&-panel":{display:"inline-flex",flexDirection:"column",textAlign:"center",background:u,borderRadius:h,outline:"none","&-focused":{borderColor:g},"&-rtl":{direction:"rtl",[`${t}-prev-icon,
+ ${t}-super-prev-icon`]:{transform:"rotate(45deg)"},[`${t}-next-icon,
+ ${t}-super-next-icon`]:{transform:"rotate(-135deg)"}}},[`&-decade-panel,
+ &-year-panel,
+ &-quarter-panel,
+ &-month-panel,
+ &-week-panel,
+ &-date-panel,
+ &-time-panel`]:{display:"flex",flexDirection:"column",width:W},"&-header":{display:"flex",padding:`0 ${X(s)}`,color:p,borderBottom:`${X(d)} ${v} ${b}`,"> *":{flex:"none"},button:{padding:0,color:y,lineHeight:X(S),background:"transparent",border:0,cursor:"pointer",transition:`color ${x}`,fontSize:"inherit"},"> button":{minWidth:"1.6em",fontSize:I,"&:hover":{color:$},"&:disabled":{opacity:.25,pointerEvents:"none"}},"&-view":{flex:"auto",fontWeight:E,lineHeight:X(S),button:{color:"inherit",fontWeight:"inherit",verticalAlign:"top","&:not(:first-child)":{marginInlineStart:s},"&:hover":{color:g}}}},[`&-prev-icon,
+ &-next-icon,
+ &-super-prev-icon,
+ &-super-next-icon`]:{position:"relative",display:"inline-block",width:i,height:i,"&::before":{position:"absolute",top:0,insetInlineStart:0,display:"inline-block",width:i,height:i,border:"0 solid currentcolor",borderBlockStartWidth:m,borderBlockEndWidth:0,borderInlineStartWidth:m,borderInlineEndWidth:0,content:'""'}},[`&-super-prev-icon,
+ &-super-next-icon`]:{"&::after":{position:"absolute",top:H,insetInlineStart:H,display:"inline-block",width:i,height:i,border:"0 solid currentcolor",borderBlockStartWidth:m,borderBlockEndWidth:0,borderInlineStartWidth:m,borderInlineEndWidth:0,content:'""'}},[`&-prev-icon,
+ &-super-prev-icon`]:{transform:"rotate(-45deg)"},[`&-next-icon,
+ &-super-next-icon`]:{transform:"rotate(135deg)"},"&-content":{width:"100%",tableLayout:"fixed",borderCollapse:"collapse","th, td":{position:"relative",minWidth:w,fontWeight:"normal"},th:{height:e.calc(w).add(e.calc(R).mul(2)).equal(),color:N,verticalAlign:"middle"}},"&-cell":Object.assign({padding:`${X(R)} 0`,color:P,cursor:"pointer","&-in-view":{color:N}},Zz(e)),[`&-decade-panel,
+ &-year-panel,
+ &-quarter-panel,
+ &-month-panel`]:{[`${t}-content`]:{height:e.calc(F).mul(4).equal()},[r]:{padding:`0 ${X(s)}`}},"&-quarter-panel":{[`${t}-content`]:{height:T}},"&-decade-panel":{[r]:{padding:`0 ${X(e.calc(s).div(2).equal())}`},[`${t}-cell::before`]:{display:"none"}},[`&-year-panel,
+ &-quarter-panel,
+ &-month-panel`]:{[`${t}-body`]:{padding:`0 ${X(s)}`},[r]:{width:o}},"&-date-panel":{[`${t}-body`]:{padding:`${X(s)} ${X(j)}`},[`${t}-content th`]:{boxSizing:"border-box",padding:0}},"&-week-panel":{[`${t}-cell`]:{[`&:hover ${r},
+ &-selected ${r},
+ ${r}`]:{background:"transparent !important"}},"&-row":{td:{"&:before":{transition:`background ${x}`},"&:first-child:before":{borderStartStartRadius:D,borderEndStartRadius:D},"&:last-child:before":{borderStartEndRadius:D,borderEndEndRadius:D}},["&:hover td"]:{"&:before":{background:O}},[`&-range-start td,
+ &-range-end td,
+ &-selected td`]:{[`&${n}`]:{"&:before":{background:g},[`&${t}-cell-week`]:{color:new Mt(_).setAlpha(.5).toHexString()},[r]:{color:_}}},["&-range-hover td:before"]:{background:B}}},["&-week-panel, &-date-panel-show-week"]:{[`${t}-body`]:{padding:`${X(s)} ${X(l)}`},[`${t}-content th`]:{width:"auto"}},"&-datetime-panel":{display:"flex",[`${t}-time-panel`]:{borderInlineStart:`${X(d)} ${v} ${b}`},[`${t}-date-panel,
+ ${t}-time-panel`]:{transition:`opacity ${z}`},"&-active":{[`${t}-date-panel,
+ ${t}-time-panel`]:{opacity:.3,"&-active":{opacity:1}}}},"&-time-panel":{width:"auto",minWidth:"auto",direction:"ltr",[`${t}-content`]:{display:"flex",flex:"auto",height:M},"&-column":{flex:"1 0 auto",width:L,margin:`${X(c)} 0`,padding:0,overflowY:"hidden",textAlign:"start",listStyle:"none",transition:`background ${x}`,overflowX:"hidden","&::-webkit-scrollbar":{width:8,backgroundColor:"transparent"},"&::-webkit-scrollbar-thumb":{backgroundColor:e.colorTextTertiary,borderRadius:4},"&":{scrollbarWidth:"thin",scrollbarColor:`${e.colorTextTertiary} transparent`},"&::after":{display:"block",height:e.calc("100%").sub(A).equal(),content:'""'},"&:not(:first-child)":{borderInlineStart:`${X(d)} ${v} ${b}`},"&-active":{background:new Mt(B).setAlpha(.2).toHexString()},"&:hover":{overflowY:"auto"},"> li":{margin:0,padding:0,[`&${t}-time-panel-cell`]:{marginInline:k,[`${t}-time-panel-cell-inner`]:{display:"block",width:e.calc(L).sub(e.calc(k).mul(2)).equal(),height:A,margin:0,paddingBlock:0,paddingInlineEnd:0,paddingInlineStart:e.calc(L).sub(A).div(2).equal(),color:N,lineHeight:X(A),borderRadius:D,cursor:"pointer",transition:`background ${x}`,"&:hover":{background:O}},"&-selected":{[`${t}-time-panel-cell-inner`]:{background:B}},"&-disabled":{[`${t}-time-panel-cell-inner`]:{color:P,background:"transparent",cursor:"not-allowed"}}}}}}}}},Jz=e=>{const{componentCls:t,textHeight:n,lineWidth:r,paddingSM:o,antCls:i,colorPrimary:a,cellActiveWithRangeBg:l,colorPrimaryBorder:s,lineType:c,colorSplit:u}=e;return{[`${t}-dropdown`]:{[`${t}-footer`]:{borderTop:`${X(r)} ${c} ${u}`,"&-extra":{padding:`0 ${X(o)}`,lineHeight:X(e.calc(n).sub(e.calc(r).mul(2)).equal()),textAlign:"start","&:not(:last-child)":{borderBottom:`${X(r)} ${c} ${u}`}}},[`${t}-panels + ${t}-footer ${t}-ranges`]:{justifyContent:"space-between"},[`${t}-ranges`]:{marginBlock:0,paddingInline:X(o),overflow:"hidden",textAlign:"start",listStyle:"none",display:"flex",justifyContent:"center",alignItems:"center","> li":{lineHeight:X(e.calc(n).sub(e.calc(r).mul(2)).equal()),display:"inline-block"},[`${t}-now-btn-disabled`]:{pointerEvents:"none",color:e.colorTextDisabled},[`${t}-preset > ${i}-tag-blue`]:{color:a,background:l,borderColor:s,cursor:"pointer"},[`${t}-ok`]:{paddingBlock:e.calc(r).mul(2).equal(),marginInlineStart:"auto"}}}}},eF=Jz,a$=e=>{const{componentCls:t,controlHeightLG:n,paddingXXS:r,padding:o}=e;return{pickerCellCls:`${t}-cell`,pickerCellInnerCls:`${t}-cell-inner`,pickerYearMonthCellWidth:e.calc(n).mul(1.5).equal(),pickerQuarterPanelContentHeight:e.calc(n).mul(1.4).equal(),pickerCellPaddingVertical:e.calc(r).add(e.calc(r).div(2)).equal(),pickerCellBorderGap:2,pickerControlIconSize:7,pickerControlIconMargin:4,pickerControlIconBorderWidth:1.5,pickerDatePanelPaddingHorizontal:e.calc(o).add(e.calc(r).div(2)).equal()}},l$=e=>{const{colorBgContainerDisabled:t,controlHeightSM:n,controlHeightLG:r}=e;return{cellHoverBg:e.controlItemBgHover,cellActiveWithRangeBg:e.controlItemBgActive,cellHoverWithRangeBg:new Mt(e.colorPrimary).lighten(35).toHexString(),cellRangeBorderColor:new Mt(e.colorPrimary).lighten(20).toHexString(),cellBgDisabled:t,timeColumnWidth:r*1.4,timeColumnHeight:28*8,timeCellHeight:28,cellWidth:n*1.5,cellHeight:n,textHeight:r,withoutTimeCellHeight:r*1.65,multipleItemBg:e.colorFillSecondary,multipleItemBorderColor:"transparent",multipleItemHeight:n,multipleItemHeightLG:e.controlHeight,multipleSelectorBgDisabled:t,multipleItemColorDisabled:e.colorTextDisabled,multipleItemBorderColorDisabled:"transparent"}},tF=e=>Object.assign(Object.assign(Object.assign(Object.assign({},q2(e)),l$(e)),hm(e)),{presetsWidth:120,presetsMaxWidth:200,zIndexPopup:e.zIndexPopupBase+50}),nF=e=>{const{componentCls:t}=e;return{[t]:[Object.assign(Object.assign(Object.assign({},Q2(e)),e$(e)),Z2(e)),{"&-outlined":{[`&${t}-multiple ${t}-selection-item`]:{background:e.multipleItemBg,border:`${X(e.lineWidth)} ${e.lineType} ${e.multipleItemBorderColor}`}},"&-filled":{[`&${t}-multiple ${t}-selection-item`]:{background:e.colorBgContainer,border:`${X(e.lineWidth)} ${e.lineType} ${e.colorSplit}`}},"&-borderless":{[`&${t}-multiple ${t}-selection-item`]:{background:e.multipleItemBg,border:`${X(e.lineWidth)} ${e.lineType} ${e.multipleItemBorderColor}`}}}]}},rF=nF,Sv=(e,t,n,r)=>{const o=e.calc(n).add(2).equal(),i=e.max(e.calc(t).sub(o).div(2).equal(),0),a=e.max(e.calc(t).sub(o).sub(i).equal(),0);return{padding:`${X(i)} ${X(r)} ${X(a)}`}},oF=e=>{const{componentCls:t,colorError:n,colorWarning:r}=e;return{[`${t}:not(${t}-disabled):not([disabled])`]:{[`&${t}-status-error`]:{[`${t}-active-bar`]:{background:n}},[`&${t}-status-warning`]:{[`${t}-active-bar`]:{background:r}}}}},iF=e=>{const{componentCls:t,antCls:n,controlHeight:r,paddingInline:o,lineWidth:i,lineType:a,colorBorder:l,borderRadius:s,motionDurationMid:c,colorTextDisabled:u,colorTextPlaceholder:d,controlHeightLG:v,fontSizeLG:h,controlHeightSM:g,paddingInlineSM:p,paddingXS:b,marginXS:m,colorTextDescription:y,lineWidthBold:S,colorPrimary:x,motionDurationSlow:$,zIndexPopup:E,paddingXXS:w,sizePopupArrow:R,colorBgElevated:P,borderRadiusLG:N,boxShadowSecondary:I,borderRadiusSM:z,colorSplit:F,cellHoverBg:T,presetsWidth:D,presetsMaxWidth:_,boxShadowPopoverArrow:O,fontHeight:M,fontHeightLG:L,lineHeightLG:A}=e;return[{[t]:Object.assign(Object.assign(Object.assign({},Qt(e)),Sv(e,r,M,o)),{position:"relative",display:"inline-flex",alignItems:"center",lineHeight:1,borderRadius:s,transition:`border ${c}, box-shadow ${c}, background ${c}`,[`${t}-input`]:{position:"relative",display:"inline-flex",alignItems:"center",width:"100%","> input":Object.assign(Object.assign({position:"relative",display:"inline-block",width:"100%",color:"inherit",fontSize:e.fontSize,lineHeight:e.lineHeight,transition:`all ${c}`},t$(d)),{flex:"auto",minWidth:1,height:"auto",padding:0,background:"transparent",border:0,fontFamily:"inherit","&:focus":{boxShadow:"none",outline:0},"&[disabled]":{background:"transparent",color:u,cursor:"not-allowed"}}),"&-placeholder":{"> input":{color:d}}},"&-large":Object.assign(Object.assign({},Sv(e,v,L,o)),{[`${t}-input > input`]:{fontSize:h,lineHeight:A}}),"&-small":Object.assign({},Sv(e,g,M,p)),[`${t}-suffix`]:{display:"flex",flex:"none",alignSelf:"center",marginInlineStart:e.calc(b).div(2).equal(),color:u,lineHeight:1,pointerEvents:"none",transition:`opacity ${c}, color ${c}`,"> *":{verticalAlign:"top","&:not(:last-child)":{marginInlineEnd:m}}},[`${t}-clear`]:{position:"absolute",top:"50%",insetInlineEnd:0,color:u,lineHeight:1,transform:"translateY(-50%)",cursor:"pointer",opacity:0,transition:`opacity ${c}, color ${c}`,"> *":{verticalAlign:"top"},"&:hover":{color:y}},"&:hover":{[`${t}-clear`]:{opacity:1},[`${t}-suffix:not(:last-child)`]:{opacity:0}},[`${t}-separator`]:{position:"relative",display:"inline-block",width:"1em",height:h,color:u,fontSize:h,verticalAlign:"top",cursor:"default",[`${t}-focused &`]:{color:y},[`${t}-range-separator &`]:{[`${t}-disabled &`]:{cursor:"not-allowed"}}},"&-range":{position:"relative",display:"inline-flex",[`${t}-active-bar`]:{bottom:e.calc(i).mul(-1).equal(),height:S,background:x,opacity:0,transition:`all ${$} ease-out`,pointerEvents:"none"},[`&${t}-focused`]:{[`${t}-active-bar`]:{opacity:1}},[`${t}-range-separator`]:{alignItems:"center",padding:`0 ${X(b)}`,lineHeight:1}},"&-range, &-multiple":{[`${t}-clear`]:{insetInlineEnd:o},[`&${t}-small`]:{[`${t}-clear`]:{insetInlineEnd:p}}},"&-dropdown":Object.assign(Object.assign(Object.assign({},Qt(e)),i$(e)),{pointerEvents:"none",position:"absolute",top:-9999,left:{_skip_check_:!0,value:-9999},zIndex:E,[`&${t}-dropdown-hidden`]:{display:"none"},[`&${t}-dropdown-placement-bottomLeft`]:{[`${t}-range-arrow`]:{top:0,display:"block",transform:"translateY(-100%)"}},[`&${t}-dropdown-placement-topLeft`]:{[`${t}-range-arrow`]:{bottom:0,display:"block",transform:"translateY(100%) rotate(180deg)"}},[`&${n}-slide-up-enter${n}-slide-up-enter-active${t}-dropdown-placement-topLeft,
+ &${n}-slide-up-enter${n}-slide-up-enter-active${t}-dropdown-placement-topRight,
+ &${n}-slide-up-appear${n}-slide-up-appear-active${t}-dropdown-placement-topLeft,
+ &${n}-slide-up-appear${n}-slide-up-appear-active${t}-dropdown-placement-topRight`]:{animationName:om},[`&${n}-slide-up-enter${n}-slide-up-enter-active${t}-dropdown-placement-bottomLeft,
+ &${n}-slide-up-enter${n}-slide-up-enter-active${t}-dropdown-placement-bottomRight,
+ &${n}-slide-up-appear${n}-slide-up-appear-active${t}-dropdown-placement-bottomLeft,
+ &${n}-slide-up-appear${n}-slide-up-appear-active${t}-dropdown-placement-bottomRight`]:{animationName:nm},[`&${n}-slide-up-leave${n}-slide-up-leave-active${t}-dropdown-placement-topLeft,
+ &${n}-slide-up-leave${n}-slide-up-leave-active${t}-dropdown-placement-topRight`]:{animationName:im},[`&${n}-slide-up-leave${n}-slide-up-leave-active${t}-dropdown-placement-bottomLeft,
+ &${n}-slide-up-leave${n}-slide-up-leave-active${t}-dropdown-placement-bottomRight`]:{animationName:rm},[`${t}-panel > ${t}-time-panel`]:{paddingTop:w},[`${t}-range-wrapper`]:{display:"flex",position:"relative"},[`${t}-range-arrow`]:Object.assign(Object.assign({position:"absolute",zIndex:1,display:"none",paddingInline:e.calc(o).mul(1.5).equal(),boxSizing:"content-box",transition:`left ${$} ease-out`},l2(e,P,O)),{"&:before":{insetInlineStart:e.calc(o).mul(1.5).equal()}}),[`${t}-panel-container`]:{overflow:"hidden",verticalAlign:"top",background:P,borderRadius:N,boxShadow:I,transition:`margin ${$}`,display:"inline-block",pointerEvents:"auto",[`${t}-panel-layout`]:{display:"flex",flexWrap:"nowrap",alignItems:"stretch"},[`${t}-presets`]:{display:"flex",flexDirection:"column",minWidth:D,maxWidth:_,ul:{height:0,flex:"auto",listStyle:"none",overflow:"auto",margin:0,padding:b,borderInlineEnd:`${X(i)} ${a} ${F}`,li:Object.assign(Object.assign({},ei),{borderRadius:z,paddingInline:b,paddingBlock:e.calc(g).sub(M).div(2).equal(),cursor:"pointer",transition:`all ${$}`,"+ li":{marginTop:m},"&:hover":{background:T}})}},[`${t}-panels`]:{display:"inline-flex",flexWrap:"nowrap",direction:"ltr","&:last-child":{[`${t}-panel`]:{borderWidth:0}}},[`${t}-panel`]:{verticalAlign:"top",background:"transparent",borderRadius:0,borderWidth:0,[`${t}-content,
+ table`]:{textAlign:"center"},"&-focused":{borderColor:l}}}}),"&-dropdown-range":{padding:`${X(e.calc(R).mul(2).div(3).equal())} 0`,"&-hidden":{display:"none"}},"&-rtl":{direction:"rtl",[`${t}-separator`]:{transform:"rotate(180deg)"},[`${t}-footer`]:{"&-extra":{direction:"rtl"}}}})},Xa(e,"slide-up"),Xa(e,"slide-down"),Zu(e,"move-up"),Zu(e,"move-down")]};vn("DatePicker",e=>{const t=$t(K2(e),a$(e),{inputPaddingHorizontalBase:e.calc(e.paddingSM).sub(1).equal(),multipleSelectItemHeight:e.multipleItemHeight,selectHeight:e.controlHeight});return[eF(t),iF(t),rF(t),oF(t),Qz(t),tf(e,{focusElCls:`${e.componentCls}-focused`})]},tF);const aF=e=>{const{calendarCls:t,componentCls:n,fullBg:r,fullPanelBg:o,itemActiveBg:i}=e;return{[t]:Object.assign(Object.assign(Object.assign({},i$(e)),Qt(e)),{background:r,"&-rtl":{direction:"rtl"},[`${t}-header`]:{display:"flex",justifyContent:"flex-end",padding:`${X(e.paddingSM)} 0`,[`${t}-year-select`]:{minWidth:e.yearControlWidth},[`${t}-month-select`]:{minWidth:e.monthControlWidth,marginInlineStart:e.marginXS},[`${t}-mode-switch`]:{marginInlineStart:e.marginXS}}}),[`${t} ${n}-panel`]:{background:o,border:0,borderTop:`${X(e.lineWidth)} ${e.lineType} ${e.colorSplit}`,borderRadius:0,[`${n}-month-panel, ${n}-date-panel`]:{width:"auto"},[`${n}-body`]:{padding:`${X(e.paddingXS)} 0`},[`${n}-content`]:{width:"100%"}},[`${t}-mini`]:{borderRadius:e.borderRadiusLG,[`${t}-header`]:{paddingInlineEnd:e.paddingXS,paddingInlineStart:e.paddingXS},[`${n}-panel`]:{borderRadius:`0 0 ${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)}`},[`${n}-content`]:{height:e.miniContentHeight,th:{height:"auto",padding:0,lineHeight:`${X(e.weekHeight)}`}},[`${n}-cell::before`]:{pointerEvents:"none"}},[`${t}${t}-full`]:{[`${n}-panel`]:{display:"block",width:"100%",textAlign:"end",background:r,border:0,[`${n}-body`]:{"th, td":{padding:0},th:{height:"auto",paddingInlineEnd:e.paddingSM,paddingBottom:e.paddingXXS,lineHeight:`${X(e.weekHeight)}`}}},[`${n}-cell`]:{"&::before":{display:"none"},"&:hover":{[`${t}-date`]:{background:e.controlItemBgHover}},[`${t}-date-today::before`]:{display:"none"},[`&-in-view${n}-cell-selected`]:{[`${t}-date, ${t}-date-today`]:{background:i}},"&-selected, &-selected:hover":{[`${t}-date, ${t}-date-today`]:{[`${t}-date-value`]:{color:e.colorPrimary}}}},[`${t}-date`]:{display:"block",width:"auto",height:"auto",margin:`0 ${X(e.calc(e.marginXS).div(2).equal())}`,padding:`${X(e.calc(e.paddingXS).div(2).equal())} ${X(e.paddingXS)} 0`,border:0,borderTop:`${X(e.lineWidthBold)} ${e.lineType} ${e.colorSplit}`,borderRadius:0,transition:`background ${e.motionDurationSlow}`,"&-value":{lineHeight:`${X(e.dateValueHeight)}`,transition:`color ${e.motionDurationSlow}`},"&-content":{position:"static",width:"auto",height:e.dateContentHeight,overflowY:"auto",color:e.colorText,lineHeight:e.lineHeight,textAlign:"start"},"&-today":{borderColor:e.colorPrimary,[`${t}-date-value`]:{color:e.colorText}}}},[`@media only screen and (max-width: ${X(e.screenXS)}) `]:{[`${t}`]:{[`${t}-header`]:{display:"block",[`${t}-year-select`]:{width:"50%"},[`${t}-month-select`]:{width:`calc(50% - ${X(e.paddingXS)})`},[`${t}-mode-switch`]:{width:"100%",marginTop:e.marginXS,marginInlineStart:0,"> label":{width:"50%",textAlign:"center"}}}}}}},lF=e=>Object.assign({fullBg:e.colorBgContainer,fullPanelBg:e.colorBgContainer,itemActiveBg:e.controlItemBgActive,yearControlWidth:80,monthControlWidth:70,miniContentHeight:256},l$(e)),sF=vn("Calendar",e=>{const t=`${e.componentCls}-calendar`,n=$t(e,a$(e),{calendarCls:t,pickerCellInnerCls:`${e.componentCls}-cell-inner`,dateValueHeight:e.controlHeightSM,weekHeight:e.calc(e.controlHeightSM).mul(.75).equal(),dateContentHeight:e.calc(e.calc(e.fontHeightSM).add(e.marginXS)).mul(3).add(e.calc(e.lineWidth).mul(2)).equal()});return[aF(n)]},lF);function s$(e){function t(i,a){return i&&a&&e.getYear(i)===e.getYear(a)}function n(i,a){return t(i,a)&&e.getMonth(i)===e.getMonth(a)}function r(i,a){return n(i,a)&&e.getDate(i)===e.getDate(a)}return i=>{const{prefixCls:a,className:l,rootClassName:s,style:c,dateFullCellRender:u,dateCellRender:d,monthFullCellRender:v,monthCellRender:h,cellRender:g,fullCellRender:p,headerRender:b,value:m,defaultValue:y,disabledDate:S,mode:x,validRange:$,fullscreen:E=!0,onChange:w,onPanelChange:R,onSelect:P}=i,{getPrefixCls:N,direction:I,calendar:z}=f.exports.useContext(ot),F=N("picker",a),T=`${F}-calendar`,[D,_,O]=sF(F,T),M=e.getNow(),[L,A]=kt(()=>m||e.getNow(),{defaultValue:y,value:m}),[B,k]=kt("month",{value:x}),j=f.exports.useMemo(()=>B==="year"?"month":"date",[B]),H=f.exports.useCallback(J=>($?e.isAfter($[0],J)||e.isAfter(J,$[1]):!1)||!!(S!=null&&S(J)),[S,$]),W=(J,re)=>{R==null||R(J,re)},Y=J=>{A(J),r(J,L)||((j==="date"&&!n(J,L)||j==="month"&&!t(J,L))&&W(J,B),w==null||w(J))},K=J=>{k(J),W(L,J)},q=(J,re)=>{Y(J),P==null||P(J,{source:re})},ee=()=>{const{locale:J}=i,re=Object.assign(Object.assign({},Kp),J);return re.lang=Object.assign(Object.assign({},re.lang),(J||{}).lang),re},Z=f.exports.useCallback((J,re)=>p?p(J,re):u?u(J):ie("div",{className:te(`${F}-cell-inner`,`${T}-date`,{[`${T}-date-today`]:r(M,J)}),children:[C("div",{className:`${T}-date-value`,children:String(e.getDate(J)).padStart(2,"0")}),C("div",{className:`${T}-date-content`,children:g?g(J,re):d&&d(J)})]}),[u,d,g,p]),Q=f.exports.useCallback((J,re)=>{if(p)return p(J,re);if(v)return v(J);const fe=re.locale.shortMonths||e.locale.getShortMonths(re.locale.locale);return ie("div",{className:te(`${F}-cell-inner`,`${T}-date`,{[`${T}-date-today`]:n(M,J)}),children:[C("div",{className:`${T}-date-value`,children:fe[e.getMonth(J)]}),C("div",{className:`${T}-date-content`,children:g?g(J,re):h&&h(J)})]})},[v,h,g,p]),[ne]=Wx("Calendar",ee),ae=(J,re)=>{if(re.type==="date")return Z(J,re);if(re.type==="month")return Q(J,Object.assign(Object.assign({},re),{locale:ne==null?void 0:ne.lang}))};return D(ie("div",{className:te(T,{[`${T}-full`]:E,[`${T}-mini`]:!E,[`${T}-rtl`]:I==="rtl"},z==null?void 0:z.className,l,s,_,O),style:Object.assign(Object.assign({},z==null?void 0:z.style),c),children:[b?b({value:L,type:B,onChange:J=>{q(J,"customize")},onTypeChange:K}):C(Fz,{prefixCls:T,value:L,generateConfig:e,mode:B,fullscreen:E,locale:ne==null?void 0:ne.lang,validRange:$,onChange:q,onModeChange:K}),C(yz,{value:L,prefixCls:F,locale:ne==null?void 0:ne.lang,generateConfig:e,cellRender:ae,onSelect:J=>{q(J,j)},mode:j,picker:j,disabledDate:H,hideHeader:!0})]}))}}const c$=s$(VL);c$.generateCalendar=s$;const cF=c$,uF=e=>{const{prefixCls:t,className:n,style:r,size:o,shape:i}=e,a=te({[`${t}-lg`]:o==="large",[`${t}-sm`]:o==="small"}),l=te({[`${t}-circle`]:i==="circle",[`${t}-square`]:i==="square",[`${t}-round`]:i==="round"}),s=f.exports.useMemo(()=>typeof o=="number"?{width:o,height:o,lineHeight:`${o}px`}:{},[o]);return C("span",{className:te(t,a,l,n),style:Object.assign(Object.assign({},s),r)})},vf=uF,dF=new Ct("ant-skeleton-loading",{"0%":{backgroundPosition:"100% 50%"},"100%":{backgroundPosition:"0 50%"}}),pf=e=>({height:e,lineHeight:X(e)}),Da=e=>Object.assign({width:e},pf(e)),fF=e=>({background:e.skeletonLoadingBackground,backgroundSize:"400% 100%",animationName:dF,animationDuration:e.skeletonLoadingMotionDuration,animationTimingFunction:"ease",animationIterationCount:"infinite"}),Cv=(e,t)=>Object.assign({width:t(e).mul(5).equal(),minWidth:t(e).mul(5).equal()},pf(e)),vF=e=>{const{skeletonAvatarCls:t,gradientFromColor:n,controlHeight:r,controlHeightLG:o,controlHeightSM:i}=e;return{[`${t}`]:Object.assign({display:"inline-block",verticalAlign:"top",background:n},Da(r)),[`${t}${t}-circle`]:{borderRadius:"50%"},[`${t}${t}-lg`]:Object.assign({},Da(o)),[`${t}${t}-sm`]:Object.assign({},Da(i))}},pF=e=>{const{controlHeight:t,borderRadiusSM:n,skeletonInputCls:r,controlHeightLG:o,controlHeightSM:i,gradientFromColor:a,calc:l}=e;return{[`${r}`]:Object.assign({display:"inline-block",verticalAlign:"top",background:a,borderRadius:n},Cv(t,l)),[`${r}-lg`]:Object.assign({},Cv(o,l)),[`${r}-sm`]:Object.assign({},Cv(i,l))}},qb=e=>Object.assign({width:e},pf(e)),gF=e=>{const{skeletonImageCls:t,imageSizeBase:n,gradientFromColor:r,borderRadiusSM:o,calc:i}=e;return{[`${t}`]:Object.assign(Object.assign({display:"flex",alignItems:"center",justifyContent:"center",verticalAlign:"top",background:r,borderRadius:o},qb(i(n).mul(2).equal())),{[`${t}-path`]:{fill:"#bfbfbf"},[`${t}-svg`]:Object.assign(Object.assign({},qb(n)),{maxWidth:i(n).mul(4).equal(),maxHeight:i(n).mul(4).equal()}),[`${t}-svg${t}-svg-circle`]:{borderRadius:"50%"}}),[`${t}${t}-circle`]:{borderRadius:"50%"}}},xv=(e,t,n)=>{const{skeletonButtonCls:r}=e;return{[`${n}${r}-circle`]:{width:t,minWidth:t,borderRadius:"50%"},[`${n}${r}-round`]:{borderRadius:t}}},wv=(e,t)=>Object.assign({width:t(e).mul(2).equal(),minWidth:t(e).mul(2).equal()},pf(e)),hF=e=>{const{borderRadiusSM:t,skeletonButtonCls:n,controlHeight:r,controlHeightLG:o,controlHeightSM:i,gradientFromColor:a,calc:l}=e;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({[`${n}`]:Object.assign({display:"inline-block",verticalAlign:"top",background:a,borderRadius:t,width:l(r).mul(2).equal(),minWidth:l(r).mul(2).equal()},wv(r,l))},xv(e,r,n)),{[`${n}-lg`]:Object.assign({},wv(o,l))}),xv(e,o,`${n}-lg`)),{[`${n}-sm`]:Object.assign({},wv(i,l))}),xv(e,i,`${n}-sm`))},mF=e=>{const{componentCls:t,skeletonAvatarCls:n,skeletonTitleCls:r,skeletonParagraphCls:o,skeletonButtonCls:i,skeletonInputCls:a,skeletonImageCls:l,controlHeight:s,controlHeightLG:c,controlHeightSM:u,gradientFromColor:d,padding:v,marginSM:h,borderRadius:g,titleHeight:p,blockRadius:b,paragraphLiHeight:m,controlHeightXS:y,paragraphMarginTop:S}=e;return{[`${t}`]:{display:"table",width:"100%",[`${t}-header`]:{display:"table-cell",paddingInlineEnd:v,verticalAlign:"top",[`${n}`]:Object.assign({display:"inline-block",verticalAlign:"top",background:d},Da(s)),[`${n}-circle`]:{borderRadius:"50%"},[`${n}-lg`]:Object.assign({},Da(c)),[`${n}-sm`]:Object.assign({},Da(u))},[`${t}-content`]:{display:"table-cell",width:"100%",verticalAlign:"top",[`${r}`]:{width:"100%",height:p,background:d,borderRadius:b,[`+ ${o}`]:{marginBlockStart:u}},[`${o}`]:{padding:0,"> li":{width:"100%",height:m,listStyle:"none",background:d,borderRadius:b,"+ li":{marginBlockStart:y}}},[`${o}> li:last-child:not(:first-child):not(:nth-child(2))`]:{width:"61%"}},[`&-round ${t}-content`]:{[`${r}, ${o} > li`]:{borderRadius:g}}},[`${t}-with-avatar ${t}-content`]:{[`${r}`]:{marginBlockStart:h,[`+ ${o}`]:{marginBlockStart:S}}},[`${t}${t}-element`]:Object.assign(Object.assign(Object.assign(Object.assign({display:"inline-block",width:"auto"},hF(e)),vF(e)),pF(e)),gF(e)),[`${t}${t}-block`]:{width:"100%",[`${i}`]:{width:"100%"},[`${a}`]:{width:"100%"}},[`${t}${t}-active`]:{[`
+ ${r},
+ ${o} > li,
+ ${n},
+ ${i},
+ ${a},
+ ${l}
+ `]:Object.assign({},fF(e))}}},yF=e=>{const{colorFillContent:t,colorFill:n}=e,r=t,o=n;return{color:r,colorGradientEnd:o,gradientFromColor:r,gradientToColor:o,titleHeight:e.controlHeight/2,blockRadius:e.borderRadiusSM,paragraphMarginTop:e.marginLG+e.marginXXS,paragraphLiHeight:e.controlHeight/2}},ll=vn("Skeleton",e=>{const{componentCls:t,calc:n}=e,r=$t(e,{skeletonAvatarCls:`${t}-avatar`,skeletonTitleCls:`${t}-title`,skeletonParagraphCls:`${t}-paragraph`,skeletonButtonCls:`${t}-button`,skeletonInputCls:`${t}-input`,skeletonImageCls:`${t}-image`,imageSizeBase:n(e.controlHeight).mul(1.5).equal(),borderRadius:100,skeletonLoadingBackground:`linear-gradient(90deg, ${e.gradientFromColor} 25%, ${e.gradientToColor} 37%, ${e.gradientFromColor} 63%)`,skeletonLoadingMotionDuration:"1.4s"});return[mF(r)]},yF,{deprecatedTokens:[["color","gradientFromColor"],["colorGradientEnd","gradientToColor"]]}),bF=e=>{const{prefixCls:t,className:n,rootClassName:r,active:o,shape:i="circle",size:a="default"}=e,{getPrefixCls:l}=f.exports.useContext(ot),s=l("skeleton",t),[c,u,d]=ll(s),v=lr(e,["prefixCls","className"]),h=te(s,`${s}-element`,{[`${s}-active`]:o},n,r,u,d);return c(C("div",{className:h,children:C(vf,{...Object.assign({prefixCls:`${s}-avatar`,shape:i,size:a},v)})}))},SF=bF,CF=e=>{const{prefixCls:t,className:n,rootClassName:r,active:o,block:i=!1,size:a="default"}=e,{getPrefixCls:l}=f.exports.useContext(ot),s=l("skeleton",t),[c,u,d]=ll(s),v=lr(e,["prefixCls"]),h=te(s,`${s}-element`,{[`${s}-active`]:o,[`${s}-block`]:i},n,r,u,d);return c(C("div",{className:h,children:C(vf,{...Object.assign({prefixCls:`${s}-button`,size:a},v)})}))},xF=CF,wF="M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z",$F=e=>{const{prefixCls:t,className:n,rootClassName:r,style:o,active:i}=e,{getPrefixCls:a}=f.exports.useContext(ot),l=a("skeleton",t),[s,c,u]=ll(l),d=te(l,`${l}-element`,{[`${l}-active`]:i},n,r,c,u);return s(C("div",{className:d,children:C("div",{className:te(`${l}-image`,n),style:o,children:C("svg",{viewBox:"0 0 1098 1024",xmlns:"http://www.w3.org/2000/svg",className:`${l}-image-svg`,children:C("path",{d:wF,className:`${l}-image-path`})})})}))},EF=$F,MF=e=>{const{prefixCls:t,className:n,rootClassName:r,active:o,block:i,size:a="default"}=e,{getPrefixCls:l}=f.exports.useContext(ot),s=l("skeleton",t),[c,u,d]=ll(s),v=lr(e,["prefixCls"]),h=te(s,`${s}-element`,{[`${s}-active`]:o,[`${s}-block`]:i},n,r,u,d);return c(C("div",{className:h,children:C(vf,{...Object.assign({prefixCls:`${s}-input`,size:a},v)})}))},OF=MF,RF=e=>{const{prefixCls:t,className:n,rootClassName:r,style:o,active:i,children:a}=e,{getPrefixCls:l}=f.exports.useContext(ot),s=l("skeleton",t),[c,u,d]=ll(s),v=te(s,`${s}-element`,{[`${s}-active`]:i},u,n,r,d),h=a!=null?a:C(UI,{});return c(C("div",{className:v,children:C("div",{className:te(`${s}-image`,n),style:o,children:h})}))},IF=RF,PF=e=>{const t=l=>{const{width:s,rows:c=2}=e;if(Array.isArray(s))return s[l];if(c-1===l)return s},{prefixCls:n,className:r,style:o,rows:i}=e,a=Oe(Array(i)).map((l,s)=>C("li",{style:{width:t(s)}},s));return C("ul",{className:te(n,r),style:o,children:a})},TF=PF,NF=e=>{let{prefixCls:t,className:n,width:r,style:o}=e;return C("h3",{className:te(t,n),style:Object.assign({width:r},o)})},_F=NF;function $v(e){return e&&typeof e=="object"?e:{}}function AF(e,t){return e&&!t?{size:"large",shape:"square"}:{size:"large",shape:"circle"}}function DF(e,t){return!e&&t?{width:"38%"}:e&&t?{width:"50%"}:{}}function LF(e,t){const n={};return(!e||!t)&&(n.width="61%"),!e&&t?n.rows=3:n.rows=2,n}const sl=e=>{const{prefixCls:t,loading:n,className:r,rootClassName:o,style:i,children:a,avatar:l=!1,title:s=!0,paragraph:c=!0,active:u,round:d}=e,{getPrefixCls:v,direction:h,skeleton:g}=f.exports.useContext(ot),p=v("skeleton",t),[b,m,y]=ll(p);if(n||!("loading"in e)){const S=!!l,x=!!s,$=!!c;let E;if(S){const P=Object.assign(Object.assign({prefixCls:`${p}-avatar`},AF(x,$)),$v(l));E=C("div",{className:`${p}-header`,children:C(vf,{...Object.assign({},P)})})}let w;if(x||$){let P;if(x){const I=Object.assign(Object.assign({prefixCls:`${p}-title`},DF(S,$)),$v(s));P=C(_F,{...Object.assign({},I)})}let N;if($){const I=Object.assign(Object.assign({prefixCls:`${p}-paragraph`},LF(S,x)),$v(c));N=C(TF,{...Object.assign({},I)})}w=ie("div",{className:`${p}-content`,children:[P,N]})}const R=te(p,{[`${p}-with-avatar`]:S,[`${p}-active`]:u,[`${p}-rtl`]:h==="rtl",[`${p}-round`]:d},g==null?void 0:g.className,r,o,m,y);return b(ie("div",{className:R,style:Object.assign(Object.assign({},g==null?void 0:g.style),i),children:[E,w]}))}return typeof a<"u"?a:null};sl.Button=xF;sl.Avatar=SF;sl.Input=OF;sl.Image=EF;sl.Node=IF;const zF=sl,gf=f.exports.createContext(null);var FF=function(t){var n=t.activeTabOffset,r=t.horizontal,o=t.rtl,i=t.indicator,a=i===void 0?{}:i,l=a.size,s=a.align,c=s===void 0?"center":s,u=f.exports.useState(),d=G(u,2),v=d[0],h=d[1],g=f.exports.useRef(),p=lt.useCallback(function(m){return typeof l=="function"?l(m):typeof l=="number"?l:m},[l]);function b(){St.cancel(g.current)}return f.exports.useEffect(function(){var m={};if(n)if(r){m.width=p(n.width);var y=o?"right":"left";c==="start"&&(m[y]=n[y]),c==="center"&&(m[y]=n[y]+n.width/2,m.transform=o?"translateX(50%)":"translateX(-50%)"),c==="end"&&(m[y]=n[y]+n.width,m.transform="translateX(-100%)")}else m.height=p(n.height),c==="start"&&(m.top=n.top),c==="center"&&(m.top=n.top+n.height/2,m.transform="translateY(-50%)"),c==="end"&&(m.top=n.top+n.height,m.transform="translateY(-100%)");return b(),g.current=St(function(){h(m)}),b},[n,r,o,c,p]),{style:v}},Xb={width:0,height:0,left:0,top:0};function kF(e,t,n){return f.exports.useMemo(function(){for(var r,o=new Map,i=t.get((r=e[0])===null||r===void 0?void 0:r.key)||Xb,a=i.left+i.width,l=0;lT?(z=N,E.current="x"):(z=I,E.current="y"),t(-z,-z)&&P.preventDefault()}var R=f.exports.useRef(null);R.current={onTouchStart:S,onTouchMove:x,onTouchEnd:$,onWheel:w},f.exports.useEffect(function(){function P(F){R.current.onTouchStart(F)}function N(F){R.current.onTouchMove(F)}function I(F){R.current.onTouchEnd(F)}function z(F){R.current.onWheel(F)}return document.addEventListener("touchmove",N,{passive:!1}),document.addEventListener("touchend",I,{passive:!1}),e.current.addEventListener("touchstart",P,{passive:!1}),e.current.addEventListener("wheel",z),function(){document.removeEventListener("touchmove",N),document.removeEventListener("touchend",I)}},[])}function u$(e){var t=f.exports.useState(0),n=G(t,2),r=n[0],o=n[1],i=f.exports.useRef(0),a=f.exports.useRef();return a.current=e,Hp(function(){var l;(l=a.current)===null||l===void 0||l.call(a)},[r]),function(){i.current===r&&(i.current+=1,o(i.current))}}function HF(e){var t=f.exports.useRef([]),n=f.exports.useState({}),r=G(n,2),o=r[1],i=f.exports.useRef(typeof e=="function"?e():e),a=u$(function(){var s=i.current;t.current.forEach(function(c){s=c(s)}),t.current=[],i.current=s,o({})});function l(s){t.current.push(s),a()}return[i.current,l]}var e1={width:0,height:0,left:0,top:0,right:0};function WF(e,t,n,r,o,i,a){var l=a.tabs,s=a.tabPosition,c=a.rtl,u,d,v;return["top","bottom"].includes(s)?(u="width",d=c?"right":"left",v=Math.abs(n)):(u="height",d="top",v=-n),f.exports.useMemo(function(){if(!l.length)return[0,0];for(var h=l.length,g=h,p=0;pv+t){g=p-1;break}}for(var m=0,y=h-1;y>=0;y-=1){var S=e.get(l[y].key)||e1;if(S[d]=g?[0,0]:[m,g]},[e,t,r,o,i,v,s,l.map(function(h){return h.key}).join("_"),c])}function t1(e){var t;return e instanceof Map?(t={},e.forEach(function(n,r){t[r]=n})):t=e,JSON.stringify(t)}var VF="TABS_DQ";function d$(e){return String(e).replace(/"/g,VF)}function f$(e,t,n,r){return!(!n||r||e===!1||e===void 0&&(t===!1||t===null))}var v$=f.exports.forwardRef(function(e,t){var n=e.prefixCls,r=e.editable,o=e.locale,i=e.style;return!r||r.showAdd===!1?null:C("button",{ref:t,type:"button",className:"".concat(n,"-nav-add"),style:i,"aria-label":(o==null?void 0:o.addAriaLabel)||"Add tab",onClick:function(l){r.onEdit("add",{event:l})},children:r.addIcon||"+"})}),n1=f.exports.forwardRef(function(e,t){var n=e.position,r=e.prefixCls,o=e.extra;if(!o)return null;var i,a={};return Qe(o)==="object"&&!f.exports.isValidElement(o)?a=o:a.right=o,n==="right"&&(i=a.right),n==="left"&&(i=a.left),i?C("div",{className:"".concat(r,"-extra-content"),ref:t,children:i}):null}),UF=f.exports.forwardRef(function(e,t){var n=e.prefixCls,r=e.id,o=e.tabs,i=e.locale,a=e.mobile,l=e.moreIcon,s=l===void 0?"More":l,c=e.moreTransitionName,u=e.style,d=e.className,v=e.editable,h=e.tabBarGutter,g=e.rtl,p=e.removeAriaLabel,b=e.onTabClick,m=e.getPopupContainer,y=e.popupClassName,S=f.exports.useState(!1),x=G(S,2),$=x[0],E=x[1],w=f.exports.useState(null),R=G(w,2),P=R[0],N=R[1],I="".concat(r,"-more-popup"),z="".concat(n,"-dropdown"),F=P!==null?"".concat(I,"-").concat(P):null,T=i==null?void 0:i.dropdownAriaLabel;function D(k,j){k.preventDefault(),k.stopPropagation(),v.onEdit("remove",{key:j,event:k})}var _=C(Qs,{onClick:function(j){var H=j.key,W=j.domEvent;b(H,W),E(!1)},prefixCls:"".concat(z,"-menu"),id:I,tabIndex:-1,role:"listbox","aria-activedescendant":F,selectedKeys:[P],"aria-label":T!==void 0?T:"expanded dropdown",children:o.map(function(k){var j=k.closable,H=k.disabled,W=k.closeIcon,Y=k.key,K=k.label,q=f$(j,W,v,H);return ie(cf,{id:"".concat(I,"-").concat(Y),role:"option","aria-controls":r&&"".concat(r,"-panel-").concat(Y),disabled:H,children:[C("span",{children:K}),q&&C("button",{type:"button","aria-label":p||"remove",tabIndex:0,className:"".concat(z,"-menu-item-remove"),onClick:function(Z){Z.stopPropagation(),D(Z,Y)},children:W||v.removeIcon||"\xD7"})]},Y)})});function O(k){for(var j=o.filter(function(q){return!q.disabled}),H=j.findIndex(function(q){return q.key===P})||0,W=j.length,Y=0;YVe?"left":"right"})}),F=G(z,2),T=F[0],D=F[1],_=Qb(0,function(We,Ve){!I&&p&&p({direction:We>Ve?"top":"bottom"})}),O=G(_,2),M=O[0],L=O[1],A=f.exports.useState([0,0]),B=G(A,2),k=B[0],j=B[1],H=f.exports.useState([0,0]),W=G(H,2),Y=W[0],K=W[1],q=f.exports.useState([0,0]),ee=G(q,2),Z=ee[0],Q=ee[1],ne=f.exports.useState([0,0]),ae=G(ne,2),J=ae[0],re=ae[1],fe=HF(new Map),ve=G(fe,2),pe=ve[0],oe=ve[1],se=kF(S,pe,Y[0]),le=Fc(k,I),Ce=Fc(Y,I),ce=Fc(Z,I),de=Fc(J,I),xe=lege?ge:We}var Se=f.exports.useRef(null),st=f.exports.useState(),nt=G(st,2),Ne=nt[0],Ee=nt[1];function _e(){Ee(Date.now())}function Be(){Se.current&&clearTimeout(Se.current)}jF(w,function(We,Ve){function vt(Ie,ze){Ie(function(Ke){var at=Pe(Ke+ze);return at})}return xe?(I?vt(D,We):vt(L,Ve),Be(),_e(),!0):!1}),f.exports.useEffect(function(){return Be(),Ne&&(Se.current=setTimeout(function(){Ee(0)},100)),Be},[Ne]);var qe=WF(se,he,I?T:M,Ce,ce,de,U(U({},e),{},{tabs:S})),it=G(qe,2),ft=it[0],ut=it[1],Ue=hn(function(){var We=arguments.length>0&&arguments[0]!==void 0?arguments[0]:a,Ve=se.get(We)||{width:0,height:0,left:0,right:0,top:0};if(I){var vt=T;l?Ve.rightT+he&&(vt=Ve.right+Ve.width-he):Ve.left<-T?vt=-Ve.left:Ve.left+Ve.width>-T+he&&(vt=-(Ve.left+Ve.width-he)),L(0),D(Pe(vt))}else{var Ie=M;Ve.top<-M?Ie=-Ve.top:Ve.top+Ve.height>-M+he&&(Ie=-(Ve.top+Ve.height-he)),D(0),L(Pe(Ie))}}),He={};d==="top"||d==="bottom"?He[l?"marginRight":"marginLeft"]=v:He.marginTop=v;var Xe=S.map(function(We,Ve){var vt=We.key;return C(GF,{id:o,prefixCls:y,tab:We,style:Ve===0?void 0:He,closable:We.closable,editable:c,active:vt===a,renderWrapper:h,removeAriaLabel:u==null?void 0:u.removeAriaLabel,onClick:function(ze){g(vt,ze)},onFocus:function(){Ue(vt),_e(),w.current&&(l||(w.current.scrollLeft=0),w.current.scrollTop=0)}},vt)}),Le=function(){return oe(function(){var Ve,vt=new Map,Ie=(Ve=R.current)===null||Ve===void 0?void 0:Ve.getBoundingClientRect();return S.forEach(function(ze){var Ke,at=ze.key,Gt=(Ke=R.current)===null||Ke===void 0?void 0:Ke.querySelector('[data-node-key="'.concat(d$(at),'"]'));if(Gt){var At=KF(Gt,Ie),Zt=G(At,4),Jt=Zt[0],kn=Zt[1],qn=Zt[2],pn=Zt[3];vt.set(at,{width:Jt,height:kn,left:qn,top:pn})}}),vt})};f.exports.useEffect(function(){Le()},[S.map(function(We){return We.key}).join("_")]);var Re=u$(function(){var We=ra(x),Ve=ra($),vt=ra(E);j([We[0]-Ve[0]-vt[0],We[1]-Ve[1]-vt[1]]);var Ie=ra(N);Q(Ie);var ze=ra(P);re(ze);var Ke=ra(R);K([Ke[0]-Ie[0],Ke[1]-Ie[1]]),Le()}),be=S.slice(0,ft),Ae=S.slice(ut+1),Me=[].concat(Oe(be),Oe(Ae)),$e=se.get(a),Te=FF({activeTabOffset:$e,horizontal:I,indicator:b,rtl:l}),ye=Te.style;f.exports.useEffect(function(){Ue()},[a,we,ge,t1($e),t1(se),I]),f.exports.useEffect(function(){Re()},[l]);var Ge=!!Me.length,Ze="".concat(y,"-nav-wrap"),et,ht,mt,ct;return I?l?(ht=T>0,et=T!==ge):(et=T<0,ht=T!==we):(mt=M<0,ct=M!==we),C(mr,{onResize:Re,children:ie("div",{ref:Fi(t,x),role:"tablist",className:te("".concat(y,"-nav"),n),style:r,onKeyDown:function(){_e()},children:[C(n1,{ref:$,position:"left",extra:s,prefixCls:y}),C(mr,{onResize:Re,children:C("div",{className:te(Ze,V(V(V(V({},"".concat(Ze,"-ping-left"),et),"".concat(Ze,"-ping-right"),ht),"".concat(Ze,"-ping-top"),mt),"".concat(Ze,"-ping-bottom"),ct)),ref:w,children:C(mr,{onResize:Re,children:ie("div",{ref:R,className:"".concat(y,"-nav-list"),style:{transform:"translate(".concat(T,"px, ").concat(M,"px)"),transition:Ne?"none":void 0},children:[Xe,C(v$,{ref:N,prefixCls:y,locale:u,editable:c,style:U(U({},Xe.length===0?void 0:He),{},{visibility:Ge?"hidden":null})}),C("div",{className:te("".concat(y,"-ink-bar"),V({},"".concat(y,"-ink-bar-animated"),i.inkBar)),style:ye})]})})})}),C(YF,{...e,removeAriaLabel:u==null?void 0:u.removeAriaLabel,ref:P,prefixCls:y,tabs:Me,className:!Ge&&ke,tabMoving:!!Ne}),C(n1,{ref:E,position:"right",extra:s,prefixCls:y})]})})}),p$=f.exports.forwardRef(function(e,t){var n=e.prefixCls,r=e.className,o=e.style,i=e.id,a=e.active,l=e.tabKey,s=e.children;return C("div",{id:i&&"".concat(i,"-panel-").concat(l),role:"tabpanel",tabIndex:a?0:-1,"aria-labelledby":i&&"".concat(i,"-tab-").concat(l),"aria-hidden":!a,style:o,className:te(n,a&&"".concat(n,"-active"),r),ref:t,children:s})}),qF=["renderTabBar"],XF=["label","key"],QF=function(t){var n=t.renderTabBar,r=Je(t,qF),o=f.exports.useContext(gf),i=o.tabs;if(n){var a=U(U({},r),{},{panes:i.map(function(l){var s=l.label,c=l.key,u=Je(l,XF);return C(p$,{tab:s,tabKey:c,...u},c)})});return n(a,r1)}return C(r1,{...r})},ZF=["key","forceRender","style","className","destroyInactiveTabPane"],JF=function(t){var n=t.id,r=t.activeKey,o=t.animated,i=t.tabPosition,a=t.destroyInactiveTabPane,l=f.exports.useContext(gf),s=l.prefixCls,c=l.tabs,u=o.tabPane,d="".concat(s,"-tabpane");return C("div",{className:te("".concat(s,"-content-holder")),children:C("div",{className:te("".concat(s,"-content"),"".concat(s,"-content-").concat(i),V({},"".concat(s,"-content-animated"),u)),children:c.map(function(v){var h=v.key,g=v.forceRender,p=v.style,b=v.className,m=v.destroyInactiveTabPane,y=Je(v,ZF),S=h===r;return C(to,{visible:S,forceRender:g,removeOnLeave:!!(a||m),leavedClassName:"".concat(d,"-hidden"),...o.tabPaneMotion,children:function(x,$){var E=x.style,w=x.className;return C(p$,{...y,prefixCls:d,id:n,tabKey:h,animated:u,active:S,style:U(U({},p),E),className:te(b,w),ref:$})}},h)})})})};function ek(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{inkBar:!0,tabPane:!1},t;return e===!1?t={inkBar:!1,tabPane:!1}:e===!0?t={inkBar:!0,tabPane:!1}:t=U({inkBar:!0},Qe(e)==="object"?e:{}),t.tabPaneMotion&&t.tabPane===void 0&&(t.tabPane=!0),!t.tabPaneMotion&&t.tabPane&&(t.tabPane=!1),t}var tk=["id","prefixCls","className","items","direction","activeKey","defaultActiveKey","editable","animated","tabPosition","tabBarGutter","tabBarStyle","tabBarExtraContent","locale","moreIcon","moreTransitionName","destroyInactiveTabPane","renderTabBar","onChange","onTabClick","onTabScroll","getPopupContainer","popupClassName","indicator"],o1=0,nk=f.exports.forwardRef(function(e,t){var n=e.id,r=e.prefixCls,o=r===void 0?"rc-tabs":r,i=e.className,a=e.items,l=e.direction,s=e.activeKey,c=e.defaultActiveKey,u=e.editable,d=e.animated,v=e.tabPosition,h=v===void 0?"top":v,g=e.tabBarGutter,p=e.tabBarStyle,b=e.tabBarExtraContent,m=e.locale,y=e.moreIcon,S=e.moreTransitionName,x=e.destroyInactiveTabPane,$=e.renderTabBar,E=e.onChange,w=e.onTabClick,R=e.onTabScroll,P=e.getPopupContainer,N=e.popupClassName,I=e.indicator,z=Je(e,tk),F=f.exports.useMemo(function(){return(a||[]).filter(function(re){return re&&Qe(re)==="object"&&"key"in re})},[a]),T=l==="rtl",D=ek(d),_=f.exports.useState(!1),O=G(_,2),M=O[0],L=O[1];f.exports.useEffect(function(){L(am())},[]);var A=kt(function(){var re;return(re=F[0])===null||re===void 0?void 0:re.key},{value:s,defaultValue:c}),B=G(A,2),k=B[0],j=B[1],H=f.exports.useState(function(){return F.findIndex(function(re){return re.key===k})}),W=G(H,2),Y=W[0],K=W[1];f.exports.useEffect(function(){var re=F.findIndex(function(ve){return ve.key===k});if(re===-1){var fe;re=Math.max(0,Math.min(Y,F.length-1)),j((fe=F[re])===null||fe===void 0?void 0:fe.key)}K(re)},[F.map(function(re){return re.key}).join("_"),k,Y]);var q=kt(null,{value:n}),ee=G(q,2),Z=ee[0],Q=ee[1];f.exports.useEffect(function(){n||(Q("rc-tabs-".concat(o1)),o1+=1)},[]);function ne(re,fe){w==null||w(re,fe);var ve=re!==k;j(re),ve&&(E==null||E(re))}var ae={id:Z,activeKey:k,animated:D,tabPosition:h,rtl:T,mobile:M},J=U(U({},ae),{},{editable:u,locale:m,moreIcon:y,moreTransitionName:S,tabBarGutter:g,onTabClick:ne,onTabScroll:R,extra:b,style:p,panes:null,getPopupContainer:P,popupClassName:N,indicator:I});return C(gf.Provider,{value:{tabs:F,prefixCls:o},children:ie("div",{ref:t,id:n,className:te(o,"".concat(o,"-").concat(h),V(V(V({},"".concat(o,"-mobile"),M),"".concat(o,"-editable"),u),"".concat(o,"-rtl"),T),i),...z,children:[C(QF,{...J,renderTabBar:$}),C(JF,{destroyInactiveTabPane:x,...ae,animated:D})]})})});const rk={motionAppear:!1,motionEnter:!0,motionLeave:!0};function ok(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{inkBar:!0,tabPane:!1},n;return t===!1?n={inkBar:!1,tabPane:!1}:t===!0?n={inkBar:!0,tabPane:!0}:n=Object.assign({inkBar:!0},typeof t=="object"?t:{}),n.tabPane&&(n.tabPaneMotion=Object.assign(Object.assign({},rk),{motionName:ni(e,"switch")})),n}var ik=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);ot)}function lk(e,t){if(e)return e;const n=Qo(t).map(r=>{if(f.exports.isValidElement(r)){const{key:o,props:i}=r,a=i||{},{tab:l}=a,s=ik(a,["tab"]);return Object.assign(Object.assign({key:String(o)},s),{label:l})}return null});return ak(n)}const sk=e=>{const{componentCls:t,motionDurationSlow:n}=e;return[{[t]:{[`${t}-switch`]:{"&-appear, &-enter":{transition:"none","&-start":{opacity:0},"&-active":{opacity:1,transition:`opacity ${n}`}},"&-leave":{position:"absolute",transition:"none",inset:0,"&-start":{opacity:1},"&-active":{opacity:0,transition:`opacity ${n}`}}}}},[Xa(e,"slide-up"),Xa(e,"slide-down")]]},ck=sk,uk=e=>{const{componentCls:t,tabsCardPadding:n,cardBg:r,cardGutter:o,colorBorderSecondary:i,itemSelectedColor:a}=e;return{[`${t}-card`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab`]:{margin:0,padding:n,background:r,border:`${X(e.lineWidth)} ${e.lineType} ${i}`,transition:`all ${e.motionDurationSlow} ${e.motionEaseInOut}`},[`${t}-tab-active`]:{color:a,background:e.colorBgContainer},[`${t}-ink-bar`]:{visibility:"hidden"}},[`&${t}-top, &${t}-bottom`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab + ${t}-tab`]:{marginLeft:{_skip_check_:!0,value:X(o)}}}},[`&${t}-top`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab`]:{borderRadius:`${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)} 0 0`},[`${t}-tab-active`]:{borderBottomColor:e.colorBgContainer}}},[`&${t}-bottom`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab`]:{borderRadius:`0 0 ${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)}`},[`${t}-tab-active`]:{borderTopColor:e.colorBgContainer}}},[`&${t}-left, &${t}-right`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab + ${t}-tab`]:{marginTop:X(o)}}},[`&${t}-left`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab`]:{borderRadius:{_skip_check_:!0,value:`${X(e.borderRadiusLG)} 0 0 ${X(e.borderRadiusLG)}`}},[`${t}-tab-active`]:{borderRightColor:{_skip_check_:!0,value:e.colorBgContainer}}}},[`&${t}-right`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab`]:{borderRadius:{_skip_check_:!0,value:`0 ${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)} 0`}},[`${t}-tab-active`]:{borderLeftColor:{_skip_check_:!0,value:e.colorBgContainer}}}}}}},dk=e=>{const{componentCls:t,itemHoverColor:n,dropdownEdgeChildVerticalPadding:r}=e;return{[`${t}-dropdown`]:Object.assign(Object.assign({},Qt(e)),{position:"absolute",top:-9999,left:{_skip_check_:!0,value:-9999},zIndex:e.zIndexPopup,display:"block","&-hidden":{display:"none"},[`${t}-dropdown-menu`]:{maxHeight:e.tabsDropdownHeight,margin:0,padding:`${X(r)} 0`,overflowX:"hidden",overflowY:"auto",textAlign:{_skip_check_:!0,value:"left"},listStyleType:"none",backgroundColor:e.colorBgContainer,backgroundClip:"padding-box",borderRadius:e.borderRadiusLG,outline:"none",boxShadow:e.boxShadowSecondary,"&-item":Object.assign(Object.assign({},ei),{display:"flex",alignItems:"center",minWidth:e.tabsDropdownWidth,margin:0,padding:`${X(e.paddingXXS)} ${X(e.paddingSM)}`,color:e.colorText,fontWeight:"normal",fontSize:e.fontSize,lineHeight:e.lineHeight,cursor:"pointer",transition:`all ${e.motionDurationSlow}`,"> span":{flex:1,whiteSpace:"nowrap"},"&-remove":{flex:"none",marginLeft:{_skip_check_:!0,value:e.marginSM},color:e.colorTextDescription,fontSize:e.fontSizeSM,background:"transparent",border:0,cursor:"pointer","&:hover":{color:n}},"&:hover":{background:e.controlItemBgHover},"&-disabled":{"&, &:hover":{color:e.colorTextDisabled,background:"transparent",cursor:"not-allowed"}}})}})}},fk=e=>{const{componentCls:t,margin:n,colorBorderSecondary:r,horizontalMargin:o,verticalItemPadding:i,verticalItemMargin:a,calc:l}=e;return{[`${t}-top, ${t}-bottom`]:{flexDirection:"column",[`> ${t}-nav, > div > ${t}-nav`]:{margin:o,"&::before":{position:"absolute",right:{_skip_check_:!0,value:0},left:{_skip_check_:!0,value:0},borderBottom:`${X(e.lineWidth)} ${e.lineType} ${r}`,content:"''"},[`${t}-ink-bar`]:{height:e.lineWidthBold,"&-animated":{transition:`width ${e.motionDurationSlow}, left ${e.motionDurationSlow},
+ right ${e.motionDurationSlow}`}},[`${t}-nav-wrap`]:{"&::before, &::after":{top:0,bottom:0,width:e.controlHeight},"&::before":{left:{_skip_check_:!0,value:0},boxShadow:e.boxShadowTabsOverflowLeft},"&::after":{right:{_skip_check_:!0,value:0},boxShadow:e.boxShadowTabsOverflowRight},[`&${t}-nav-wrap-ping-left::before`]:{opacity:1},[`&${t}-nav-wrap-ping-right::after`]:{opacity:1}}}},[`${t}-top`]:{[`> ${t}-nav,
+ > div > ${t}-nav`]:{"&::before":{bottom:0},[`${t}-ink-bar`]:{bottom:0}}},[`${t}-bottom`]:{[`> ${t}-nav, > div > ${t}-nav`]:{order:1,marginTop:n,marginBottom:0,"&::before":{top:0},[`${t}-ink-bar`]:{top:0}},[`> ${t}-content-holder, > div > ${t}-content-holder`]:{order:0}},[`${t}-left, ${t}-right`]:{[`> ${t}-nav, > div > ${t}-nav`]:{flexDirection:"column",minWidth:l(e.controlHeight).mul(1.25).equal(),[`${t}-tab`]:{padding:i,textAlign:"center"},[`${t}-tab + ${t}-tab`]:{margin:a},[`${t}-nav-wrap`]:{flexDirection:"column","&::before, &::after":{right:{_skip_check_:!0,value:0},left:{_skip_check_:!0,value:0},height:e.controlHeight},"&::before":{top:0,boxShadow:e.boxShadowTabsOverflowTop},"&::after":{bottom:0,boxShadow:e.boxShadowTabsOverflowBottom},[`&${t}-nav-wrap-ping-top::before`]:{opacity:1},[`&${t}-nav-wrap-ping-bottom::after`]:{opacity:1}},[`${t}-ink-bar`]:{width:e.lineWidthBold,"&-animated":{transition:`height ${e.motionDurationSlow}, top ${e.motionDurationSlow}`}},[`${t}-nav-list, ${t}-nav-operations`]:{flex:"1 0 auto",flexDirection:"column"}}},[`${t}-left`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-ink-bar`]:{right:{_skip_check_:!0,value:0}}},[`> ${t}-content-holder, > div > ${t}-content-holder`]:{marginLeft:{_skip_check_:!0,value:X(l(e.lineWidth).mul(-1).equal())},borderLeft:{_skip_check_:!0,value:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`},[`> ${t}-content > ${t}-tabpane`]:{paddingLeft:{_skip_check_:!0,value:e.paddingLG}}}},[`${t}-right`]:{[`> ${t}-nav, > div > ${t}-nav`]:{order:1,[`${t}-ink-bar`]:{left:{_skip_check_:!0,value:0}}},[`> ${t}-content-holder, > div > ${t}-content-holder`]:{order:0,marginRight:{_skip_check_:!0,value:l(e.lineWidth).mul(-1).equal()},borderRight:{_skip_check_:!0,value:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`},[`> ${t}-content > ${t}-tabpane`]:{paddingRight:{_skip_check_:!0,value:e.paddingLG}}}}}},vk=e=>{const{componentCls:t,cardPaddingSM:n,cardPaddingLG:r,horizontalItemPaddingSM:o,horizontalItemPaddingLG:i}=e;return{[t]:{"&-small":{[`> ${t}-nav`]:{[`${t}-tab`]:{padding:o,fontSize:e.titleFontSizeSM}}},"&-large":{[`> ${t}-nav`]:{[`${t}-tab`]:{padding:i,fontSize:e.titleFontSizeLG}}}},[`${t}-card`]:{[`&${t}-small`]:{[`> ${t}-nav`]:{[`${t}-tab`]:{padding:n}},[`&${t}-bottom`]:{[`> ${t}-nav ${t}-tab`]:{borderRadius:`0 0 ${X(e.borderRadius)} ${X(e.borderRadius)}`}},[`&${t}-top`]:{[`> ${t}-nav ${t}-tab`]:{borderRadius:`${X(e.borderRadius)} ${X(e.borderRadius)} 0 0`}},[`&${t}-right`]:{[`> ${t}-nav ${t}-tab`]:{borderRadius:{_skip_check_:!0,value:`0 ${X(e.borderRadius)} ${X(e.borderRadius)} 0`}}},[`&${t}-left`]:{[`> ${t}-nav ${t}-tab`]:{borderRadius:{_skip_check_:!0,value:`${X(e.borderRadius)} 0 0 ${X(e.borderRadius)}`}}}},[`&${t}-large`]:{[`> ${t}-nav`]:{[`${t}-tab`]:{padding:r}}}}}},pk=e=>{const{componentCls:t,itemActiveColor:n,itemHoverColor:r,iconCls:o,tabsHorizontalItemMargin:i,horizontalItemPadding:a,itemSelectedColor:l,itemColor:s}=e,c=`${t}-tab`;return{[c]:{position:"relative",WebkitTouchCallout:"none",WebkitTapHighlightColor:"transparent",display:"inline-flex",alignItems:"center",padding:a,fontSize:e.titleFontSize,background:"transparent",border:0,outline:"none",cursor:"pointer",color:s,"&-btn, &-remove":Object.assign({"&:focus:not(:focus-visible), &:active":{color:n}},Xd(e)),"&-btn":{outline:"none",transition:"all 0.3s",[`${c}-icon:not(:last-child)`]:{marginInlineEnd:e.marginSM}},"&-remove":{flex:"none",marginRight:{_skip_check_:!0,value:e.calc(e.marginXXS).mul(-1).equal()},marginLeft:{_skip_check_:!0,value:e.marginXS},color:e.colorTextDescription,fontSize:e.fontSizeSM,background:"transparent",border:"none",outline:"none",cursor:"pointer",transition:`all ${e.motionDurationSlow}`,"&:hover":{color:e.colorTextHeading}},"&:hover":{color:r},[`&${c}-active ${c}-btn`]:{color:l,textShadow:e.tabsActiveTextShadow},[`&${c}-disabled`]:{color:e.colorTextDisabled,cursor:"not-allowed"},[`&${c}-disabled ${c}-btn, &${c}-disabled ${t}-remove`]:{"&:focus, &:active":{color:e.colorTextDisabled}},[`& ${c}-remove ${o}`]:{margin:0},[`${o}:not(:last-child)`]:{marginRight:{_skip_check_:!0,value:e.marginSM}}},[`${c} + ${c}`]:{margin:{_skip_check_:!0,value:i}}}},gk=e=>{const{componentCls:t,tabsHorizontalItemMarginRTL:n,iconCls:r,cardGutter:o,calc:i}=e;return{[`${t}-rtl`]:{direction:"rtl",[`${t}-nav`]:{[`${t}-tab`]:{margin:{_skip_check_:!0,value:n},[`${t}-tab:last-of-type`]:{marginLeft:{_skip_check_:!0,value:0}},[r]:{marginRight:{_skip_check_:!0,value:0},marginLeft:{_skip_check_:!0,value:X(e.marginSM)}},[`${t}-tab-remove`]:{marginRight:{_skip_check_:!0,value:X(e.marginXS)},marginLeft:{_skip_check_:!0,value:X(i(e.marginXXS).mul(-1).equal())},[r]:{margin:0}}}},[`&${t}-left`]:{[`> ${t}-nav`]:{order:1},[`> ${t}-content-holder`]:{order:0}},[`&${t}-right`]:{[`> ${t}-nav`]:{order:0},[`> ${t}-content-holder`]:{order:1}},[`&${t}-card${t}-top, &${t}-card${t}-bottom`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-tab + ${t}-tab`]:{marginRight:{_skip_check_:!0,value:o},marginLeft:{_skip_check_:!0,value:0}}}}},[`${t}-dropdown-rtl`]:{direction:"rtl"},[`${t}-menu-item`]:{[`${t}-dropdown-rtl`]:{textAlign:{_skip_check_:!0,value:"right"}}}}},hk=e=>{const{componentCls:t,tabsCardPadding:n,cardHeight:r,cardGutter:o,itemHoverColor:i,itemActiveColor:a,colorBorderSecondary:l}=e;return{[t]:Object.assign(Object.assign(Object.assign(Object.assign({},Qt(e)),{display:"flex",[`> ${t}-nav, > div > ${t}-nav`]:{position:"relative",display:"flex",flex:"none",alignItems:"center",[`${t}-nav-wrap`]:{position:"relative",display:"flex",flex:"auto",alignSelf:"stretch",overflow:"hidden",whiteSpace:"nowrap",transform:"translate(0)","&::before, &::after":{position:"absolute",zIndex:1,opacity:0,transition:`opacity ${e.motionDurationSlow}`,content:"''",pointerEvents:"none"}},[`${t}-nav-list`]:{position:"relative",display:"flex",transition:`opacity ${e.motionDurationSlow}`},[`${t}-nav-operations`]:{display:"flex",alignSelf:"stretch"},[`${t}-nav-operations-hidden`]:{position:"absolute",visibility:"hidden",pointerEvents:"none"},[`${t}-nav-more`]:{position:"relative",padding:n,background:"transparent",border:0,color:e.colorText,"&::after":{position:"absolute",right:{_skip_check_:!0,value:0},bottom:0,left:{_skip_check_:!0,value:0},height:e.calc(e.controlHeightLG).div(8).equal(),transform:"translateY(100%)",content:"''"}},[`${t}-nav-add`]:Object.assign({minWidth:r,minHeight:r,marginLeft:{_skip_check_:!0,value:o},padding:`0 ${X(e.paddingXS)}`,background:"transparent",border:`${X(e.lineWidth)} ${e.lineType} ${l}`,borderRadius:`${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)} 0 0`,outline:"none",cursor:"pointer",color:e.colorText,transition:`all ${e.motionDurationSlow} ${e.motionEaseInOut}`,"&:hover":{color:i},"&:active, &:focus:not(:focus-visible)":{color:a}},Xd(e))},[`${t}-extra-content`]:{flex:"none"},[`${t}-ink-bar`]:{position:"absolute",background:e.inkBarColor,pointerEvents:"none"}}),pk(e)),{[`${t}-content`]:{position:"relative",width:"100%"},[`${t}-content-holder`]:{flex:"auto",minWidth:0,minHeight:0},[`${t}-tabpane`]:{outline:"none","&-hidden":{display:"none"}}}),[`${t}-centered`]:{[`> ${t}-nav, > div > ${t}-nav`]:{[`${t}-nav-wrap`]:{[`&:not([class*='${t}-nav-wrap-ping'])`]:{justifyContent:"center"}}}}}},mk=e=>{const t=e.controlHeightLG;return{zIndexPopup:e.zIndexPopupBase+50,cardBg:e.colorFillAlter,cardHeight:t,cardPadding:`${(t-Math.round(e.fontSize*e.lineHeight))/2-e.lineWidth}px ${e.padding}px`,cardPaddingSM:`${e.paddingXXS*1.5}px ${e.padding}px`,cardPaddingLG:`${e.paddingXS}px ${e.padding}px ${e.paddingXXS*1.5}px`,titleFontSize:e.fontSize,titleFontSizeLG:e.fontSizeLG,titleFontSizeSM:e.fontSize,inkBarColor:e.colorPrimary,horizontalMargin:`0 0 ${e.margin}px 0`,horizontalItemGutter:32,horizontalItemMargin:"",horizontalItemMarginRTL:"",horizontalItemPadding:`${e.paddingSM}px 0`,horizontalItemPaddingSM:`${e.paddingXS}px 0`,horizontalItemPaddingLG:`${e.padding}px 0`,verticalItemPadding:`${e.paddingXS}px ${e.paddingLG}px`,verticalItemMargin:`${e.margin}px 0 0 0`,itemColor:e.colorText,itemSelectedColor:e.colorPrimary,itemHoverColor:e.colorPrimaryHover,itemActiveColor:e.colorPrimaryActive,cardGutter:e.marginXXS/2}},yk=vn("Tabs",e=>{const t=$t(e,{tabsCardPadding:e.cardPadding,dropdownEdgeChildVerticalPadding:e.paddingXXS,tabsActiveTextShadow:"0 0 0.25px currentcolor",tabsDropdownHeight:200,tabsDropdownWidth:120,tabsHorizontalItemMargin:`0 0 0 ${X(e.horizontalItemGutter)}`,tabsHorizontalItemMarginRTL:`0 0 0 ${X(e.horizontalItemGutter)}`});return[vk(t),gk(t),fk(t),dk(t),uk(t),hk(t),ck(t)]},mk),bk=()=>null,Sk=bk;var Ck=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var t,n,r,o,i,a,l;const{type:s,className:c,rootClassName:u,size:d,onEdit:v,hideAdd:h,centered:g,addIcon:p,moreIcon:b,popupClassName:m,children:y,items:S,animated:x,style:$,indicatorSize:E,indicator:w}=e,R=Ck(e,["type","className","rootClassName","size","onEdit","hideAdd","centered","addIcon","moreIcon","popupClassName","children","items","animated","style","indicatorSize","indicator"]),{prefixCls:P}=R,{direction:N,tabs:I,getPrefixCls:z,getPopupContainer:F}=f.exports.useContext(ot),T=z("tabs",P),D=no(T),[_,O,M]=yk(T,D);let L;s==="editable-card"&&(L={onEdit:(Y,K)=>{let{key:q,event:ee}=K;v==null||v(Y==="add"?ee:q,Y)},removeIcon:C(eo,{}),addIcon:(p!=null?p:I==null?void 0:I.addIcon)||C(BP,{}),showAdd:h!==!0});const A=z(),B=So(d),k=lk(S,y),j=ok(T,x),H=Object.assign(Object.assign({},I==null?void 0:I.style),$),W={align:(t=w==null?void 0:w.align)!==null&&t!==void 0?t:(n=I==null?void 0:I.indicator)===null||n===void 0?void 0:n.align,size:(a=(o=(r=w==null?void 0:w.size)!==null&&r!==void 0?r:E)!==null&&o!==void 0?o:(i=I==null?void 0:I.indicator)===null||i===void 0?void 0:i.size)!==null&&a!==void 0?a:I==null?void 0:I.indicatorSize};return _(C(nk,{...Object.assign({direction:N,getPopupContainer:F,moreTransitionName:`${A}-slide-up`},R,{items:k,className:te({[`${T}-${B}`]:B,[`${T}-card`]:["card","editable-card"].includes(s),[`${T}-editable-card`]:s==="editable-card",[`${T}-centered`]:g},I==null?void 0:I.className,c,u,O,M,D),popupClassName:te(m,O,M,D),style:H,editable:L,moreIcon:(l=b!=null?b:I==null?void 0:I.moreIcon)!==null&&l!==void 0?l:C(JI,{}),prefixCls:T,animated:j,indicator:W})}))};g$.TabPane=Sk;const xk=g$;var wk=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var{prefixCls:t,className:n,hoverable:r=!0}=e,o=wk(e,["prefixCls","className","hoverable"]);const{getPrefixCls:i}=f.exports.useContext(ot),a=i("card",t),l=te(`${a}-grid`,n,{[`${a}-grid-hoverable`]:r});return C("div",{...Object.assign({},o,{className:l})})},h$=$k,Ek=e=>{const{antCls:t,componentCls:n,headerHeight:r,cardPaddingBase:o,tabsMarginBottom:i}=e;return Object.assign(Object.assign({display:"flex",justifyContent:"center",flexDirection:"column",minHeight:r,marginBottom:-1,padding:`0 ${X(o)}`,color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.headerFontSize,background:e.headerBg,borderBottom:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`,borderRadius:`${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)} 0 0`},Us()),{"&-wrapper":{width:"100%",display:"flex",alignItems:"center"},"&-title":Object.assign(Object.assign({display:"inline-block",flex:1},ei),{[`
+ > ${n}-typography,
+ > ${n}-typography-edit-content
+ `]:{insetInlineStart:0,marginTop:0,marginBottom:0}}),[`${t}-tabs-top`]:{clear:"both",marginBottom:i,color:e.colorText,fontWeight:"normal",fontSize:e.fontSize,"&-bar":{borderBottom:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorderSecondary}`}}})},Mk=e=>{const{cardPaddingBase:t,colorBorderSecondary:n,cardShadow:r,lineWidth:o}=e;return{width:"33.33%",padding:t,border:0,borderRadius:0,boxShadow:`
+ ${X(o)} 0 0 0 ${n},
+ 0 ${X(o)} 0 0 ${n},
+ ${X(o)} ${X(o)} 0 0 ${n},
+ ${X(o)} 0 0 0 ${n} inset,
+ 0 ${X(o)} 0 0 ${n} inset;
+ `,transition:`all ${e.motionDurationMid}`,"&-hoverable:hover":{position:"relative",zIndex:1,boxShadow:r}}},Ok=e=>{const{componentCls:t,iconCls:n,actionsLiMargin:r,cardActionsIconSize:o,colorBorderSecondary:i,actionsBg:a}=e;return Object.assign(Object.assign({margin:0,padding:0,listStyle:"none",background:a,borderTop:`${X(e.lineWidth)} ${e.lineType} ${i}`,display:"flex",borderRadius:`0 0 ${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)}`},Us()),{"& > li":{margin:r,color:e.colorTextDescription,textAlign:"center","> span":{position:"relative",display:"block",minWidth:e.calc(e.cardActionsIconSize).mul(2).equal(),fontSize:e.fontSize,lineHeight:e.lineHeight,cursor:"pointer","&:hover":{color:e.colorPrimary,transition:`color ${e.motionDurationMid}`},[`a:not(${t}-btn), > ${n}`]:{display:"inline-block",width:"100%",color:e.colorTextDescription,lineHeight:X(e.fontHeight),transition:`color ${e.motionDurationMid}`,"&:hover":{color:e.colorPrimary}},[`> ${n}`]:{fontSize:o,lineHeight:X(e.calc(o).mul(e.lineHeight).equal())}},"&:not(:last-child)":{borderInlineEnd:`${X(e.lineWidth)} ${e.lineType} ${i}`}}})},Rk=e=>Object.assign(Object.assign({margin:`${X(e.calc(e.marginXXS).mul(-1).equal())} 0`,display:"flex"},Us()),{"&-avatar":{paddingInlineEnd:e.padding},"&-detail":{overflow:"hidden",flex:1,"> div:not(:last-child)":{marginBottom:e.marginXS}},"&-title":Object.assign({color:e.colorTextHeading,fontWeight:e.fontWeightStrong,fontSize:e.fontSizeLG},ei),"&-description":{color:e.colorTextDescription}}),Ik=e=>{const{componentCls:t,cardPaddingBase:n,colorFillAlter:r}=e;return{[`${t}-head`]:{padding:`0 ${X(n)}`,background:r,"&-title":{fontSize:e.fontSize}},[`${t}-body`]:{padding:`${X(e.padding)} ${X(n)}`}}},Pk=e=>{const{componentCls:t}=e;return{overflow:"hidden",[`${t}-body`]:{userSelect:"none"}}},Tk=e=>{const{antCls:t,componentCls:n,cardShadow:r,cardHeadPadding:o,colorBorderSecondary:i,boxShadowTertiary:a,cardPaddingBase:l,extraColor:s}=e;return{[n]:Object.assign(Object.assign({},Qt(e)),{position:"relative",background:e.colorBgContainer,borderRadius:e.borderRadiusLG,[`&:not(${n}-bordered)`]:{boxShadow:a},[`${n}-head`]:Ek(e),[`${n}-extra`]:{marginInlineStart:"auto",color:s,fontWeight:"normal",fontSize:e.fontSize},[`${n}-body`]:Object.assign({padding:l,borderRadius:` 0 0 ${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)}`},Us()),[`${n}-grid`]:Mk(e),[`${n}-cover`]:{"> *":{display:"block",width:"100%"},[`img, img + ${t}-image-mask`]:{borderRadius:`${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)} 0 0`}},[`${n}-actions`]:Ok(e),[`${n}-meta`]:Rk(e)}),[`${n}-bordered`]:{border:`${X(e.lineWidth)} ${e.lineType} ${i}`,[`${n}-cover`]:{marginTop:-1,marginInlineStart:-1,marginInlineEnd:-1}},[`${n}-hoverable`]:{cursor:"pointer",transition:`box-shadow ${e.motionDurationMid}, border-color ${e.motionDurationMid}`,"&:hover":{borderColor:"transparent",boxShadow:r}},[`${n}-contain-grid`]:{borderRadius:`${X(e.borderRadiusLG)} ${X(e.borderRadiusLG)} 0 0 `,[`${n}-body`]:{display:"flex",flexWrap:"wrap"},[`&:not(${n}-loading) ${n}-body`]:{marginBlockStart:e.calc(e.lineWidth).mul(-1).equal(),marginInlineStart:e.calc(e.lineWidth).mul(-1).equal(),padding:0}},[`${n}-contain-tabs`]:{[`> ${n}-head`]:{minHeight:0,[`${n}-head-title, ${n}-extra`]:{paddingTop:o}}},[`${n}-type-inner`]:Ik(e),[`${n}-loading`]:Pk(e),[`${n}-rtl`]:{direction:"rtl"}}},Nk=e=>{const{componentCls:t,cardPaddingSM:n,headerHeightSM:r,headerFontSizeSM:o}=e;return{[`${t}-small`]:{[`> ${t}-head`]:{minHeight:r,padding:`0 ${X(n)}`,fontSize:o,[`> ${t}-head-wrapper`]:{[`> ${t}-extra`]:{fontSize:e.fontSize}}},[`> ${t}-body`]:{padding:n}},[`${t}-small${t}-contain-tabs`]:{[`> ${t}-head`]:{[`${t}-head-title, ${t}-extra`]:{paddingTop:0,display:"flex",alignItems:"center"}}}}},_k=e=>({headerBg:"transparent",headerFontSize:e.fontSizeLG,headerFontSizeSM:e.fontSize,headerHeight:e.fontSizeLG*e.lineHeightLG+e.padding*2,headerHeightSM:e.fontSize*e.lineHeight+e.paddingXS*2,actionsBg:e.colorBgContainer,actionsLiMargin:`${e.paddingSM}px 0`,tabsMarginBottom:-e.padding-e.lineWidth,extraColor:e.colorText}),Ak=vn("Card",e=>{const t=$t(e,{cardShadow:e.boxShadowCard,cardHeadPadding:e.padding,cardPaddingBase:e.paddingLG,cardActionsIconSize:e.fontSize,cardPaddingSM:12});return[Tk(t),Nk(t)]},_k);var i1=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{actionClasses:t,actions:n=[],actionStyle:r}=e;return C("ul",{className:t,style:r,children:n.map((o,i)=>{const a=`action-${i}`;return C("li",{style:{width:`${100/n.length}%`},children:C("span",{children:o})},a)})})},Lk=f.exports.forwardRef((e,t)=>{const{prefixCls:n,className:r,rootClassName:o,style:i,extra:a,headStyle:l={},bodyStyle:s={},title:c,loading:u,bordered:d=!0,size:v,type:h,cover:g,actions:p,tabList:b,children:m,activeTabKey:y,defaultActiveTabKey:S,tabBarExtraContent:x,hoverable:$,tabProps:E={},classNames:w,styles:R}=e,P=i1(e,["prefixCls","className","rootClassName","style","extra","headStyle","bodyStyle","title","loading","bordered","size","type","cover","actions","tabList","children","activeTabKey","defaultActiveTabKey","tabBarExtraContent","hoverable","tabProps","classNames","styles"]),{getPrefixCls:N,direction:I,card:z}=f.exports.useContext(ot),F=pe=>{var oe;(oe=e.onTabChange)===null||oe===void 0||oe.call(e,pe)},T=pe=>{var oe;return te((oe=z==null?void 0:z.classNames)===null||oe===void 0?void 0:oe[pe],w==null?void 0:w[pe])},D=pe=>{var oe;return Object.assign(Object.assign({},(oe=z==null?void 0:z.styles)===null||oe===void 0?void 0:oe[pe]),R==null?void 0:R[pe])},_=f.exports.useMemo(()=>{let pe=!1;return f.exports.Children.forEach(m,oe=>{oe&&oe.type&&oe.type===h$&&(pe=!0)}),pe},[m]),O=N("card",n),[M,L,A]=Ak(O),B=C(zF,{loading:!0,active:!0,paragraph:{rows:4},title:!1,children:m}),k=y!==void 0,j=Object.assign(Object.assign({},E),{[k?"activeKey":"defaultActiveKey"]:k?y:S,tabBarExtraContent:x});let H;const W=So(v),K=b?C(xk,{...Object.assign({size:!W||W==="default"?"large":W},j,{className:`${O}-head-tabs`,onChange:F,items:b.map(pe=>{var{tab:oe}=pe,se=i1(pe,["tab"]);return Object.assign({label:oe},se)})})}):null;if(c||a||K){const pe=te(`${O}-head`,T("header")),oe=te(`${O}-head-title`,T("title")),se=te(`${O}-extra`,T("extra")),le=Object.assign(Object.assign({},l),D("header"));H=ie("div",{className:pe,style:le,children:[ie("div",{className:`${O}-head-wrapper`,children:[c&&C("div",{className:oe,style:D("title"),children:c}),a&&C("div",{className:se,style:D("extra"),children:a})]}),K]})}const q=te(`${O}-cover`,T("cover")),ee=g?C("div",{className:q,style:D("cover"),children:g}):null,Z=te(`${O}-body`,T("body")),Q=Object.assign(Object.assign({},s),D("body")),ne=C("div",{className:Z,style:Q,children:u?B:m}),ae=te(`${O}-actions`,T("actions")),J=p&&p.length?C(Dk,{actionClasses:ae,actionStyle:D("actions"),actions:p}):null,re=lr(P,["onTabChange"]),fe=te(O,z==null?void 0:z.className,{[`${O}-loading`]:u,[`${O}-bordered`]:d,[`${O}-hoverable`]:$,[`${O}-contain-grid`]:_,[`${O}-contain-tabs`]:b&&b.length,[`${O}-${W}`]:W,[`${O}-type-${h}`]:!!h,[`${O}-rtl`]:I==="rtl"},r,o,L,A),ve=Object.assign(Object.assign({},z==null?void 0:z.style),i);return M(ie("div",{...Object.assign({ref:t},re,{className:fe,style:ve}),children:[H,ee,ne,J]}))}),zk=Lk;var Fk=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{prefixCls:t,className:n,avatar:r,title:o,description:i}=e,a=Fk(e,["prefixCls","className","avatar","title","description"]),{getPrefixCls:l}=f.exports.useContext(ot),s=l("card",t),c=te(`${s}-meta`,n),u=r?C("div",{className:`${s}-meta-avatar`,children:r}):null,d=o?C("div",{className:`${s}-meta-title`,children:o}):null,v=i?C("div",{className:`${s}-meta-description`,children:i}):null,h=d||v?ie("div",{className:`${s}-meta-detail`,children:[d,v]}):null;return ie("div",{...Object.assign({},a,{className:c}),children:[u,h]})},Bk=kk,Pm=zk;Pm.Grid=h$;Pm.Meta=Bk;const m$=Pm;function jk(e,t,n){var r=n||{},o=r.noTrailing,i=o===void 0?!1:o,a=r.noLeading,l=a===void 0?!1:a,s=r.debounceMode,c=s===void 0?void 0:s,u,d=!1,v=0;function h(){u&&clearTimeout(u)}function g(b){var m=b||{},y=m.upcomingOnly,S=y===void 0?!1:y;h(),d=!S}function p(){for(var b=arguments.length,m=new Array(b),y=0;ye?l?(v=Date.now(),i||(u=setTimeout(c?E:$,e))):$():i!==!0&&(u=setTimeout(c?E:$,c===void 0?e-x:e))}return p.cancel=g,p}function Hk(e,t,n){var r=n||{},o=r.atBegin,i=o===void 0?!1:o;return jk(e,t,{debounceMode:i!==!1})}function Wk(e){return!!(e.addonBefore||e.addonAfter)}function Vk(e){return!!(e.prefix||e.suffix||e.allowClear)}function od(e,t,n,r){if(!!n){var o=t;if(t.type==="click"){var i=e.cloneNode(!0);o=Object.create(t,{target:{value:i},currentTarget:{value:i}}),i.value="",n(o);return}if(e.type!=="file"&&r!==void 0){var a=e.cloneNode(!0);o=Object.create(t,{target:{value:a},currentTarget:{value:a}}),a.value=r,n(o);return}n(o)}}function Uk(e,t){if(!!e){e.focus(t);var n=t||{},r=n.cursor;if(r){var o=e.value.length;switch(r){case"start":e.setSelectionRange(0,0);break;case"end":e.setSelectionRange(o,o);break;default:e.setSelectionRange(0,o)}}}}var y$=function(t){var n,r,o=t.inputElement,i=t.children,a=t.prefixCls,l=t.prefix,s=t.suffix,c=t.addonBefore,u=t.addonAfter,d=t.className,v=t.style,h=t.disabled,g=t.readOnly,p=t.focused,b=t.triggerFocus,m=t.allowClear,y=t.value,S=t.handleReset,x=t.hidden,$=t.classes,E=t.classNames,w=t.dataAttrs,R=t.styles,P=t.components,N=i!=null?i:o,I=(P==null?void 0:P.affixWrapper)||"span",z=(P==null?void 0:P.groupWrapper)||"span",F=(P==null?void 0:P.wrapper)||"span",T=(P==null?void 0:P.groupAddon)||"span",D=f.exports.useRef(null),_=function(J){var re;(re=D.current)!==null&&re!==void 0&&re.contains(J.target)&&(b==null||b())},O=Vk(t),M=f.exports.cloneElement(N,{value:y,className:te(N.props.className,!O&&(E==null?void 0:E.variant))||null});if(O){var L,A=null;if(m){var B,k=!h&&!g&&y,j="".concat(a,"-clear-icon"),H=Qe(m)==="object"&&m!==null&&m!==void 0&&m.clearIcon?m.clearIcon:"\u2716";A=C("span",{onClick:S,onMouseDown:function(J){return J.preventDefault()},className:te(j,(B={},V(B,"".concat(j,"-hidden"),!k),V(B,"".concat(j,"-has-suffix"),!!s),B)),role:"button",tabIndex:-1,children:H})}var W="".concat(a,"-affix-wrapper"),Y=te(W,(L={},V(L,"".concat(a,"-disabled"),h),V(L,"".concat(W,"-disabled"),h),V(L,"".concat(W,"-focused"),p),V(L,"".concat(W,"-readonly"),g),V(L,"".concat(W,"-input-with-clear-btn"),s&&m&&y),L),$==null?void 0:$.affixWrapper,E==null?void 0:E.affixWrapper,E==null?void 0:E.variant),K=(s||m)&&ie("span",{className:te("".concat(a,"-suffix"),E==null?void 0:E.suffix),style:R==null?void 0:R.suffix,children:[A,s]});M=ie(I,{className:Y,style:R==null?void 0:R.affixWrapper,onClick:_,...w==null?void 0:w.affixWrapper,ref:D,children:[l&&C("span",{className:te("".concat(a,"-prefix"),E==null?void 0:E.prefix),style:R==null?void 0:R.prefix,children:l}),M,K]})}if(Wk(t)){var q="".concat(a,"-group"),ee="".concat(q,"-addon"),Z="".concat(q,"-wrapper"),Q=te("".concat(a,"-wrapper"),q,$==null?void 0:$.wrapper,E==null?void 0:E.wrapper),ne=te(Z,V({},"".concat(Z,"-disabled"),h),$==null?void 0:$.group,E==null?void 0:E.groupWrapper);M=C(z,{className:ne,children:ie(F,{className:Q,children:[c&&C(T,{className:ee,children:c}),M,u&&C(T,{className:ee,children:u})]})})}return lt.cloneElement(M,{className:te((n=M.props)===null||n===void 0?void 0:n.className,d)||null,style:U(U({},(r=M.props)===null||r===void 0?void 0:r.style),v),hidden:x})},Yk=["show"];function b$(e,t){return f.exports.useMemo(function(){var n={};t&&(n.show=Qe(t)==="object"&&t.formatter?t.formatter:!!t),n=U(U({},n),e);var r=n,o=r.show,i=Je(r,Yk);return U(U({},i),{},{show:!!o,showFormatter:typeof o=="function"?o:void 0,strategy:i.strategy||function(a){return a.length}})},[e,t])}var Gk=["autoComplete","onChange","onFocus","onBlur","onPressEnter","onKeyDown","prefixCls","disabled","htmlSize","className","maxLength","suffix","showCount","count","type","classes","classNames","styles","onCompositionStart","onCompositionEnd"],Kk=f.exports.forwardRef(function(e,t){var n=e.autoComplete,r=e.onChange,o=e.onFocus,i=e.onBlur,a=e.onPressEnter,l=e.onKeyDown,s=e.prefixCls,c=s===void 0?"rc-input":s,u=e.disabled,d=e.htmlSize,v=e.className,h=e.maxLength,g=e.suffix,p=e.showCount,b=e.count,m=e.type,y=m===void 0?"text":m,S=e.classes,x=e.classNames,$=e.styles,E=e.onCompositionStart,w=e.onCompositionEnd,R=Je(e,Gk),P=f.exports.useState(!1),N=G(P,2),I=N[0],z=N[1],F=f.exports.useRef(!1),T=f.exports.useRef(null),D=function(se){T.current&&Uk(T.current,se)},_=kt(e.defaultValue,{value:e.value}),O=G(_,2),M=O[0],L=O[1],A=M==null?"":String(M),B=f.exports.useState(null),k=G(B,2),j=k[0],H=k[1],W=b$(b,p),Y=W.max||h,K=W.strategy(A),q=!!Y&&K>Y;f.exports.useImperativeHandle(t,function(){return{focus:D,blur:function(){var se;(se=T.current)===null||se===void 0||se.blur()},setSelectionRange:function(se,le,Ce){var ce;(ce=T.current)===null||ce===void 0||ce.setSelectionRange(se,le,Ce)},select:function(){var se;(se=T.current)===null||se===void 0||se.select()},input:T.current}}),f.exports.useEffect(function(){z(function(oe){return oe&&u?!1:oe})},[u]);var ee=function(se,le,Ce){var ce=le;if(!F.current&&W.exceedFormatter&&W.max&&W.strategy(le)>W.max){if(ce=W.exceedFormatter(le,{max:W.max}),le!==ce){var de,xe;H([((de=T.current)===null||de===void 0?void 0:de.selectionStart)||0,((xe=T.current)===null||xe===void 0?void 0:xe.selectionEnd)||0])}}else if(Ce.source==="compositionEnd")return;L(ce),T.current&&od(T.current,se,r,ce)};f.exports.useEffect(function(){if(j){var oe;(oe=T.current)===null||oe===void 0||oe.setSelectionRange.apply(oe,Oe(j))}},[j]);var Z=function(se){ee(se,se.target.value,{source:"change"})},Q=function(se){F.current=!1,ee(se,se.currentTarget.value,{source:"compositionEnd"}),w==null||w(se)},ne=function(se){a&&se.key==="Enter"&&a(se),l==null||l(se)},ae=function(se){z(!0),o==null||o(se)},J=function(se){z(!1),i==null||i(se)},re=function(se){L(""),D(),T.current&&od(T.current,se,r)},fe=q&&"".concat(c,"-out-of-range"),ve=function(){var se=lr(e,["prefixCls","onPressEnter","addonBefore","addonAfter","prefix","suffix","allowClear","defaultValue","showCount","count","classes","htmlSize","styles","classNames"]);return C("input",{autoComplete:n,...se,onChange:Z,onFocus:ae,onBlur:J,onKeyDown:ne,className:te(c,V({},"".concat(c,"-disabled"),u),x==null?void 0:x.input),style:$==null?void 0:$.input,ref:T,size:d,type:y,onCompositionStart:function(Ce){F.current=!0,E==null||E(Ce)},onCompositionEnd:Q})},pe=function(){var se=Number(Y)>0;if(g||W.show){var le=W.showFormatter?W.showFormatter({value:A,count:K,maxLength:Y}):"".concat(K).concat(se?" / ".concat(Y):"");return ie(Tt,{children:[W.show&&C("span",{className:te("".concat(c,"-show-count-suffix"),V({},"".concat(c,"-show-count-has-suffix"),!!g),x==null?void 0:x.count),style:U({},$==null?void 0:$.count),children:le}),g]})}return null};return C(y$,{...R,prefixCls:c,className:te(v,fe),handleReset:re,value:A,focused:I,triggerFocus:D,suffix:pe(),disabled:u,classes:S,classNames:x,styles:$,children:ve()})});const qk=e=>{const{getPrefixCls:t,direction:n}=f.exports.useContext(ot),{prefixCls:r,className:o}=e,i=t("input-group",r),a=t("input"),[l,s]=Im(a),c=te(i,{[`${i}-lg`]:e.size==="large",[`${i}-sm`]:e.size==="small",[`${i}-compact`]:e.compact,[`${i}-rtl`]:n==="rtl"},s,o),u=f.exports.useContext(Jr),d=f.exports.useMemo(()=>Object.assign(Object.assign({},u),{isFormItemInput:!1}),[u]);return l(C("span",{className:c,style:e.style,onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave,onFocus:e.onFocus,onBlur:e.onBlur,children:C(Jr.Provider,{value:d,children:e.children})}))},Xk=qk;function S$(e,t){const n=f.exports.useRef([]),r=()=>{n.current.push(setTimeout(()=>{var o,i,a,l;((o=e.current)===null||o===void 0?void 0:o.input)&&((i=e.current)===null||i===void 0?void 0:i.input.getAttribute("type"))==="password"&&((a=e.current)===null||a===void 0?void 0:a.input.hasAttribute("value"))&&((l=e.current)===null||l===void 0||l.input.removeAttribute("value"))}))};return f.exports.useEffect(()=>(t&&r(),()=>n.current.forEach(o=>{o&&clearTimeout(o)})),[]),r}function Qk(e){return!!(e.prefix||e.suffix||e.allowClear||e.showCount)}const Zk=e=>{let t;return typeof e=="object"&&(e==null?void 0:e.clearIcon)?t=e:e&&(t={clearIcon:C(Nd,{})}),t},Jk=Zk;var e7=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var n;const{prefixCls:r,bordered:o=!0,status:i,size:a,disabled:l,onBlur:s,onFocus:c,suffix:u,allowClear:d,addonAfter:v,addonBefore:h,className:g,style:p,styles:b,rootClassName:m,onChange:y,classNames:S,variant:x}=e,$=e7(e,["prefixCls","bordered","status","size","disabled","onBlur","onFocus","suffix","allowClear","addonAfter","addonBefore","className","style","styles","rootClassName","onChange","classNames","variant"]),{getPrefixCls:E,direction:w,input:R}=lt.useContext(ot),P=E("input",r),N=f.exports.useRef(null),I=no(P),[z,F,T]=Im(P,I),{compactSize:D,compactItemClassnames:_}=ef(P,w),O=So(ae=>{var J;return(J=a!=null?a:D)!==null&&J!==void 0?J:ae}),M=lt.useContext(rl),L=l!=null?l:M,{status:A,hasFeedback:B,feedbackIcon:k}=f.exports.useContext(Jr),j=dm(A,i),H=Qk(e)||!!B;f.exports.useRef(H);const W=S$(N,!0),Y=ae=>{W(),s==null||s(ae)},K=ae=>{W(),c==null||c(ae)},q=ae=>{W(),y==null||y(ae)},ee=(B||u)&&ie(Tt,{children:[u,B&&k]}),Z=Jk(d),[Q,ne]=vm(x,o);return z(C(Kk,{...Object.assign({ref:xr(t,N),prefixCls:P,autoComplete:R==null?void 0:R.autoComplete},$,{disabled:L,onBlur:Y,onFocus:K,style:Object.assign(Object.assign({},R==null?void 0:R.style),p),styles:Object.assign(Object.assign({},R==null?void 0:R.styles),b),suffix:ee,allowClear:Z,className:te(g,m,T,I,_,R==null?void 0:R.className),onChange:q,addonAfter:v&&C(ig,{children:C(db,{override:!0,status:!0,children:v})}),addonBefore:h&&C(ig,{children:C(db,{override:!0,status:!0,children:h})}),classNames:Object.assign(Object.assign(Object.assign({},S),R==null?void 0:R.classNames),{input:te({[`${P}-sm`]:O==="small",[`${P}-lg`]:O==="large",[`${P}-rtl`]:w==="rtl"},S==null?void 0:S.input,(n=R==null?void 0:R.classNames)===null||n===void 0?void 0:n.input,F),variant:te({[`${P}-${Q}`]:ne},ed(P,j)),affixWrapper:te({[`${P}-affix-wrapper-sm`]:O==="small",[`${P}-affix-wrapper-lg`]:O==="large",[`${P}-affix-wrapper-rtl`]:w==="rtl"},F),wrapper:te({[`${P}-group-rtl`]:w==="rtl"},F),groupWrapper:te({[`${P}-group-wrapper-sm`]:O==="small",[`${P}-group-wrapper-lg`]:O==="large",[`${P}-group-wrapper-rtl`]:w==="rtl",[`${P}-group-wrapper-${Q}`]:ne},ed(`${P}-group-wrapper`,j,B),F)})})}))}),Tm=n7;var r7=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);oe?C(sx,{}):C(rP,{}),i7={click:"onClick",hover:"onMouseOver"},a7=f.exports.forwardRef((e,t)=>{const{visibilityToggle:n=!0}=e,r=typeof n=="object"&&n.visible!==void 0,[o,i]=f.exports.useState(()=>r?n.visible:!1),a=f.exports.useRef(null);f.exports.useEffect(()=>{r&&i(n.visible)},[r,n]);const l=S$(a),s=()=>{const{disabled:$}=e;$||(o&&l(),i(E=>{var w;const R=!E;return typeof n=="object"&&((w=n.onVisibleChange)===null||w===void 0||w.call(n,R)),R}))},c=$=>{const{action:E="click",iconRender:w=o7}=e,R=i7[E]||"",P=w(o),N={[R]:s,className:`${$}-icon`,key:"passwordIcon",onMouseDown:I=>{I.preventDefault()},onMouseUp:I=>{I.preventDefault()}};return f.exports.cloneElement(f.exports.isValidElement(P)?P:C("span",{children:P}),N)},{className:u,prefixCls:d,inputPrefixCls:v,size:h}=e,g=r7(e,["className","prefixCls","inputPrefixCls","size"]),{getPrefixCls:p}=f.exports.useContext(ot),b=p("input",v),m=p("input-password",d),y=n&&c(m),S=te(m,u,{[`${m}-${h}`]:!!h}),x=Object.assign(Object.assign({},lr(g,["suffix","iconRender","visibilityToggle"])),{type:o?"text":"password",className:S,prefixCls:b,suffix:y});return h&&(x.size=h),C(Tm,{...Object.assign({ref:xr(t,a)},x)})}),l7=a7;var s7=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{prefixCls:n,inputPrefixCls:r,className:o,size:i,suffix:a,enterButton:l=!1,addonAfter:s,loading:c,disabled:u,onSearch:d,onChange:v,onCompositionStart:h,onCompositionEnd:g}=e,p=s7(e,["prefixCls","inputPrefixCls","className","size","suffix","enterButton","addonAfter","loading","disabled","onSearch","onChange","onCompositionStart","onCompositionEnd"]),{getPrefixCls:b,direction:m}=f.exports.useContext(ot),y=f.exports.useRef(!1),S=b("input-search",n),x=b("input",r),{compactSize:$}=ef(S,m),E=So(A=>{var B;return(B=i!=null?i:$)!==null&&B!==void 0?B:A}),w=f.exports.useRef(null),R=A=>{A&&A.target&&A.type==="click"&&d&&d(A.target.value,A,{source:"clear"}),v&&v(A)},P=A=>{var B;document.activeElement===((B=w.current)===null||B===void 0?void 0:B.input)&&A.preventDefault()},N=A=>{var B,k;d&&d((k=(B=w.current)===null||B===void 0?void 0:B.input)===null||k===void 0?void 0:k.value,A,{source:"input"})},I=A=>{y.current||c||N(A)},z=typeof l=="boolean"?C(_d,{}):null,F=`${S}-button`;let T;const D=l||{},_=D.type&&D.type.__ANT_BUTTON===!0;_||D.type==="button"?T=ti(D,Object.assign({onMouseDown:P,onClick:A=>{var B,k;(k=(B=D==null?void 0:D.props)===null||B===void 0?void 0:B.onClick)===null||k===void 0||k.call(B,A),N(A)},key:"enterButton"},_?{className:F,size:E}:{})):T=C(Xu,{className:F,type:l?"primary":void 0,size:E,disabled:u,onMouseDown:P,onClick:N,loading:c,icon:z,children:l},"enterButton"),s&&(T=[T,ti(s,{key:"addonAfter"})]);const O=te(S,{[`${S}-rtl`]:m==="rtl",[`${S}-${E}`]:!!E,[`${S}-with-button`]:!!l},o),M=A=>{y.current=!0,h==null||h(A)},L=A=>{y.current=!1,g==null||g(A)};return C(Tm,{...Object.assign({ref:xr(w,t),onPressEnter:I},p,{size:E,onCompositionStart:M,onCompositionEnd:L,prefixCls:x,addonAfter:T,suffix:a,onChange:R,className:O,disabled:u})})}),u7=c7;var d7=`
+ min-height:0 !important;
+ max-height:none !important;
+ height:0 !important;
+ visibility:hidden !important;
+ overflow:hidden !important;
+ position:absolute !important;
+ z-index:-1000 !important;
+ top:0 !important;
+ right:0 !important;
+ pointer-events: none !important;
+`,f7=["letter-spacing","line-height","padding-top","padding-bottom","font-family","font-weight","font-size","font-variant","text-rendering","text-transform","width","text-indent","padding-left","padding-right","border-width","box-sizing","word-break","white-space"],Ev={},dr;function v7(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=e.getAttribute("id")||e.getAttribute("data-reactid")||e.getAttribute("name");if(t&&Ev[n])return Ev[n];var r=window.getComputedStyle(e),o=r.getPropertyValue("box-sizing")||r.getPropertyValue("-moz-box-sizing")||r.getPropertyValue("-webkit-box-sizing"),i=parseFloat(r.getPropertyValue("padding-bottom"))+parseFloat(r.getPropertyValue("padding-top")),a=parseFloat(r.getPropertyValue("border-bottom-width"))+parseFloat(r.getPropertyValue("border-top-width")),l=f7.map(function(c){return"".concat(c,":").concat(r.getPropertyValue(c))}).join(";"),s={sizingStyle:l,paddingSize:i,borderSize:a,boxSizing:o};return t&&n&&(Ev[n]=s),s}function p7(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:null,r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:null;dr||(dr=document.createElement("textarea"),dr.setAttribute("tab-index","-1"),dr.setAttribute("aria-hidden","true"),document.body.appendChild(dr)),e.getAttribute("wrap")?dr.setAttribute("wrap",e.getAttribute("wrap")):dr.removeAttribute("wrap");var o=v7(e,t),i=o.paddingSize,a=o.borderSize,l=o.boxSizing,s=o.sizingStyle;dr.setAttribute("style","".concat(s,";").concat(d7)),dr.value=e.value||e.placeholder||"";var c=void 0,u=void 0,d,v=dr.scrollHeight;if(l==="border-box"?v+=a:l==="content-box"&&(v-=i),n!==null||r!==null){dr.value=" ";var h=dr.scrollHeight-i;n!==null&&(c=h*n,l==="border-box"&&(c=c+i+a),v=Math.max(c,v)),r!==null&&(u=h*r,l==="border-box"&&(u=u+i+a),d=v>u?"":"hidden",v=Math.min(u,v))}var g={height:v,overflowY:d,resize:"none"};return c&&(g.minHeight=c),u&&(g.maxHeight=u),g}var g7=["prefixCls","onPressEnter","defaultValue","value","autoSize","onResize","className","style","disabled","onChange","onInternalAutoSize"],Mv=0,Ov=1,Rv=2,h7=f.exports.forwardRef(function(e,t){var n=e,r=n.prefixCls;n.onPressEnter;var o=n.defaultValue,i=n.value,a=n.autoSize,l=n.onResize,s=n.className,c=n.style,u=n.disabled,d=n.onChange;n.onInternalAutoSize;var v=Je(n,g7),h=kt(o,{value:i,postState:function(H){return H!=null?H:""}}),g=G(h,2),p=g[0],b=g[1],m=function(H){b(H.target.value),d==null||d(H)},y=f.exports.useRef();f.exports.useImperativeHandle(t,function(){return{textArea:y.current}});var S=f.exports.useMemo(function(){return a&&Qe(a)==="object"?[a.minRows,a.maxRows]:[]},[a]),x=G(S,2),$=x[0],E=x[1],w=!!a,R=function(){try{if(document.activeElement===y.current){var H=y.current,W=H.selectionStart,Y=H.selectionEnd,K=H.scrollTop;y.current.setSelectionRange(W,Y),y.current.scrollTop=K}}catch{}},P=f.exports.useState(Rv),N=G(P,2),I=N[0],z=N[1],F=f.exports.useState(),T=G(F,2),D=T[0],_=T[1],O=function(){z(Mv)};Nt(function(){w&&O()},[i,$,E,w]),Nt(function(){if(I===Mv)z(Ov);else if(I===Ov){var j=p7(y.current,!1,$,E);z(Rv),_(j)}else R()},[I]);var M=f.exports.useRef(),L=function(){St.cancel(M.current)},A=function(H){I===Rv&&(l==null||l(H),a&&(L(),M.current=St(function(){O()})))};f.exports.useEffect(function(){return L},[]);var B=w?D:null,k=U(U({},c),B);return(I===Mv||I===Ov)&&(k.overflowY="hidden",k.overflowX="hidden"),C(mr,{onResize:A,disabled:!(a||l),children:C("textarea",{...v,ref:y,style:k,className:te(r,s,V({},"".concat(r,"-disabled"),u)),disabled:u,value:p,onChange:m})})}),m7=["defaultValue","value","onFocus","onBlur","onChange","allowClear","maxLength","onCompositionStart","onCompositionEnd","suffix","prefixCls","showCount","count","className","style","disabled","hidden","classNames","styles","onResize"],y7=lt.forwardRef(function(e,t){var n,r,o=e.defaultValue,i=e.value,a=e.onFocus,l=e.onBlur,s=e.onChange,c=e.allowClear,u=e.maxLength,d=e.onCompositionStart,v=e.onCompositionEnd,h=e.suffix,g=e.prefixCls,p=g===void 0?"rc-textarea":g,b=e.showCount,m=e.count,y=e.className,S=e.style,x=e.disabled,$=e.hidden,E=e.classNames,w=e.styles,R=e.onResize,P=Je(e,m7),N=kt(o,{value:i,defaultValue:o}),I=G(N,2),z=I[0],F=I[1],T=z==null?"":String(z),D=lt.useState(!1),_=G(D,2),O=_[0],M=_[1],L=lt.useRef(!1),A=lt.useState(null),B=G(A,2),k=B[0],j=B[1],H=f.exports.useRef(null),W=function(){var ge;return(ge=H.current)===null||ge===void 0?void 0:ge.textArea},Y=function(){W().focus()};f.exports.useImperativeHandle(t,function(){return{resizableTextArea:H.current,focus:Y,blur:function(){W().blur()}}}),f.exports.useEffect(function(){M(function(we){return!x&&we})},[x]);var K=lt.useState(null),q=G(K,2),ee=q[0],Z=q[1];lt.useEffect(function(){if(ee){var we;(we=W()).setSelectionRange.apply(we,Oe(ee))}},[ee]);var Q=b$(m,b),ne=(n=Q.max)!==null&&n!==void 0?n:u,ae=Number(ne)>0,J=Q.strategy(T),re=!!ne&&J>ne,fe=function(ge,Pe){var Se=Pe;!L.current&&Q.exceedFormatter&&Q.max&&Q.strategy(Pe)>Q.max&&(Se=Q.exceedFormatter(Pe,{max:Q.max}),Pe!==Se&&Z([W().selectionStart||0,W().selectionEnd||0])),F(Se),od(ge.currentTarget,ge,s,Se)},ve=function(ge){L.current=!0,d==null||d(ge)},pe=function(ge){L.current=!1,fe(ge,ge.currentTarget.value),v==null||v(ge)},oe=function(ge){fe(ge,ge.target.value)},se=function(ge){var Pe=P.onPressEnter,Se=P.onKeyDown;ge.key==="Enter"&&Pe&&Pe(ge),Se==null||Se(ge)},le=function(ge){M(!0),a==null||a(ge)},Ce=function(ge){M(!1),l==null||l(ge)},ce=function(ge){F(""),Y(),od(W(),ge,s)},de=h,xe;Q.show&&(Q.showFormatter?xe=Q.showFormatter({value:T,count:J,maxLength:ne}):xe="".concat(J).concat(ae?" / ".concat(ne):""),de=ie(Tt,{children:[de,C("span",{className:te("".concat(p,"-data-count"),E==null?void 0:E.count),style:w==null?void 0:w.count,children:xe})]}));var he=function(ge){var Pe;R==null||R(ge),(Pe=W())!==null&&Pe!==void 0&&Pe.style.height&&j(!0)},ke=!P.autoSize&&!b&&!c;return C(y$,{value:T,allowClear:c,handleReset:ce,suffix:de,prefixCls:p,classNames:U(U({},E),{},{affixWrapper:te(E==null?void 0:E.affixWrapper,(r={},V(r,"".concat(p,"-show-count"),b),V(r,"".concat(p,"-textarea-allow-clear"),c),r))}),disabled:x,focused:O,className:te(y,re&&"".concat(p,"-out-of-range")),style:U(U({},S),k&&!ke?{height:"auto"}:{}),dataAttrs:{affixWrapper:{"data-count":typeof xe=="string"?xe:void 0}},hidden:$,children:C(h7,{...P,maxLength:u,onKeyDown:se,onChange:oe,onFocus:le,onBlur:Ce,onCompositionStart:ve,onCompositionEnd:pe,className:te(E==null?void 0:E.textarea),style:U(U({},w==null?void 0:w.textarea),{},{resize:S==null?void 0:S.resize}),disabled:x,prefixCls:p,onResize:he,ref:H})})}),b7=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var n;const{prefixCls:r,bordered:o=!0,size:i,disabled:a,status:l,allowClear:s,classNames:c,rootClassName:u,className:d,variant:v}=e,h=b7(e,["prefixCls","bordered","size","disabled","status","allowClear","classNames","rootClassName","className","variant"]),{getPrefixCls:g,direction:p}=f.exports.useContext(ot),b=So(i),m=f.exports.useContext(rl),y=a!=null?a:m,{status:S,hasFeedback:x,feedbackIcon:$}=f.exports.useContext(Jr),E=dm(S,l),w=f.exports.useRef(null);f.exports.useImperativeHandle(t,()=>{var _;return{resizableTextArea:(_=w.current)===null||_===void 0?void 0:_.resizableTextArea,focus:O=>{var M,L;t7((L=(M=w.current)===null||M===void 0?void 0:M.resizableTextArea)===null||L===void 0?void 0:L.textArea,O)},blur:()=>{var O;return(O=w.current)===null||O===void 0?void 0:O.blur()}}});const R=g("input",r);let P;typeof s=="object"&&(s==null?void 0:s.clearIcon)?P=s:s&&(P={clearIcon:C(Nd,{})});const N=no(R),[I,z,F]=Im(R,N),[T,D]=vm(v,o);return I(C(y7,{...Object.assign({},h,{disabled:y,allowClear:P,className:te(F,N,d,u),classNames:Object.assign(Object.assign({},c),{textarea:te({[`${R}-sm`]:b==="small",[`${R}-lg`]:b==="large"},z,c==null?void 0:c.textarea),variant:te({[`${R}-${T}`]:D},ed(R,E)),affixWrapper:te(`${R}-textarea-affix-wrapper`,{[`${R}-affix-wrapper-rtl`]:p==="rtl",[`${R}-affix-wrapper-sm`]:b==="small",[`${R}-affix-wrapper-lg`]:b==="large",[`${R}-textarea-show-count`]:e.showCount||((n=e.count)===null||n===void 0?void 0:n.show)},z)}),prefixCls:R,suffix:x&&C("span",{className:`${R}-textarea-suffix`,children:$}),ref:w})}))}),C7=S7,Js=Tm;Js.Group=Xk;Js.Search=u7;Js.TextArea=C7;Js.Password=l7;const C$=Js;function x$(){var e=document.documentElement.clientWidth,t=window.innerHeight||document.documentElement.clientHeight;return{width:e,height:t}}function x7(e){var t=e.getBoundingClientRect(),n=document.documentElement;return{left:t.left+(window.pageXOffset||n.scrollLeft)-(n.clientLeft||document.body.clientLeft||0),top:t.top+(window.pageYOffset||n.scrollTop)-(n.clientTop||document.body.clientTop||0)}}var Pg=["crossOrigin","decoding","draggable","loading","referrerPolicy","sizes","srcSet","useMap","alt"],ec=f.exports.createContext(null),a1=0;function w7(e,t){var n=f.exports.useState(function(){return a1+=1,String(a1)}),r=G(n,1),o=r[0],i=f.exports.useContext(ec),a={data:t,canPreview:e};return f.exports.useEffect(function(){if(i)return i.register(o,a)},[]),f.exports.useEffect(function(){i&&i.register(o,a)},[e,t]),o}function $7(e){return new Promise(function(t){var n=document.createElement("img");n.onerror=function(){return t(!1)},n.onload=function(){return t(!0)},n.src=e})}function w$(e){var t=e.src,n=e.isCustomPlaceholder,r=e.fallback,o=f.exports.useState(n?"loading":"normal"),i=G(o,2),a=i[0],l=i[1],s=f.exports.useRef(!1),c=a==="error";f.exports.useEffect(function(){var h=!0;return $7(t).then(function(g){!g&&h&&l("error")}),function(){h=!1}},[t]),f.exports.useEffect(function(){n&&!s.current?l("loading"):c&&l("normal")},[t]);var u=function(){l("normal")},d=function(g){s.current=!1,a==="loading"&&g!==null&&g!==void 0&&g.complete&&(g.naturalWidth||g.naturalHeight)&&(s.current=!0,u())},v=c&&r?{src:r}:{onLoad:u,src:t};return[d,v,a]}function $a(e,t,n,r){var o=zu.unstable_batchedUpdates?function(a){zu.unstable_batchedUpdates(n,a)}:n;return e!=null&&e.addEventListener&&e.addEventListener(t,o,r),{remove:function(){e!=null&&e.removeEventListener&&e.removeEventListener(t,o,r)}}}var kc={x:0,y:0,rotate:0,scale:1,flipX:!1,flipY:!1};function E7(e,t,n,r){var o=f.exports.useRef(null),i=f.exports.useRef([]),a=f.exports.useState(kc),l=G(a,2),s=l[0],c=l[1],u=function(g){c(kc),r&&!Vs(kc,s)&&r({transform:kc,action:g})},d=function(g,p){o.current===null&&(i.current=[],o.current=St(function(){c(function(b){var m=b;return i.current.forEach(function(y){m=U(U({},m),y)}),o.current=null,r==null||r({transform:m,action:p}),m})})),i.current.push(U(U({},s),g))},v=function(g,p,b,m,y){var S=e.current,x=S.width,$=S.height,E=S.offsetWidth,w=S.offsetHeight,R=S.offsetLeft,P=S.offsetTop,N=g,I=s.scale*g;I>n?(I=n,N=n/s.scale):Ir){if(t>0)return V({},e,i);if(t<0&&or)return V({},e,t<0?i:-i);return{}}function $$(e,t,n,r){var o=x$(),i=o.width,a=o.height,l=null;return e<=i&&t<=a?l={x:0,y:0}:(e>i||t>a)&&(l=U(U({},l1("x",n,e,i)),l1("y",r,t,a))),l}var Ea=1,M7=1;function O7(e,t,n,r,o,i,a){var l=o.rotate,s=o.scale,c=o.x,u=o.y,d=f.exports.useState(!1),v=G(d,2),h=v[0],g=v[1],p=f.exports.useRef({diffX:0,diffY:0,transformX:0,transformY:0}),b=function($){!t||$.button!==0||($.preventDefault(),$.stopPropagation(),p.current={diffX:$.pageX-c,diffY:$.pageY-u,transformX:c,transformY:u},g(!0))},m=function($){n&&h&&i({x:$.pageX-p.current.diffX,y:$.pageY-p.current.diffY},"move")},y=function(){if(n&&h){g(!1);var $=p.current,E=$.transformX,w=$.transformY,R=c!==E&&u!==w;if(!R)return;var P=e.current.offsetWidth*s,N=e.current.offsetHeight*s,I=e.current.getBoundingClientRect(),z=I.left,F=I.top,T=l%180!==0,D=$$(T?N:P,T?P:N,z,F);D&&i(U({},D),"dragRebound")}},S=function($){if(!(!n||$.deltaY==0)){var E=Math.abs($.deltaY/100),w=Math.min(E,M7),R=Ea+w*r;$.deltaY>0&&(R=Ea/R),a(R,"wheel",$.clientX,$.clientY)}};return f.exports.useEffect(function(){var x,$,E,w;if(t){E=$a(window,"mouseup",y,!1),w=$a(window,"mousemove",m,!1);try{window.top!==window.self&&(x=$a(window.top,"mouseup",y,!1),$=$a(window.top,"mousemove",m,!1))}catch{}}return function(){var R,P,N,I;(R=E)===null||R===void 0||R.remove(),(P=w)===null||P===void 0||P.remove(),(N=x)===null||N===void 0||N.remove(),(I=$)===null||I===void 0||I.remove()}},[n,h,c,u,l,t]),{isMoving:h,onMouseDown:b,onMouseMove:m,onMouseUp:y,onWheel:S}}function id(e,t){var n=e.x-t.x,r=e.y-t.y;return Math.hypot(n,r)}function R7(e,t,n,r){var o=id(e,n),i=id(t,r);if(o===0&&i===0)return[e.x,e.y];var a=o/(o+i),l=e.x+a*(t.x-e.x),s=e.y+a*(t.y-e.y);return[l,s]}function I7(e,t,n,r,o,i,a){var l=o.rotate,s=o.scale,c=o.x,u=o.y,d=f.exports.useState(!1),v=G(d,2),h=v[0],g=v[1],p=f.exports.useRef({point1:{x:0,y:0},point2:{x:0,y:0},eventType:"none"}),b=function($){p.current=U(U({},p.current),$)},m=function($){if(!!t){$.stopPropagation(),g(!0);var E=$.touches,w=E===void 0?[]:E;w.length>1?b({point1:{x:w[0].clientX,y:w[0].clientY},point2:{x:w[1].clientX,y:w[1].clientY},eventType:"touchZoom"}):b({point1:{x:w[0].clientX-c,y:w[0].clientY-u},eventType:"move"})}},y=function($){var E=$.touches,w=E===void 0?[]:E,R=p.current,P=R.point1,N=R.point2,I=R.eventType;if(w.length>1&&I==="touchZoom"){var z={x:w[0].clientX,y:w[0].clientY},F={x:w[1].clientX,y:w[1].clientY},T=R7(P,N,z,F),D=G(T,2),_=D[0],O=D[1],M=id(z,F)/id(P,N);a(M,"touchZoom",_,O,!0),b({point1:z,point2:F,eventType:"touchZoom"})}else I==="move"&&(i({x:w[0].clientX-P.x,y:w[0].clientY-P.y},"move"),b({eventType:"move"}))},S=function(){if(!!n){if(h&&g(!1),b({eventType:"none"}),r>s)return i({x:0,y:0,scale:r},"touchZoom");var $=e.current.offsetWidth*s,E=e.current.offsetHeight*s,w=e.current.getBoundingClientRect(),R=w.left,P=w.top,N=l%180!==0,I=$$(N?E:$,N?$:E,R,P);I&&i(U({},I),"dragRebound")}};return f.exports.useEffect(function(){var x;return n&&t&&(x=$a(window,"touchmove",function($){return $.preventDefault()},{passive:!1})),function(){var $;($=x)===null||$===void 0||$.remove()}},[n,t]),{isTouching:h,onTouchStart:m,onTouchMove:y,onTouchEnd:S}}var P7=function(t){var n=t.visible,r=t.maskTransitionName,o=t.getContainer,i=t.prefixCls,a=t.rootClassName,l=t.icons,s=t.countRender,c=t.showSwitch,u=t.showProgress,d=t.current,v=t.transform,h=t.count,g=t.scale,p=t.minScale,b=t.maxScale,m=t.closeIcon,y=t.onSwitchLeft,S=t.onSwitchRight,x=t.onClose,$=t.onZoomIn,E=t.onZoomOut,w=t.onRotateRight,R=t.onRotateLeft,P=t.onFlipX,N=t.onFlipY,I=t.toolbarRender,z=t.zIndex,F=f.exports.useContext(ec),T=l.rotateLeft,D=l.rotateRight,_=l.zoomIn,O=l.zoomOut,M=l.close,L=l.left,A=l.right,B=l.flipX,k=l.flipY,j="".concat(i,"-operations-operation");f.exports.useEffect(function(){var K=function(ee){ee.keyCode===ue.ESC&&x()};return n&&window.addEventListener("keydown",K),function(){window.removeEventListener("keydown",K)}},[n]);var H=[{icon:k,onClick:N,type:"flipY"},{icon:B,onClick:P,type:"flipX"},{icon:T,onClick:R,type:"rotateLeft"},{icon:D,onClick:w,type:"rotateRight"},{icon:O,onClick:E,type:"zoomOut",disabled:g<=p},{icon:_,onClick:$,type:"zoomIn",disabled:g===b}],W=H.map(function(K){var q,ee=K.icon,Z=K.onClick,Q=K.type,ne=K.disabled;return C("div",{className:te(j,(q={},V(q,"".concat(i,"-operations-operation-").concat(Q),!0),V(q,"".concat(i,"-operations-operation-disabled"),!!ne),q)),onClick:Z,children:ee},Q)}),Y=C("div",{className:"".concat(i,"-operations"),children:W});return C(to,{visible:n,motionName:r,children:function(K){var q=K.className,ee=K.style;return C(nf,{open:!0,getContainer:o!=null?o:document.body,children:ie("div",{className:te("".concat(i,"-operations-wrapper"),q,a),style:U(U({},ee),{},{zIndex:z}),children:[m===null?null:C("button",{className:"".concat(i,"-close"),onClick:x,children:m||M}),c&&ie(Tt,{children:[C("div",{className:te("".concat(i,"-switch-left"),V({},"".concat(i,"-switch-left-disabled"),d===0)),onClick:y,children:L}),C("div",{className:te("".concat(i,"-switch-right"),V({},"".concat(i,"-switch-right-disabled"),d===h-1)),onClick:S,children:A})]}),ie("div",{className:"".concat(i,"-footer"),children:[u&&C("div",{className:"".concat(i,"-progress"),children:s?s(d+1,h):"".concat(d+1," / ").concat(h)}),I?I(Y,U({icons:{flipYIcon:W[0],flipXIcon:W[1],rotateLeftIcon:W[2],rotateRightIcon:W[3],zoomOutIcon:W[4],zoomInIcon:W[5]},actions:{onFlipY:N,onFlipX:P,onRotateLeft:R,onRotateRight:w,onZoomOut:E,onZoomIn:$},transform:v},F?{current:d,total:h}:{})):Y]})]})})}})},T7=["fallback","src","imgRef"],N7=["prefixCls","src","alt","fallback","movable","onClose","visible","icons","rootClassName","closeIcon","getContainer","current","count","countRender","scaleStep","minScale","maxScale","transitionName","maskTransitionName","imageRender","imgCommonProps","toolbarRender","onTransform","onChange"],_7=function(t){var n=t.fallback,r=t.src,o=t.imgRef,i=Je(t,T7),a=w$({src:r,fallback:n}),l=G(a,2),s=l[0],c=l[1];return C("img",{ref:function(d){o.current=d,s(d)},...i,...c})},E$=function(t){var n=t.prefixCls,r=t.src,o=t.alt,i=t.fallback,a=t.movable,l=a===void 0?!0:a,s=t.onClose,c=t.visible,u=t.icons,d=u===void 0?{}:u,v=t.rootClassName,h=t.closeIcon,g=t.getContainer,p=t.current,b=p===void 0?0:p,m=t.count,y=m===void 0?1:m,S=t.countRender,x=t.scaleStep,$=x===void 0?.5:x,E=t.minScale,w=E===void 0?1:E,R=t.maxScale,P=R===void 0?50:R,N=t.transitionName,I=N===void 0?"zoom":N,z=t.maskTransitionName,F=z===void 0?"fade":z,T=t.imageRender,D=t.imgCommonProps,_=t.toolbarRender,O=t.onTransform,M=t.onChange,L=Je(t,N7),A=f.exports.useRef(),B=f.exports.useContext(ec),k=B&&y>1,j=B&&y>=1,H=f.exports.useState(!0),W=G(H,2),Y=W[0],K=W[1],q=E7(A,w,P,O),ee=q.transform,Z=q.resetTransform,Q=q.updateTransform,ne=q.dispatchZoomChange,ae=O7(A,l,c,$,ee,Q,ne),J=ae.isMoving,re=ae.onMouseDown,fe=ae.onWheel,ve=I7(A,l,c,w,ee,Q,ne),pe=ve.isTouching,oe=ve.onTouchStart,se=ve.onTouchMove,le=ve.onTouchEnd,Ce=ee.rotate,ce=ee.scale,de=te(V({},"".concat(n,"-moving"),J));f.exports.useEffect(function(){Y||K(!0)},[Y]);var xe=function(){Z("close")},he=function(){ne(Ea+$,"zoomIn")},ke=function(){ne(Ea/(Ea+$),"zoomOut")},we=function(){Q({rotate:Ce+90},"rotateRight")},ge=function(){Q({rotate:Ce-90},"rotateLeft")},Pe=function(){Q({flipX:!ee.flipX},"flipX")},Se=function(){Q({flipY:!ee.flipY},"flipY")},st=function(qe){qe==null||qe.preventDefault(),qe==null||qe.stopPropagation(),b>0&&(K(!1),Z("prev"),M==null||M(b-1,b))},nt=function(qe){qe==null||qe.preventDefault(),qe==null||qe.stopPropagation(),b({position:e||"absolute",inset:0}),B7=e=>{const{iconCls:t,motionDurationSlow:n,paddingXXS:r,marginXXS:o,prefixCls:i,colorTextLightSolid:a}=e;return{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",color:a,background:new Mt("#000").setAlpha(.5).toRgbString(),cursor:"pointer",opacity:0,transition:`opacity ${n}`,[`.${i}-mask-info`]:Object.assign(Object.assign({},ei),{padding:`0 ${X(r)}`,[t]:{marginInlineEnd:o,svg:{verticalAlign:"baseline"}}})}},j7=e=>{const{previewCls:t,modalMaskBg:n,paddingSM:r,marginXL:o,margin:i,paddingLG:a,previewOperationColorDisabled:l,previewOperationHoverColor:s,motionDurationSlow:c,iconCls:u,colorTextLightSolid:d}=e,v=new Mt(n).setAlpha(.1),h=v.clone().setAlpha(.2);return{[`${t}-footer`]:{position:"fixed",bottom:o,left:{_skip_check_:!0,value:0},width:"100%",display:"flex",flexDirection:"column",alignItems:"center",color:e.previewOperationColor},[`${t}-progress`]:{marginBottom:i},[`${t}-close`]:{position:"fixed",top:o,right:{_skip_check_:!0,value:o},display:"flex",color:d,backgroundColor:v.toRgbString(),borderRadius:"50%",padding:r,outline:0,border:0,cursor:"pointer",transition:`all ${c}`,"&:hover":{backgroundColor:h.toRgbString()},[`& > ${u}`]:{fontSize:e.previewOperationSize}},[`${t}-operations`]:{display:"flex",alignItems:"center",padding:`0 ${X(a)}`,backgroundColor:v.toRgbString(),borderRadius:100,"&-operation":{marginInlineStart:r,padding:r,cursor:"pointer",transition:`all ${c}`,userSelect:"none",[`&:not(${t}-operations-operation-disabled):hover > ${u}`]:{color:s},"&-disabled":{color:l,cursor:"not-allowed"},"&:first-of-type":{marginInlineStart:0},[`& > ${u}`]:{fontSize:e.previewOperationSize}}}}},H7=e=>{const{modalMaskBg:t,iconCls:n,previewOperationColorDisabled:r,previewCls:o,zIndexPopup:i,motionDurationSlow:a}=e,l=new Mt(t).setAlpha(.1),s=l.clone().setAlpha(.2);return{[`${o}-switch-left, ${o}-switch-right`]:{position:"fixed",insetBlockStart:"50%",zIndex:e.calc(i).add(1).equal({unit:!1}),display:"flex",alignItems:"center",justifyContent:"center",width:e.imagePreviewSwitchSize,height:e.imagePreviewSwitchSize,marginTop:e.calc(e.imagePreviewSwitchSize).mul(-1).div(2).equal(),color:e.previewOperationColor,background:l.toRgbString(),borderRadius:"50%",transform:"translateY(-50%)",cursor:"pointer",transition:`all ${a}`,userSelect:"none","&:hover":{background:s.toRgbString()},["&-disabled"]:{"&, &:hover":{color:r,background:"transparent",cursor:"not-allowed",[`> ${n}`]:{cursor:"not-allowed"}}},[`> ${n}`]:{fontSize:e.previewOperationSize}},[`${o}-switch-left`]:{insetInlineStart:e.marginSM},[`${o}-switch-right`]:{insetInlineEnd:e.marginSM}}},W7=e=>{const{motionEaseOut:t,previewCls:n,motionDurationSlow:r,componentCls:o}=e;return[{[`${o}-preview-root`]:{[n]:{height:"100%",textAlign:"center",pointerEvents:"none"},[`${n}-body`]:Object.assign(Object.assign({},Tg()),{overflow:"hidden"}),[`${n}-img`]:{maxWidth:"100%",maxHeight:"70%",verticalAlign:"middle",transform:"scale3d(1, 1, 1)",cursor:"grab",transition:`transform ${r} ${t} 0s`,userSelect:"none","&-wrapper":Object.assign(Object.assign({},Tg()),{transition:`transform ${r} ${t} 0s`,display:"flex",justifyContent:"center",alignItems:"center","& > *":{pointerEvents:"auto"},"&::before":{display:"inline-block",width:1,height:"50%",marginInlineEnd:-1,content:'""'}})},[`${n}-moving`]:{[`${n}-preview-img`]:{cursor:"grabbing","&-wrapper":{transitionDuration:"0s"}}}}},{[`${o}-preview-root`]:{[`${n}-wrap`]:{zIndex:e.zIndexPopup}}},{[`${o}-preview-operations-wrapper`]:{position:"fixed",zIndex:e.calc(e.zIndexPopup).add(1).equal({unit:!1})},"&":[j7(e),H7(e)]}]},V7=e=>{const{componentCls:t}=e;return{[t]:{position:"relative",display:"inline-block",[`${t}-img`]:{width:"100%",height:"auto",verticalAlign:"middle"},[`${t}-img-placeholder`]:{backgroundColor:e.colorBgContainerDisabled,backgroundImage:"url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTQuNSAyLjVoLTEzQS41LjUgMCAwIDAgMSAzdjEwYS41LjUgMCAwIDAgLjUuNWgxM2EuNS41IDAgMCAwIC41LS41VjNhLjUuNSAwIDAgMC0uNS0uNXpNNS4yODEgNC43NWExIDEgMCAwIDEgMCAyIDEgMSAwIDAgMSAwLTJ6bTguMDMgNi44M2EuMTI3LjEyNyAwIDAgMS0uMDgxLjAzSDIuNzY5YS4xMjUuMTI1IDAgMCAxLS4wOTYtLjIwN2wyLjY2MS0zLjE1NmEuMTI2LjEyNiAwIDAgMSAuMTc3LS4wMTZsLjAxNi4wMTZMNy4wOCAxMC4wOWwyLjQ3LTIuOTNhLjEyNi4xMjYgMCAwIDEgLjE3Ny0uMDE2bC4wMTUuMDE2IDMuNTg4IDQuMjQ0YS4xMjcuMTI3IDAgMCAxLS4wMi4xNzV6IiBmaWxsPSIjOEM4QzhDIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L3N2Zz4=')",backgroundRepeat:"no-repeat",backgroundPosition:"center center",backgroundSize:"30%"},[`${t}-mask`]:Object.assign({},B7(e)),[`${t}-mask:hover`]:{opacity:1},[`${t}-placeholder`]:Object.assign({},Tg())}}},U7=e=>{const{previewCls:t}=e;return{[`${t}-root`]:of(e,"zoom"),["&"]:zw(e,!0)}},Y7=e=>({zIndexPopup:e.zIndexPopupBase+80,previewOperationColor:new Mt(e.colorTextLightSolid).setAlpha(.65).toRgbString(),previewOperationHoverColor:new Mt(e.colorTextLightSolid).setAlpha(.85).toRgbString(),previewOperationColorDisabled:new Mt(e.colorTextLightSolid).setAlpha(.25).toRgbString(),previewOperationSize:e.fontSizeIcon*1.5}),M$=vn("Image",e=>{const t=`${e.componentCls}-preview`,n=$t(e,{previewCls:t,modalMaskBg:new Mt("#000").setAlpha(.45).toRgbString(),imagePreviewSwitchSize:e.controlHeightLG});return[V7(n),W7(n),Fw($t(n,{componentCls:t})),U7(n)]},Y7);var G7=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var{previewPrefixCls:t,preview:n}=e,r=G7(e,["previewPrefixCls","preview"]);const{getPrefixCls:o}=f.exports.useContext(ot),i=o("image",t),a=`${i}-preview`,l=o(),s=no(i),[c,u,d]=M$(i,s),[v]=Qd("ImagePreview",typeof n=="object"?n.zIndex:void 0),h=f.exports.useMemo(()=>{var g;if(n===!1)return n;const p=typeof n=="object"?n:{},b=te(u,d,s,(g=p.rootClassName)!==null&&g!==void 0?g:"");return Object.assign(Object.assign({},p),{transitionName:ni(l,"zoom",p.transitionName),maskTransitionName:ni(l,"fade",p.maskTransitionName),rootClassName:b,zIndex:v})},[n]);return c(C(hf.PreviewGroup,{...Object.assign({preview:h,previewPrefixCls:a,icons:O$},r)}))},q7=K7;var s1=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{var t;const{prefixCls:n,preview:r,className:o,rootClassName:i,style:a}=e,l=s1(e,["prefixCls","preview","className","rootClassName","style"]),{getPrefixCls:s,locale:c=Jo,getPopupContainer:u,image:d}=f.exports.useContext(ot),v=s("image",n),h=s(),g=c.Image||Jo.Image,p=no(v),[b,m,y]=M$(v,p),S=te(i,m,y,p),x=te(o,m,d==null?void 0:d.className),[$]=Qd("ImagePreview",typeof r=="object"?r.zIndex:void 0),E=f.exports.useMemo(()=>{var R;if(r===!1)return r;const P=typeof r=="object"?r:{},{getContainer:N,closeIcon:I}=P,z=s1(P,["getContainer","closeIcon"]);return Object.assign(Object.assign({mask:ie("div",{className:`${v}-mask-info`,children:[C(sx,{}),g==null?void 0:g.preview]}),icons:O$},z),{getContainer:N!=null?N:u,transitionName:ni(h,"zoom",P.transitionName),maskTransitionName:ni(h,"fade",P.maskTransitionName),zIndex:$,closeIcon:I!=null?I:(R=d==null?void 0:d.preview)===null||R===void 0?void 0:R.closeIcon})},[r,g,(t=d==null?void 0:d.preview)===null||t===void 0?void 0:t.closeIcon]),w=Object.assign(Object.assign({},d==null?void 0:d.style),a);return b(C(hf,{...Object.assign({prefixCls:v,preview:E,rootClassName:S,className:x,style:w},l)}))};R$.PreviewGroup=q7;const cu=R$,X7=new Ct("antSpinMove",{to:{opacity:1}}),Q7=new Ct("antRotate",{to:{transform:"rotate(405deg)"}}),Z7=e=>{const{componentCls:t,calc:n}=e;return{[`${t}`]:Object.assign(Object.assign({},Qt(e)),{position:"absolute",display:"none",color:e.colorPrimary,fontSize:0,textAlign:"center",verticalAlign:"middle",opacity:0,transition:`transform ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`,"&-spinning":{position:"static",display:"inline-block",opacity:1},[`${t}-text`]:{fontSize:e.fontSize,paddingTop:n(n(e.dotSize).sub(e.fontSize)).div(2).add(2).equal()},"&-fullscreen":{position:"fixed",width:"100vw",height:"100vh",backgroundColor:e.colorBgMask,zIndex:e.zIndexPopupBase,inset:0,display:"flex",alignItems:"center",flexDirection:"column",justifyContent:"center",opacity:0,visibility:"hidden",transition:`all ${e.motionDurationMid}`,"&-show":{opacity:1,visibility:"visible"},[`${t}-dot ${t}-dot-item`]:{backgroundColor:e.colorWhite},[`${t}-text`]:{color:e.colorTextLightSolid}},"&-nested-loading":{position:"relative",[`> div > ${t}`]:{position:"absolute",top:0,insetInlineStart:0,zIndex:4,display:"block",width:"100%",height:"100%",maxHeight:e.contentHeight,[`${t}-dot`]:{position:"absolute",top:"50%",insetInlineStart:"50%",margin:n(e.dotSize).mul(-1).div(2).equal()},[`${t}-text`]:{position:"absolute",top:"50%",width:"100%",textShadow:`0 1px 2px ${e.colorBgContainer}`},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSize).div(2).mul(-1).sub(10).equal()},"&-sm":{[`${t}-dot`]:{margin:n(e.dotSizeSM).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeSM).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeSM).div(2).mul(-1).sub(10).equal()}},"&-lg":{[`${t}-dot`]:{margin:n(e.dotSizeLG).mul(-1).div(2).equal()},[`${t}-text`]:{paddingTop:n(n(e.dotSizeLG).sub(e.fontSize)).div(2).add(2).equal()},[`&${t}-show-text ${t}-dot`]:{marginTop:n(e.dotSizeLG).div(2).mul(-1).sub(10).equal()}}},[`${t}-container`]:{position:"relative",transition:`opacity ${e.motionDurationSlow}`,"&::after":{position:"absolute",top:0,insetInlineEnd:0,bottom:0,insetInlineStart:0,zIndex:10,width:"100%",height:"100%",background:e.colorBgContainer,opacity:0,transition:`all ${e.motionDurationSlow}`,content:'""',pointerEvents:"none"}},[`${t}-blur`]:{clear:"both",opacity:.5,userSelect:"none",pointerEvents:"none",["&::after"]:{opacity:.4,pointerEvents:"auto"}}},["&-tip"]:{color:e.spinDotDefault},[`${t}-dot`]:{position:"relative",display:"inline-block",fontSize:e.dotSize,width:"1em",height:"1em","&-item":{position:"absolute",display:"block",width:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),height:n(e.dotSize).sub(n(e.marginXXS).div(2)).div(2).equal(),backgroundColor:e.colorPrimary,borderRadius:"100%",transform:"scale(0.75)",transformOrigin:"50% 50%",opacity:.3,animationName:X7,animationDuration:"1s",animationIterationCount:"infinite",animationTimingFunction:"linear",animationDirection:"alternate","&:nth-child(1)":{top:0,insetInlineStart:0,animationDelay:"0s"},"&:nth-child(2)":{top:0,insetInlineEnd:0,animationDelay:"0.4s"},"&:nth-child(3)":{insetInlineEnd:0,bottom:0,animationDelay:"0.8s"},"&:nth-child(4)":{bottom:0,insetInlineStart:0,animationDelay:"1.2s"}},"&-spin":{transform:"rotate(45deg)",animationName:Q7,animationDuration:"1.2s",animationIterationCount:"infinite",animationTimingFunction:"linear"}},[`&-sm ${t}-dot`]:{fontSize:e.dotSizeSM,i:{width:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal(),height:n(n(e.dotSizeSM).sub(n(e.marginXXS).div(2))).div(2).equal()}},[`&-lg ${t}-dot`]:{fontSize:e.dotSizeLG,i:{width:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal(),height:n(n(e.dotSizeLG).sub(e.marginXXS)).div(2).equal()}},[`&${t}-show-text ${t}-text`]:{display:"block"}})}},J7=e=>{const{controlHeightLG:t,controlHeight:n}=e;return{contentHeight:400,dotSize:t/2,dotSizeSM:t*.35,dotSizeLG:n}},eB=vn("Spin",e=>{const t=$t(e,{spinDotDefault:e.colorTextDescription});return[Z7(t)]},J7);var tB=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{prefixCls:t,spinning:n=!0,delay:r=0,className:o,rootClassName:i,size:a="default",tip:l,wrapperClassName:s,style:c,children:u,fullscreen:d=!1}=e,v=tB(e,["prefixCls","spinning","delay","className","rootClassName","size","tip","wrapperClassName","style","children","fullscreen"]),{getPrefixCls:h}=f.exports.useContext(ot),g=h("spin",t),[p,b,m]=eB(g),[y,S]=f.exports.useState(()=>n&&!rB(n,r));f.exports.useEffect(()=>{if(n){const z=Hk(r,()=>{S(!0)});return z(),()=>{var F;(F=z==null?void 0:z.cancel)===null||F===void 0||F.call(z)}}S(!1)},[r,n]);const x=f.exports.useMemo(()=>typeof u<"u"&&!d,[u,d]),{direction:$,spin:E}=f.exports.useContext(ot),w=te(g,E==null?void 0:E.className,{[`${g}-sm`]:a==="small",[`${g}-lg`]:a==="large",[`${g}-spinning`]:y,[`${g}-show-text`]:!!l,[`${g}-fullscreen`]:d,[`${g}-fullscreen-show`]:d&&y,[`${g}-rtl`]:$==="rtl"},o,i,b,m),R=te(`${g}-container`,{[`${g}-blur`]:y}),P=lr(v,["indicator"]),N=Object.assign(Object.assign({},E==null?void 0:E.style),c),I=ie("div",{...Object.assign({},P,{style:N,className:w,"aria-live":"polite","aria-busy":y}),children:[nB(g,e),l&&(x||d)?C("div",{className:`${g}-text`,children:l}):null]});return p(x?ie("div",{...Object.assign({},P,{className:te(`${g}-nested-loading`,s,b,m)}),children:[y&&C("div",{children:I},"loading"),C("div",{className:R,children:u},"container")]}):I)};I$.setDefaultIndicator=e=>{uu=e};const oB=I$;var iB={percent:0,prefixCls:"rc-progress",strokeColor:"#2db7f5",strokeLinecap:"round",strokeWidth:1,trailColor:"#D9D9D9",trailWidth:1,gapPosition:"bottom"},aB=function(){var t=f.exports.useRef([]),n=f.exports.useRef(null);return f.exports.useEffect(function(){var r=Date.now(),o=!1;t.current.forEach(function(i){if(!!i){o=!0;var a=i.style;a.transitionDuration=".3s, .3s, .3s, .06s",n.current&&r-n.current<100&&(a.transitionDuration="0s, 0s")}}),o&&(n.current=Date.now())}),t.current},c1=0,lB=Rn();function sB(){var e;return lB?(e=c1,c1+=1):e="TEST_OR_SSR",e}const cB=function(e){var t=f.exports.useState(),n=G(t,2),r=n[0],o=n[1];return f.exports.useEffect(function(){o("rc_progress_".concat(sB()))},[]),e||r};var u1=function(t){var n=t.bg,r=t.children;return C("div",{style:{width:"100%",height:"100%",background:n},children:r})};function d1(e,t){return Object.keys(e).map(function(n){var r=parseFloat(n),o="".concat(Math.floor(r*t),"%");return"".concat(e[n]," ").concat(o)})}var uB=f.exports.forwardRef(function(e,t){var n=e.prefixCls,r=e.color,o=e.gradientId,i=e.radius,a=e.style,l=e.ptg,s=e.strokeLinecap,c=e.strokeWidth,u=e.size,d=e.gapDegree,v=r&&Qe(r)==="object",h=v?"#FFF":void 0,g=u/2,p=C("circle",{className:"".concat(n,"-circle-path"),r:i,cx:g,cy:g,stroke:h,strokeLinecap:s,strokeWidth:c,opacity:l===0?0:1,style:a,ref:t});if(!v)return p;var b="".concat(o,"-conic"),m=d?"".concat(180+d/2,"deg"):"0deg",y=d1(r,(360-d)/360),S=d1(r,1),x="conic-gradient(from ".concat(m,", ").concat(y.join(", "),")"),$="linear-gradient(to ".concat(d?"bottom":"top",", ").concat(S.join(", "),")");return ie(Tt,{children:[C("mask",{id:b,children:p}),C("foreignObject",{x:0,y:0,width:u,height:u,mask:"url(#".concat(b,")"),children:C(u1,{bg:$,children:C(u1,{bg:x})})})]})}),Dl=100,Iv=function(t,n,r,o,i,a,l,s,c,u){var d=arguments.length>10&&arguments[10]!==void 0?arguments[10]:0,v=r/100*360*((360-a)/360),h=a===0?0:{bottom:0,top:180,left:90,right:-90}[l],g=(100-o)/100*n;c==="round"&&o!==100&&(g+=u/2,g>=n&&(g=n-.01));var p=Dl/2;return{stroke:typeof s=="string"?s:void 0,strokeDasharray:"".concat(n,"px ").concat(t),strokeDashoffset:g+d,transform:"rotate(".concat(i+v+h,"deg)"),transformOrigin:"".concat(p,"px ").concat(p,"px"),transition:"stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s",fillOpacity:0}},dB=["id","prefixCls","steps","strokeWidth","trailWidth","gapDegree","gapPosition","trailColor","strokeLinecap","style","className","strokeColor","percent"];function f1(e){var t=e!=null?e:[];return Array.isArray(t)?t:[t]}var fB=function(t){var n=U(U({},iB),t),r=n.id,o=n.prefixCls,i=n.steps,a=n.strokeWidth,l=n.trailWidth,s=n.gapDegree,c=s===void 0?0:s,u=n.gapPosition,d=n.trailColor,v=n.strokeLinecap,h=n.style,g=n.className,p=n.strokeColor,b=n.percent,m=Je(n,dB),y=Dl/2,S=cB(r),x="".concat(S,"-gradient"),$=y-a/2,E=Math.PI*2*$,w=c>0?90+c/2:-90,R=E*((360-c)/360),P=Qe(i)==="object"?i:{count:i,space:2},N=P.count,I=P.space,z=f1(b),F=f1(p),T=F.find(function(B){return B&&Qe(B)==="object"}),D=T&&Qe(T)==="object",_=D?"butt":v,O=Iv(E,R,0,100,w,c,u,d,_,a),M=aB(),L=function(){var k=0;return z.map(function(j,H){var W=F[H]||F[F.length-1],Y=Iv(E,R,k,j,w,c,u,W,_,a);return k+=j,C(uB,{color:W,ptg:j,radius:$,prefixCls:o,gradientId:x,style:Y,strokeLinecap:_,strokeWidth:a,gapDegree:c,ref:function(q){M[H]=q},size:Dl},H)}).reverse()},A=function(){var k=Math.round(N*(z[0]/100)),j=100/N,H=0;return new Array(N).fill(null).map(function(W,Y){var K=Y<=k-1?F[0]:d,q=K&&Qe(K)==="object"?"url(#".concat(x,")"):void 0,ee=Iv(E,R,H,j,w,c,u,K,"butt",a,I);return H+=(R-ee.strokeDashoffset+I)*100/R,C("circle",{className:"".concat(o,"-circle-path"),r:$,cx:y,cy:y,stroke:q,strokeWidth:a,opacity:1,style:ee,ref:function(Q){M[Y]=Q}},Y)})};return ie("svg",{className:te("".concat(o,"-circle"),g),viewBox:"0 0 ".concat(Dl," ").concat(Dl),style:h,id:r,role:"presentation",...m,children:[!N&&C("circle",{className:"".concat(o,"-circle-trail"),r:$,cx:y,cy:y,stroke:d,strokeLinecap:_,strokeWidth:l||a,style:O}),N?A():L()]})};function Go(e){return!e||e<0?0:e>100?100:e}function ad(e){let{success:t,successPercent:n}=e,r=n;return t&&"progress"in t&&(r=t.progress),t&&"percent"in t&&(r=t.percent),r}const vB=e=>{let{percent:t,success:n,successPercent:r}=e;const o=Go(ad({success:n,successPercent:r}));return[o,Go(Go(t)-o)]},pB=e=>{let{success:t={},strokeColor:n}=e;const{strokeColor:r}=t;return[r||Na.green,n||null]},mf=(e,t,n)=>{var r,o,i,a;let l=-1,s=-1;if(t==="step"){const c=n.steps,u=n.strokeWidth;typeof e=="string"||typeof e>"u"?(l=e==="small"?2:14,s=u!=null?u:8):typeof e=="number"?[l,s]=[e,e]:[l=14,s=8]=e,l*=c}else if(t==="line"){const c=n==null?void 0:n.strokeWidth;typeof e=="string"||typeof e>"u"?s=c||(e==="small"?6:8):typeof e=="number"?[l,s]=[e,e]:[l=-1,s=8]=e}else(t==="circle"||t==="dashboard")&&(typeof e=="string"||typeof e>"u"?[l,s]=e==="small"?[60,60]:[120,120]:typeof e=="number"?[l,s]=[e,e]:(l=(o=(r=e[0])!==null&&r!==void 0?r:e[1])!==null&&o!==void 0?o:120,s=(a=(i=e[0])!==null&&i!==void 0?i:e[1])!==null&&a!==void 0?a:120));return[l,s]},gB=3,hB=e=>gB/e*100,mB=e=>{const{prefixCls:t,trailColor:n=null,strokeLinecap:r="round",gapPosition:o,gapDegree:i,width:a=120,type:l,children:s,success:c,size:u=a}=e,[d,v]=mf(u,"circle");let{strokeWidth:h}=e;h===void 0&&(h=Math.max(hB(d),6));const g={width:d,height:v,fontSize:d*.15+6},p=f.exports.useMemo(()=>{if(i||i===0)return i;if(l==="dashboard")return 75},[i,l]),b=o||l==="dashboard"&&"bottom"||void 0,m=Object.prototype.toString.call(e.strokeColor)==="[object Object]",y=pB({success:c,strokeColor:e.strokeColor}),S=te(`${t}-inner`,{[`${t}-circle-gradient`]:m}),x=C(fB,{percent:vB(e),strokeWidth:h,trailWidth:h,strokeColor:y,strokeLinecap:r,trailColor:n,prefixCls:t,gapDegree:p,gapPosition:b});return C("div",{className:S,style:g,children:d<=20?C(p2,{title:s,children:C("span",{children:x})}):ie(Tt,{children:[x,s]})})},yB=mB,ld="--progress-line-stroke-color",P$="--progress-percent",v1=e=>{const t=e?"100%":"-100%";return new Ct(`antProgress${e?"RTL":"LTR"}Active`,{"0%":{transform:`translateX(${t}) scaleX(0)`,opacity:.1},"20%":{transform:`translateX(${t}) scaleX(0)`,opacity:.5},to:{transform:"translateX(0) scaleX(1)",opacity:0}})},bB=e=>{const{componentCls:t,iconCls:n}=e;return{[t]:Object.assign(Object.assign({},Qt(e)),{display:"inline-block","&-rtl":{direction:"rtl"},"&-line":{position:"relative",width:"100%",fontSize:e.fontSize},[`${t}-outer`]:{display:"inline-block",width:"100%"},[`&${t}-show-info`]:{[`${t}-outer`]:{marginInlineEnd:`calc(-2em - ${X(e.marginXS)})`,paddingInlineEnd:`calc(2em + ${X(e.paddingXS)})`}},[`${t}-inner`]:{position:"relative",display:"inline-block",width:"100%",overflow:"hidden",verticalAlign:"middle",backgroundColor:e.remainingColor,borderRadius:e.lineBorderRadius},[`${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.defaultColor}},[`${t}-success-bg, ${t}-bg`]:{position:"relative",background:e.defaultColor,borderRadius:e.lineBorderRadius,transition:`all ${e.motionDurationSlow} ${e.motionEaseInOutCirc}`},[`${t}-bg`]:{overflow:"hidden","&::after":{content:'""',background:{_multi_value_:!0,value:["inherit",`var(${ld})`]},height:"100%",width:`calc(1 / var(${P$}) * 100%)`,display:"block"}},[`${t}-success-bg`]:{position:"absolute",insetBlockStart:0,insetInlineStart:0,backgroundColor:e.colorSuccess},[`${t}-text`]:{display:"inline-block",width:"2em",marginInlineStart:e.marginXS,color:e.colorText,lineHeight:1,whiteSpace:"nowrap",textAlign:"start",verticalAlign:"middle",wordBreak:"normal",[n]:{fontSize:e.fontSize}},[`&${t}-status-active`]:{[`${t}-bg::before`]:{position:"absolute",inset:0,backgroundColor:e.colorBgContainer,borderRadius:e.lineBorderRadius,opacity:0,animationName:v1(),animationDuration:e.progressActiveMotionDuration,animationTimingFunction:e.motionEaseOutQuint,animationIterationCount:"infinite",content:'""'}},[`&${t}-rtl${t}-status-active`]:{[`${t}-bg::before`]:{animationName:v1(!0)}},[`&${t}-status-exception`]:{[`${t}-bg`]:{backgroundColor:e.colorError},[`${t}-text`]:{color:e.colorError}},[`&${t}-status-exception ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorError}},[`&${t}-status-success`]:{[`${t}-bg`]:{backgroundColor:e.colorSuccess},[`${t}-text`]:{color:e.colorSuccess}},[`&${t}-status-success ${t}-inner:not(${t}-circle-gradient)`]:{[`${t}-circle-path`]:{stroke:e.colorSuccess}}})}},SB=e=>{const{componentCls:t,iconCls:n}=e;return{[t]:{[`${t}-circle-trail`]:{stroke:e.remainingColor},[`&${t}-circle ${t}-inner`]:{position:"relative",lineHeight:1,backgroundColor:"transparent"},[`&${t}-circle ${t}-text`]:{position:"absolute",insetBlockStart:"50%",insetInlineStart:0,width:"100%",margin:0,padding:0,color:e.circleTextColor,fontSize:e.circleTextFontSize,lineHeight:1,whiteSpace:"normal",textAlign:"center",transform:"translateY(-50%)",[n]:{fontSize:e.circleIconFontSize}},[`${t}-circle&-status-exception`]:{[`${t}-text`]:{color:e.colorError}},[`${t}-circle&-status-success`]:{[`${t}-text`]:{color:e.colorSuccess}}},[`${t}-inline-circle`]:{lineHeight:1,[`${t}-inner`]:{verticalAlign:"bottom"}}}},CB=e=>{const{componentCls:t}=e;return{[t]:{[`${t}-steps`]:{display:"inline-block","&-outer":{display:"flex",flexDirection:"row",alignItems:"center"},"&-item":{flexShrink:0,minWidth:e.progressStepMinWidth,marginInlineEnd:e.progressStepMarginInlineEnd,backgroundColor:e.remainingColor,transition:`all ${e.motionDurationSlow}`,"&-active":{backgroundColor:e.defaultColor}}}}}},xB=e=>{const{componentCls:t,iconCls:n}=e;return{[t]:{[`${t}-small&-line, ${t}-small&-line ${t}-text ${n}`]:{fontSize:e.fontSizeSM}}}},wB=e=>({circleTextColor:e.colorText,defaultColor:e.colorInfo,remainingColor:e.colorFillSecondary,lineBorderRadius:100,circleTextFontSize:"1em",circleIconFontSize:`${e.fontSize/e.fontSizeSM}em`}),$B=vn("Progress",e=>{const t=e.calc(e.marginXXS).div(2).equal(),n=$t(e,{progressStepMarginInlineEnd:t,progressStepMinWidth:t,progressActiveMotionDuration:"2.4s"});return[bB(n),SB(n),CB(n),xB(n)]},wB);var EB=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{let t=[];return Object.keys(e).forEach(n=>{const r=parseFloat(n.replace(/%/g,""));isNaN(r)||t.push({key:r,value:e[n]})}),t=t.sort((n,r)=>n.key-r.key),t.map(n=>{let{key:r,value:o}=n;return`${o} ${r}%`}).join(", ")},OB=(e,t)=>{const{from:n=Na.blue,to:r=Na.blue,direction:o=t==="rtl"?"to left":"to right"}=e,i=EB(e,["from","to","direction"]);if(Object.keys(i).length!==0){const l=MB(i),s=`linear-gradient(${o}, ${l})`;return{background:s,[ld]:s}}const a=`linear-gradient(${o}, ${n}, ${r})`;return{background:a,[ld]:a}},RB=e=>{const{prefixCls:t,direction:n,percent:r,size:o,strokeWidth:i,strokeColor:a,strokeLinecap:l="round",children:s,trailColor:c=null,success:u}=e,d=a&&typeof a!="string"?OB(a,n):{[ld]:a,background:a},v=l==="square"||l==="butt"?0:void 0,h=o!=null?o:[-1,i||(o==="small"?6:8)],[g,p]=mf(h,"line",{strokeWidth:i}),b={backgroundColor:c||void 0,borderRadius:v},m=Object.assign(Object.assign({width:`${Go(r)}%`,height:p,borderRadius:v},d),{[P$]:Go(r)/100}),y=ad(e),S={width:`${Go(y)}%`,height:p,borderRadius:v,backgroundColor:u==null?void 0:u.strokeColor},x={width:g<0?"100%":g,height:p};return ie(Tt,{children:[C("div",{className:`${t}-outer`,style:x,children:ie("div",{className:`${t}-inner`,style:b,children:[C("div",{className:`${t}-bg`,style:m}),y!==void 0?C("div",{className:`${t}-success-bg`,style:S}):null]})}),s]})},IB=RB,PB=e=>{const{size:t,steps:n,percent:r=0,strokeWidth:o=8,strokeColor:i,trailColor:a=null,prefixCls:l,children:s}=e,c=Math.round(n*(r/100)),u=t==="small"?2:14,d=t!=null?t:[u,o],[v,h]=mf(d,"step",{steps:n,strokeWidth:o}),g=v/n,p=new Array(n);for(let b=0;b{const{prefixCls:n,className:r,rootClassName:o,steps:i,strokeColor:a,percent:l=0,size:s="default",showInfo:c=!0,type:u="line",status:d,format:v,style:h}=e,g=NB(e,["prefixCls","className","rootClassName","steps","strokeColor","percent","size","showInfo","type","status","format","style"]),p=f.exports.useMemo(()=>{var F,T;const D=ad(e);return parseInt(D!==void 0?(F=D!=null?D:0)===null||F===void 0?void 0:F.toString():(T=l!=null?l:0)===null||T===void 0?void 0:T.toString(),10)},[l,e.success,e.successPercent]),b=f.exports.useMemo(()=>!_B.includes(d)&&p>=100?"success":d||"normal",[d,p]),{getPrefixCls:m,direction:y,progress:S}=f.exports.useContext(ot),x=m("progress",n),[$,E,w]=$B(x),R=f.exports.useMemo(()=>{if(!c)return null;const F=ad(e);let T;const D=v||(O=>`${O}%`),_=u==="line";return v||b!=="exception"&&b!=="success"?T=D(Go(l),Go(F)):b==="exception"?T=_?C(Nd,{}):C(eo,{}):b==="success"&&(T=_?C(NI,{}):C(lx,{})),C("span",{className:`${x}-text`,title:typeof T=="string"?T:void 0,children:T})},[c,l,p,b,u,x,v]),P=Array.isArray(a)?a[0]:a,N=typeof a=="string"||Array.isArray(a)?a:void 0;let I;u==="line"?I=i?C(TB,{...Object.assign({},e,{strokeColor:N,prefixCls:x,steps:i}),children:R}):C(IB,{...Object.assign({},e,{strokeColor:P,prefixCls:x,direction:y}),children:R}):(u==="circle"||u==="dashboard")&&(I=C(yB,{...Object.assign({},e,{strokeColor:P,prefixCls:x,progressStatus:b}),children:R}));const z=te(x,`${x}-status-${b}`,`${x}-${u==="dashboard"&&"circle"||i&&"steps"||u}`,{[`${x}-inline-circle`]:u==="circle"&&mf(s,"circle")[0]<=20,[`${x}-show-info`]:c,[`${x}-${s}`]:typeof s=="string",[`${x}-rtl`]:y==="rtl"},S==null?void 0:S.className,r,o,E,w);return $(C("div",{...Object.assign({ref:t,style:Object.assign(Object.assign({},S==null?void 0:S.style),h),className:z,role:"progressbar","aria-valuenow":p},lr(g,["trailColor","strokeWidth","width","gapDegree","gapPosition","strokeLinecap","success","successPercent"])),children:I}))}),DB=AB,LB=e=>{const{paddingXXS:t,lineWidth:n,tagPaddingHorizontal:r,componentCls:o,calc:i}=e,a=i(r).sub(n).equal(),l=i(t).sub(n).equal();return{[o]:Object.assign(Object.assign({},Qt(e)),{display:"inline-block",height:"auto",marginInlineEnd:e.marginXS,paddingInline:a,fontSize:e.tagFontSize,lineHeight:e.tagLineHeight,whiteSpace:"nowrap",background:e.defaultBg,border:`${X(e.lineWidth)} ${e.lineType} ${e.colorBorder}`,borderRadius:e.borderRadiusSM,opacity:1,transition:`all ${e.motionDurationMid}`,textAlign:"start",position:"relative",[`&${o}-rtl`]:{direction:"rtl"},"&, a, a:hover":{color:e.defaultColor},[`${o}-close-icon`]:{marginInlineStart:l,fontSize:e.tagIconSize,color:e.colorTextDescription,cursor:"pointer",transition:`all ${e.motionDurationMid}`,"&:hover":{color:e.colorTextHeading}},[`&${o}-has-color`]:{borderColor:"transparent",[`&, a, a:hover, ${e.iconCls}-close, ${e.iconCls}-close:hover`]:{color:e.colorTextLightSolid}},["&-checkable"]:{backgroundColor:"transparent",borderColor:"transparent",cursor:"pointer",[`&:not(${o}-checkable-checked):hover`]:{color:e.colorPrimary,backgroundColor:e.colorFillSecondary},"&:active, &-checked":{color:e.colorTextLightSolid},"&-checked":{backgroundColor:e.colorPrimary,"&:hover":{backgroundColor:e.colorPrimaryHover}},"&:active":{backgroundColor:e.colorPrimaryActive}},["&-hidden"]:{display:"none"},[`> ${e.iconCls} + span, > span + ${e.iconCls}`]:{marginInlineStart:a}}),[`${o}-borderless`]:{borderColor:"transparent",background:e.tagBorderlessBg}}},Nm=e=>{const{lineWidth:t,fontSizeIcon:n,calc:r}=e,o=e.fontSizeSM;return $t(e,{tagFontSize:o,tagLineHeight:X(r(e.lineHeightSM).mul(o).equal()),tagIconSize:r(n).sub(r(t).mul(2)).equal(),tagPaddingHorizontal:8,tagBorderlessBg:e.defaultBg})},_m=e=>({defaultBg:new Mt(e.colorFillQuaternary).onBackground(e.colorBgContainer).toHexString(),defaultColor:e.colorText}),T$=vn("Tag",e=>{const t=Nm(e);return LB(t)},_m);var zB=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{prefixCls:n,style:r,className:o,checked:i,onChange:a,onClick:l}=e,s=zB(e,["prefixCls","style","className","checked","onChange","onClick"]),{getPrefixCls:c,tag:u}=f.exports.useContext(ot),d=m=>{a==null||a(!i),l==null||l(m)},v=c("tag",n),[h,g,p]=T$(v),b=te(v,`${v}-checkable`,{[`${v}-checkable-checked`]:i},u==null?void 0:u.className,o,g,p);return h(C("span",{...Object.assign({},s,{ref:t,style:Object.assign(Object.assign({},r),u==null?void 0:u.style),className:b,onClick:d})}))}),kB=FB,BB=e=>ow(e,(t,n)=>{let{textColor:r,lightBorderColor:o,lightColor:i,darkColor:a}=n;return{[`${e.componentCls}${e.componentCls}-${t}`]:{color:r,background:i,borderColor:o,"&-inverse":{color:e.colorTextLightSolid,background:a,borderColor:a},[`&${e.componentCls}-borderless`]:{borderColor:"transparent"}}}}),jB=Kh(["Tag","preset"],e=>{const t=Nm(e);return BB(t)},_m);function HB(e){return typeof e!="string"?e:e.charAt(0).toUpperCase()+e.slice(1)}const Bc=(e,t,n)=>{const r=HB(n);return{[`${e.componentCls}${e.componentCls}-${t}`]:{color:e[`color${n}`],background:e[`color${r}Bg`],borderColor:e[`color${r}Border`],[`&${e.componentCls}-borderless`]:{borderColor:"transparent"}}}},WB=Kh(["Tag","status"],e=>{const t=Nm(e);return[Bc(t,"success","Success"),Bc(t,"processing","Info"),Bc(t,"error","Error"),Bc(t,"warning","Warning")]},_m);var VB=globalThis&&globalThis.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols=="function")for(var o=0,r=Object.getOwnPropertySymbols(e);o{const{prefixCls:n,className:r,rootClassName:o,style:i,children:a,icon:l,color:s,onClose:c,closeIcon:u,closable:d,bordered:v=!0}=e,h=VB(e,["prefixCls","className","rootClassName","style","children","icon","color","onClose","closeIcon","closable","bordered"]),{getPrefixCls:g,direction:p,tag:b}=f.exports.useContext(ot),[m,y]=f.exports.useState(!0);f.exports.useEffect(()=>{"visible"in h&&y(h.visible)},[h.visible]);const S=d2(s),x=ID(s),$=S||x,E=Object.assign(Object.assign({backgroundColor:s&&!$?s:void 0},b==null?void 0:b.style),i),w=g("tag",n),[R,P,N]=T$(w),I=te(w,b==null?void 0:b.className,{[`${w}-${s}`]:$,[`${w}-has-color`]:s&&!$,[`${w}-hidden`]:!m,[`${w}-rtl`]:p==="rtl",[`${w}-borderless`]:!v},r,o,P,N),z=M=>{M.stopPropagation(),c==null||c(M),!M.defaultPrevented&&y(!1)},[,F]=m6(d,u!=null?u:b==null?void 0:b.closeIcon,M=>M===null?C(eo,{className:`${w}-close-icon`,onClick:z}):C("span",{className:`${w}-close-icon`,onClick:z,children:M}),null,!1),T=typeof h.onClick=="function"||a&&a.type==="a",D=l||null,_=D?ie(Tt,{children:[D,a&&C("span",{children:a})]}):a,O=ie("span",{...Object.assign({},h,{ref:t,className:I,style:E}),children:[_,F,S&&C(jB,{prefixCls:w},"preset"),x&&C(WB,{prefixCls:w},"status")]});return R(T?C(Qh,{component:"Tag",children:O}):O)},N$=f.exports.forwardRef(UB);N$.CheckableTag=kB;const oa=N$;function YB(e){return window.go.main.App.ExportWeChatAllData(e)}function GB(){return window.go.main.App.GetAppVersion()}function KB(){return window.go.main.App.GetWeChatAllInfo()}function qB(e){return window.go.main.App.GetWeChatRoomUserList(e)}function XB(e){return window.go.main.App.GetWechatMessageDate(e)}function QB(e,t,n,r,o){return window.go.main.App.GetWechatMessageListByKeyWord(e,t,n,r,o)}function p1(e,t,n,r){return window.go.main.App.GetWechatMessageListByTime(e,t,n,r)}function ZB(e,t){return window.go.main.App.GetWechatSessionList(e,t)}function JB(e,t){return window.go.main.App.OpenFileOrExplorer(e,t)}function e9(){return window.go.main.App.WeChatInit()}const t9="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";let Am=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e));for(;e--;)t+=t9[n[e]&63];return t};function Ts(e){window.runtime.LogInfo(e)}function n9(e,t,n){return window.runtime.EventsOnMultiple(e,t,n)}function _$(e,t){return n9(e,t,-1)}function A$(e,...t){return window.runtime.EventsOff(e,...t)}function r9(){window.runtime.WindowToggleMaximise()}function o9(){window.runtime.WindowMinimise()}function i9(e){window.runtime.BrowserOpenURL(e)}function a9(){window.runtime.Quit()}function l9(e,t){let n;return function(...r){n&&clearTimeout(n),n=setTimeout(()=>{e.apply(this,r)},t)}}function s9(e){return C("div",{className:"wechat-SearchBar",children:C(ai,{theme:{components:{Input:{activeBorderColor:"#E3E4E5",activeShadow:"#E3E4E5",hoverBorderColor:"#E3E4E5"}}},children:C(C$,{className:"wechat-SearchBar-Input",placeholder:"\u641C\u7D22",prefix:C(_d,{}),allowClear:!0,onChange:t=>e.onChange(t.target.value)})})})}function c9(e){return ie("div",{className:`${e.className} wechat-UserItem`,onClick:e.onClick,tabIndex:"0",children:[C(Yo,{id:"wechat-UserItem-content-Avatar-id",className:"wechat-UserItem-content-Avatar",src:e.Avatar,size:{xs:45,sm:45,md:45,lg:45,xl:45,xxl:45},shape:"square",alt:"\u65E0\u6CD5\u52A0\u8F7D\u5934\u50CF"}),ie("div",{className:"wechat-UserItem-content",children:[C("div",{className:"wechat-UserItem-content-text wechat-UserItem-content-name",children:e.name}),C("div",{className:"wechat-UserItem-content-text wechat-UserItem-content-msg",children:e.msg})]}),C("div",{className:"wechat-UserItem-date",children:e.date})]})}function u9(e){const t=new Date(e*1e3),n=t.getFullYear(),r=t.getMonth()+1,o=t.getDate();return t.getHours(),t.getMinutes(),t.getSeconds(),`${n-2e3}/${r}/${o}`}function d9(e){const[t,n]=f.exports.useState(null),[r,o]=f.exports.useState(0),[i,a]=f.exports.useState(!0),[l,s]=f.exports.useState([]),[c,u]=f.exports.useState(""),d=(g,p)=>{n(g),e.onClickItem&&e.onClickItem(p)};f.exports.useEffect(()=>{i&&e.selfName!==""&&ZB(r,20).then(g=>{var p=JSON.parse(g);if(p.Total>0){let b=[];p.Rows.forEach(m=>{m.UserName.startsWith("gh_")||b.push(m)}),s(m=>[...m,...b]),o(m=>m+1)}else a(!1)})},[r,i,e.selfName]);const v=f.exports.useCallback(l9(g=>{console.log(g),u(g)},400),[]),h=l.filter(g=>g.NickName.includes(c));return ie("div",{className:"wechat-UserList",onClick:e.onClick,children:[C(s9,{onChange:v}),C("div",{className:"wechat-UserList-Items",children:h.map((g,p)=>C(c9,{className:t===p?"selectedItem":"",onClick:()=>{d(p,g)},name:g.NickName,msg:g.Content,date:u9(g.Time),Avatar:g.UserInfo.SmallHeadImgUrl},Am()))})]})}const ia={INIT:"normal",START:"active",END:"success",ERROR:"exception"};function f9({info:e,appVersion:t}){const[n,r]=f.exports.useState({});return f.exports.useEffect(()=>{r({PID:e.PID,path:e.FilePath,version:e.Version!==""?e.Version+" "+(e.Is64Bits?"64bits":"32bits"):"\u7248\u672C\u83B7\u53D6\u5931\u8D25",userName:e.AcountName,result:e.DBkey&&e.DBkey.length>0?"success":"failed"})},[e]),ie(Tt,{children:[C("div",{children:"\u5F53\u524D\u767B\u9646\u7684\u5FAE\u4FE1\u4FE1\u606F"}),ie("div",{className:"WechatInfoTable",children:[ie("div",{className:"WechatInfoTable-column",children:[C("div",{children:"wechatDataBackup \u7248\u672C:"}),C(oa,{className:"WechatInfoTable-column-tag",color:"success",children:t})]}),ie("div",{className:"WechatInfoTable-column",children:[C("div",{children:"\u8FDB\u7A0BPID:"}),C(oa,{className:"WechatInfoTable-column-tag",color:n.PID===0?"red":"success",children:n.PID===0?"\u5F53\u524D\u6CA1\u6709\u6253\u5F00\u5FAE\u4FE1":n.PID})]}),ie("div",{className:"WechatInfoTable-column",children:[C("div",{children:"\u6587\u4EF6\u5B58\u50A8\u8DEF\u5F84:"}),C(oa,{className:"WechatInfoTable-column-tag",color:"success",children:n.path})]}),ie("div",{className:"WechatInfoTable-column",children:[C("div",{children:"\u5FAE\u4FE1\u8F6F\u4EF6\u7248\u672C:"}),C(oa,{className:"WechatInfoTable-column-tag",color:"success",children:n.version})]}),ie("div",{className:"WechatInfoTable-column",children:[C("div",{children:"\u5FAE\u4FE1ID:"}),C(oa,{className:"WechatInfoTable-column-tag",color:n.userName===""?"red":"success",children:n.userName===""?"\u5F53\u524D\u6CA1\u6709\u767B\u9646\u5FAE\u4FE1":n.userName})]}),ie("div",{className:"WechatInfoTable-column",children:[C("div",{children:"\u89E3\u5BC6\u7ED3\u679C:"}),C(oa,{className:"WechatInfoTable-column-tag",color:n.result==="success"?"green":"red",children:n.result==="success"?"\u89E3\u5BC6\u6210\u529F":"\u89E3\u5BC6\u5931\u8D25"})]})]})]})}function v9(e){const[t,n]=f.exports.useState(!1),[r,o]=f.exports.useState({}),[i,a]=f.exports.useState(-1),[l,s]=f.exports.useState(ia.INIT),[c,u]=f.exports.useState(""),d=p=>{console.log(p);const b=JSON.parse(p);b.status==="error"?(s(ia.ERROR),a(100)):(s(b.progress!==100?ia.START:ia.END),a(b.progress))},v=()=>{console.log("showModal"),n(!0),KB().then(p=>{console.log(p),o(JSON.parse(p))}),GB().then(p=>{u(p)}),_$("exportData",d)},h=p=>{n(!1),a(-1),s(ia.INIT),A$("exportData"),e.onModalExit&&e.onModalExit()},g=p=>{YB(p),a(0),s(ia.START)};return ie("div",{className:"Setting-Modal-Parent",children:[C("div",{onClick:v,children:e.children}),ie(js,{className:"Setting-Modal",overlayClassName:"Setting-Modal-Overlay",isOpen:t,onRequestClose:h,children:[C("div",{className:"Setting-Modal-button",title:"\u5173\u95ED",onClick:()=>h(),children:C(eo,{className:"Setting-Modal-button-icon"})}),C(f9,{info:r,appVersion:c}),r.DBkey&&r.DBkey.length>0&&C(p9,{onClickExport:g,children:C(Xu,{className:"Setting-Modal-export-button",type:"primary",children:"\u5BFC\u51FA\u6B64\u8D26\u53F7\u6570\u636E"})}),i>-1&&C(DB,{percent:i,status:l})]})]})}const p9=e=>{const[t,n]=f.exports.useState(!1),r=i=>{n(!1)},o=i=>{n(!1),e.onClickExport&&e.onClickExport(i)};return ie("div",{className:"Setting-Modal-confirm-Parent",children:[C("div",{onClick:()=>n(!0),children:e.children}),ie(js,{className:"Setting-Modal-confirm",overlayClassName:"Setting-Modal-confirm-Overlay",isOpen:t,onRequestClose:r,children:[C("div",{className:"Setting-Modal-confirm-title",children:"\u9009\u62E9\u5BFC\u51FA\u65B9\u5F0F"}),ie("div",{className:"Setting-Modal-confirm-buttons",children:[C(Xu,{className:"Setting-Modal-export-button",type:"primary",onClick:()=>o(!0),children:"\u5168\u91CF\u5BFC\u51FA\uFF08\u901F\u5EA6\u6162\uFF09"}),C(Xu,{className:"Setting-Modal-export-button",type:"primary",onClick:()=>o(!1),children:"\u589E\u91CF\u5BFC\u51FA\uFF08\u901F\u5EA6\u5FEB\uFF09"})]})]})]})};function g9(e){const[t,n]=f.exports.useState("chat"),r=o=>{o!=="avatar"&&n(o),e.onClickItem&&e.onClickItem(o)};return ie("div",{className:"wechat-menu",children:[C(Yo,{id:"wechat-menu-item-Avatar",className:"wechat-menu-item wechat-menu-item-Avatar",src:e.Avatar,size:"large",shape:"square",alt:"\u65E0\u6CD5\u52A0\u8F7D\u5934\u50CF",onClick:()=>r("avatar")}),C(Yo,{icon:C($4,{}),title:"\u67E5\u770B\u804A\u5929",className:`wechat-menu-item wechat-menu-item-icon ${t==="chat"?"wechat-menu-selectedColor":""}`,size:"default",onClick:()=>r("chat")}),C(v9,{onModalExit:()=>e.onClickItem("exit"),children:C(Yo,{icon:C(c4,{}),title:"\u8BBE\u7F6E",className:`wechat-menu-item wechat-menu-item-icon ${t==="setting"?"wechat-menu-selectedColor":""}`,size:"default"})})]})}var Ng=function(e,t){return Ng=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,r){n.__proto__=r}||function(n,r){for(var o in r)r.hasOwnProperty(o)&&(n[o]=r[o])},Ng(e,t)};function h9(e,t){Ng(e,t);function n(){this.constructor=e}e.prototype=t===null?Object.create(t):(n.prototype=t.prototype,new n)}var es=function(){return es=Object.assign||function(t){for(var n,r=1,o=arguments.length;re?h():t!==!0&&(o=setTimeout(r?g:h,r===void 0?e-d:e))}return c.cancel=s,c}var La={Pixel:"Pixel",Percent:"Percent"},g1={unit:La.Percent,value:.8};function h1(e){return typeof e=="number"?{unit:La.Percent,value:e*100}:typeof e=="string"?e.match(/^(\d*(\.\d+)?)px$/)?{unit:La.Pixel,value:parseFloat(e)}:e.match(/^(\d*(\.\d+)?)%$/)?{unit:La.Percent,value:parseFloat(e)}:(console.warn('scrollThreshold format is invalid. Valid formats: "120px", "50%"...'),g1):(console.warn("scrollThreshold should be string or number"),g1)}var D$=function(e){h9(t,e);function t(n){var r=e.call(this,n)||this;return r.lastScrollTop=0,r.actionTriggered=!1,r.startY=0,r.currentY=0,r.dragging=!1,r.maxPullDownDistance=0,r.getScrollableTarget=function(){return r.props.scrollableTarget instanceof HTMLElement?r.props.scrollableTarget:typeof r.props.scrollableTarget=="string"?document.getElementById(r.props.scrollableTarget):(r.props.scrollableTarget===null&&console.warn(`You are trying to pass scrollableTarget but it is null. This might
+ happen because the element may not have been added to DOM yet.
+ See https://github.com/ankeetmaini/react-infinite-scroll-component/issues/59 for more info.
+ `),null)},r.onStart=function(o){r.lastScrollTop||(r.dragging=!0,o instanceof MouseEvent?r.startY=o.pageY:o instanceof TouchEvent&&(r.startY=o.touches[0].pageY),r.currentY=r.startY,r._infScroll&&(r._infScroll.style.willChange="transform",r._infScroll.style.transition="transform 0.2s cubic-bezier(0,0,0.31,1)"))},r.onMove=function(o){!r.dragging||(o instanceof MouseEvent?r.currentY=o.pageY:o instanceof TouchEvent&&(r.currentY=o.touches[0].pageY),!(r.currentY=Number(r.props.pullDownToRefreshThreshold)&&r.setState({pullToRefreshThresholdBreached:!0}),!(r.currentY-r.startY>r.maxPullDownDistance*1.5)&&r._infScroll&&(r._infScroll.style.overflow="visible",r._infScroll.style.transform="translate3d(0px, "+(r.currentY-r.startY)+"px, 0px)")))},r.onEnd=function(){r.startY=0,r.currentY=0,r.dragging=!1,r.state.pullToRefreshThresholdBreached&&(r.props.refreshFunction&&r.props.refreshFunction(),r.setState({pullToRefreshThresholdBreached:!1})),requestAnimationFrame(function(){r._infScroll&&(r._infScroll.style.overflow="auto",r._infScroll.style.transform="none",r._infScroll.style.willChange="unset")})},r.onScrollListener=function(o){typeof r.props.onScroll=="function"&&setTimeout(function(){return r.props.onScroll&&r.props.onScroll(o)},0);var i=r.props.height||r._scrollableNode?o.target:document.documentElement.scrollTop?document.documentElement:document.body;if(!r.actionTriggered){var a=r.props.inverse?r.isElementAtTop(i,r.props.scrollThreshold):r.isElementAtBottom(i,r.props.scrollThreshold);a&&r.props.hasMore&&(r.actionTriggered=!0,r.setState({showLoader:!0}),r.props.next&&r.props.next()),r.lastScrollTop=i.scrollTop}},r.state={showLoader:!1,pullToRefreshThresholdBreached:!1,prevDataLength:n.dataLength},r.throttledOnScrollListener=m9(150,r.onScrollListener).bind(r),r.onStart=r.onStart.bind(r),r.onMove=r.onMove.bind(r),r.onEnd=r.onEnd.bind(r),r}return t.prototype.componentDidMount=function(){if(typeof this.props.dataLength>"u")throw new Error('mandatory prop "dataLength" is missing. The prop is needed when loading more content. Check README.md for usage');if(this._scrollableNode=this.getScrollableTarget(),this.el=this.props.height?this._infScroll:this._scrollableNode||window,this.el&&this.el.addEventListener("scroll",this.throttledOnScrollListener),typeof this.props.initialScrollY=="number"&&this.el&&this.el instanceof HTMLElement&&this.el.scrollHeight>this.props.initialScrollY&&this.el.scrollTo(0,this.props.initialScrollY),this.props.pullDownToRefresh&&this.el&&(this.el.addEventListener("touchstart",this.onStart),this.el.addEventListener("touchmove",this.onMove),this.el.addEventListener("touchend",this.onEnd),this.el.addEventListener("mousedown",this.onStart),this.el.addEventListener("mousemove",this.onMove),this.el.addEventListener("mouseup",this.onEnd),this.maxPullDownDistance=this._pullDown&&this._pullDown.firstChild&&this._pullDown.firstChild.getBoundingClientRect().height||0,this.forceUpdate(),typeof this.props.refreshFunction!="function"))throw new Error(`Mandatory prop "refreshFunction" missing.
+ Pull Down To Refresh functionality will not work
+ as expected. Check README.md for usage'`)},t.prototype.componentWillUnmount=function(){this.el&&(this.el.removeEventListener("scroll",this.throttledOnScrollListener),this.props.pullDownToRefresh&&(this.el.removeEventListener("touchstart",this.onStart),this.el.removeEventListener("touchmove",this.onMove),this.el.removeEventListener("touchend",this.onEnd),this.el.removeEventListener("mousedown",this.onStart),this.el.removeEventListener("mousemove",this.onMove),this.el.removeEventListener("mouseup",this.onEnd)))},t.prototype.componentDidUpdate=function(n){this.props.dataLength!==n.dataLength&&(this.actionTriggered=!1,this.setState({showLoader:!1}))},t.getDerivedStateFromProps=function(n,r){var o=n.dataLength!==r.prevDataLength;return o?es(es({},r),{prevDataLength:n.dataLength}):null},t.prototype.isElementAtTop=function(n,r){r===void 0&&(r=.8);var o=n===document.body||n===document.documentElement?window.screen.availHeight:n.clientHeight,i=h1(r);return i.unit===La.Pixel?n.scrollTop<=i.value+o-n.scrollHeight+1:n.scrollTop<=i.value/100+o-n.scrollHeight+1},t.prototype.isElementAtBottom=function(n,r){r===void 0&&(r=.8);var o=n===document.body||n===document.documentElement?window.screen.availHeight:n.clientHeight,i=h1(r);return i.unit===La.Pixel?n.scrollTop+o>=n.scrollHeight-i.value:n.scrollTop+o>=i.value/100*n.scrollHeight},t.prototype.render=function(){var n=this,r=es({height:this.props.height||"auto",overflow:"auto",WebkitOverflowScrolling:"touch"},this.props.style),o=this.props.hasChildren||!!(this.props.children&&this.props.children instanceof Array&&this.props.children.length),i=this.props.pullDownToRefresh&&this.props.height?{overflow:"auto"}:{};return C("div",{style:i,className:"infinite-scroll-component__outerdiv",children:ie("div",{className:"infinite-scroll-component "+(this.props.className||""),ref:function(a){return n._infScroll=a},style:r,children:[this.props.pullDownToRefresh&&C("div",{style:{position:"relative"},ref:function(a){return n._pullDown=a},children:C("div",{style:{position:"absolute",left:0,right:0,top:-1*this.maxPullDownDistance},children:this.state.pullToRefreshThresholdBreached?this.props.releaseToRefreshContent:this.props.pullDownToRefreshContent})}),this.props.children,!this.state.showLoader&&!o&&this.props.hasMore&&this.props.loader,this.state.showLoader&&this.props.hasMore&&this.props.loader,!this.props.hasMore&&this.props.endMessage]})})},t}(f.exports.Component);const y9=f.exports.forwardRef((e,t)=>{let n=!1,r=!1;e.message.position==="middle"?n=!0:r=e.message.position!=="right";const o=f.exports.useMemo(()=>e.renderMessageContent(e.message),[e.message]);return ie("div",{className:"MessageBubble",id:e.id,ref:t,children:[C("time",{className:"Time",dateTime:Lt(e.message.createdAt).format(),children:Lt(e.message.createdAt*1e3).format("YYYY\u5E74M\u6708D\u65E5 HH:mm")}),n?o:ie("div",{className:"MessageBubble-content"+(r?"-left":"-right"),children:[C("div",{className:"MessageBubble-content-Avatar",children:r&&C(Yo,{className:"MessageBubble-Avatar-left",src:e.message.user.avatar,size:{xs:40,sm:40,md:40,lg:40,xl:40,xxl:40},shape:"square",alt:"\u65E0\u6CD5\u52A0\u8F7D\u5934\u50CF"})}),ie("div",{className:"Bubble"+(r?"-left":"-right"),children:[C("div",{className:"MessageBubble-Name"+(r?"-left":"-right"),truncate:1,children:e.message.user.name}),o]}),C("div",{className:"MessageBubble-content-Avatar",children:!r&&C(Yo,{className:"MessageBubble-Avatar-right",src:e.message.user.avatar,size:{xs:40,sm:40,md:40,lg:40,xl:40,xxl:40},shape:"square",alt:"\u65E0\u6CD5\u52A0\u8F7D\u5934\u50CF"})})]})]})});function b9(e){const t=f.exports.useRef(),n=f.exports.useRef(0),r=f.exports.useRef(null),o=a=>{a.srcElement.scrollTop>0&&a.srcElement.scrollTop<1&&(a.srcElement.scrollTop=0),a.srcElement.scrollTop===0?(n.current=a.srcElement.scrollHeight,r.current=a.srcElement,e.atBottom&&e.atBottom()):(n.current=0,r.current=null)};function i(){e.next()}return f.exports.useEffect(()=>{n.current!==0&&r.current&&(r.current.scrollTop=-(r.current.scrollHeight-n.current),n.current=0,r.current=null)},[e.messages]),f.exports.useEffect(()=>{t.current&&t.current.scrollIntoView()},[e.messages]),C("div",{id:"scrollableDiv",children:C(D$,{scrollableTarget:"scrollableDiv",dataLength:e.messages.length,next:i,hasMore:e.hasMore,inverse:!0,onScroll:o,children:e.messages.map(a=>C(y9,{message:a,renderMessageContent:e.renderMessageContent,id:a.key,ref:a.key===e.scrollIntoId?t:null},a.key))})})}function S9(e){return C("div",{className:"ChatUi",children:C(b9,{messages:e.messages,next:e.fetchMoreData,hasMore:e.hasMore,renderMessageContent:e.renderMessageContent,atBottom:e.atBottom,scrollIntoId:e.scrollIntoId})})}function L$(e){const[t,n]=f.exports.useState(e);return{messages:t,prependMsgs:a=>{n(a.concat(t))},appendMsgs:a=>{n(t.concat(a))},setMsgs:a=>{n(a)}}}const C9="data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCABXAFcDASIAAhEBAxEB/8QAHQABAAICAgMAAAAAAAAAAAAAAAkKBQcCAwQGCP/EACkQAAEEAgIBBAIBBQAAAAAAAAQCAwUGAAEHCAkREhMUFSEiIyUxUWH/xAAZAQEBAQEBAQAAAAAAAAAAAAAAAQIDBAX/xAAjEQACAgAGAgMBAAAAAAAAAAAAAQIREiExQVFhInGBwfAD/9oADAMBAAIRAxEAPwC/BjGM+gecYxjAGMYwBjGMAYxjAGMYwBjGMAYxjAGMw1isUDUYCatVomI6v1uuRZ83PTswWxHxUPERgzhkjJSJxK2xxAghWXSCCHnENtNNqWtWta3la/lXvv3N8inMc5wP41RZGg8WU434LRzpI7TXy5UdfzDMzcpYHBZZykVaRJEkXaxExIZN7sIDDUiUJHkbNrkZmUlGrtt6JZt/uypX9t6Is04yrfe+sXmz6lxLfMVO7Ouc9D15KJe1UqItljur/wBILSjZPRFQ5GrceDPQeh2FtEuQZbFj+JxxQAAriUEomA8cffqq97uIirBsIGr8s0V4KJ5Towr7jjEeaaghUXYoNJK1mLrNiSGYoH7CnXwDgpGKIfIWGgsqRnbwtOL1Se/rkNUrTTXW3vgkQxjGbIMYxgDGMYAzGzEzEV6KkJ2flY2DhIkR+QlZiYOFjIqMAFbU8SbISBrrAgQg7SVOvkkvNsstpUtxaU63vXkmmhxoZcjIljAR4Az5pxxj7QwgYYrS3ySiiXlIZHGHZQt5991aG2mkKcWpKU73qrX2F57578xfOxvVTqkuTqHUukzQTnJXKJQzzUfaRxSG2XbPYXRk6VuI+wiS3xzx81Jtk23QzFlsCQHG9C0/MpKKWVt6R3bKlfSWr4/bImX8ifT2693+FYPjOi8zlcYCt2mKm50XQ+j6peYHbwunR53QDf5UlcMN80xXBhjW4c+V003LsKTsGUh/WQLX0i8SPEHFnEc3ZwaMFbJgaNYLeYcl7jdZ55Qo9i5FtbQenDkQwT5DC5aV20mHr4jwUTGsNsNiB5juwPZvhnxTdUaLTJGxzPItxrtQ1UuJafY7DuQu/IEnFD+38rOGPLfJiqjFlksalJJodwKDjlgwMII89qMj1RmdFeivLPejljffzv796Yhpg0Sb4p4smhHwQZyNGedIgCSYJf10Q3GUI3oRdYgttPKuelLmJtwsEl8ix4k6l4xT/o0rttqK74+KvXdJ1LLN1FXXLfXPv8rMgRwEtHiSUeULIRcmGOcEaM62SGcAawh8Yod5va2nxSR3EOtOoUpt1paVp3tKtb3WX8TrMGx5Su/zPFem08Tsmcltgojdt/gkDp5hQmBRG/W39TcW2rUsivfHtX9n0nbW9o+RWbi8kHkP5Bnr+vx79F4WWsPNFkKdoV9tFdA176kl5lseQqNU9WVMBFAxezFXC3v6DjaRFMPuCltmDlyEJIJ44Ohtb6LcLIrpJMfY+YLz+PnuXLoG09ocyabG3serQTxW9FuVaqLJMEjCn2QSJsp46wFxsW9Jpio83jmq0g23La+F9kqk73WS6tO/WWXJIdjGM6kGMYwBjGMAjq8sk9O13x8dkza88QOYVUY6GLfF2pLzcNO2aEiJtOlp/khsiLMKFf3r0/oPu69devrrWPhRpFEq3j54jnaixHuTF9OvFivkuO0hB8jZxLzY6+kWSX+3vdBRERGw4jS9pb+sKk1lvWj1uuyRcscY1LmjjS9cT3sJchUOQqxL1SwCtPLHI3Hy4jgrj4ZLe9OCnCKWgsApvfvGMYYfR/JvWVb6Va+8PhLu1o47M4mL7EdWrXYTLFAzcW1NCRzzim2Q0GB2mLirA1QLM6I2Emdrk9CGBSJAyyYhRDOlSe+cnhmpu8OFxbq8Lu7fvQ0s41vdrvYnJ518a/XnsT2a4/7N8nMTk7L0iIGjTaIacoujWx2FI+1VypiNJUvbDEM+4U4bEhbai7FtbCZkZ9tspB2AH8nHXx/uRAdKqXHT1ym32SYKQu1HC1O06r3EBLfsp5I8OwS9sKLDaLRZLGwpELUTBUgSe0tsypUREryT5Tu6vecPfAHTLrBceMJO7tuQdg5CJlzJqXi4eRHWNIrYsTlbrFa47HaZcI+eymSRsk20lK4dcdJaa2qWHxyeOOidG6GuSlXo+89gLqCM9yPyQsRSkhLcUstynU1Zq3zA63HEv7aOk97EkLocK1OS4gDSIqCg4pYpeCyu5SaeeipXvXrnfM1S8nmskr0960utz7fjeE+JYflOwc3RfH9ZC5ZtMFHVqfvrEc2mwSULFLeWGE6Vve0t/p7TZZI7bRciwNHDSD5Q8XGtC7RxjOtJaKt/nkyMYxgDGMYAxjGAM4ONodQpt1CHG169FIcTpaFa/wBKSrW071/zet6znjAOgcUYRG2xR2Bm97920Dstso2r/Hu2ltKU736fr13r1zvxjAGMYwBjGMAYxjAGMYwBjGMAYxjAGMYwBjGMAYxjAP/Z",x9="/assets/emoji.b5d5ea11.png",w9="/assets/001_\u5FAE\u7B11.1ec7a344.png",$9="/assets/002_\u6487\u5634.0279218b.png",E9="/assets/003_\u8272.e92bb91a.png",M9="/assets/004_\u53D1\u5446.8d849292.png",O9="/assets/005_\u5F97\u610F.72060784.png",R9="/assets/006_\u6D41\u6CEA.f52e5f23.png",I9="/assets/007_\u5BB3\u7F9E.414541cc.png",P9="/assets/008_\u95ED\u5634.4b6c78a6.png",T9="/assets/009_\u7761.75e64219.png",N9="/assets/010_\u5927\u54ED.2cd2fee3.png",_9="/assets/011_\u5C34\u5C2C.70cfea1c.png",A9="/assets/012_\u53D1\u6012.b88ce021.png",D9="/assets/013_\u8C03\u76AE.f3363541.png",L9="/assets/014_\u5472\u7259.3cd1fb7c.png",z9="/assets/015_\u60CA\u8BB6.c9eb5e15.png",F9="/assets/016_\u96BE\u8FC7.5d872489.png",k9="/assets/017_\u56E7.59ee6551.png",B9="/assets/018_\u6293\u72C2.d1646df8.png",j9="/assets/019_\u5410.51bb226f.png",H9="/assets/020_\u5077\u7B11.59941b0b.png",W9="/assets/021_\u6109\u5FEB.47582f99.png",V9="/assets/022_\u767D\u773C.ca492234.png",U9="/assets/023_\u50B2\u6162.651b4c79.png",Y9="/assets/024_\u56F0.4556c7db.png",G9="/assets/025_\u60CA\u6050.ed5cfeab.png",K9="/assets/026_\u61A8\u7B11.6d317a05.png",q9="/assets/027_\u60A0\u95F2.cef28253.png",X9="/assets/028_\u5492\u9A82.a26d48fa.png",Q9="/assets/029_\u7591\u95EE.aaa09269.png",Z9="/assets/030_\u5618.40e8213d.png",J9="/assets/031_\u6655.44e3541a.png",ej="/assets/032_\u8870.1a3910a6.png",tj="/assets/033_\u9AB7\u9AC5.3c9202dc.png",nj="/assets/034_\u6572\u6253.b2798ca7.png",rj="/assets/035_\u518D\u89C1.db23652c.png",oj="/assets/036_\u64E6\u6C57.b46fa893.png",ij="/assets/037_\u62A0\u9F3B.64bc8033.png",aj="/assets/038_\u9F13\u638C.2a84e4c7.png",lj="/assets/039_\u574F\u7B11.4998b91f.png",sj="/assets/040_\u53F3\u54FC\u54FC.27d8126d.png",cj="/assets/041_\u9119\u89C6.7e22890d.png",uj="/assets/042_\u59D4\u5C48.a5caf83a.png",dj="/assets/043_\u5FEB\u54ED\u4E86.62b1b67c.png",fj="/assets/044_\u9634\u9669.3697222b.png",vj="/assets/045_\u4EB2\u4EB2.dfa6bbdf.png",pj="/assets/046_\u53EF\u601C.634845ad.png",gj="/assets/047_\u7B11\u8138.ab25a28c.png",hj="/assets/048_\u751F\u75C5.cd7aadb3.png",mj="/assets/049_\u8138\u7EA2.9ecb5c1c.png",yj="/assets/050_\u7834\u6D95\u4E3A\u7B11.a3d2342d.png",bj="/assets/051_\u6050\u60E7.7af18313.png",Sj="/assets/052_\u5931\u671B.87e0479b.png",Cj="/assets/053_\u65E0\u8BED.6220ee7c.png",xj="/assets/054_\u563F\u54C8.2116e692.png",wj="/assets/055_\u6342\u8138.28f3a0d3.png",$j="/assets/056_\u5978\u7B11.9cf99423.png",Ej="/assets/057_\u673A\u667A.93c3d05a.png",Mj="/assets/058_\u76B1\u7709.efe09ed7.png",Oj="/assets/059_\u8036.a6bc3d2b.png",Rj="/assets/060_\u5403\u74DC.a2a158de.png",Ij="/assets/061_\u52A0\u6CB9.77c81f5b.png",Pj="/assets/062_\u6C57.be95535c.png",Tj="/assets/063_\u5929\u554A.a8355bf9.png",Nj="/assets/064_Emm.787be530.png",_j="/assets/065_\u793E\u4F1A\u793E\u4F1A.a5f5902a.png",Aj="/assets/066_\u65FA\u67F4.7825a175.png",Dj="/assets/067_\u597D\u7684.a9fffc64.png",Lj="/assets/068_\u6253\u8138.560c8d1f.png",zj="/assets/069_\u54C7.74cdcc27.png",Fj="/assets/070_\u7FFB\u767D\u773C.ecb744e2.png",kj="/assets/071_666.281fb9b6.png",Bj="/assets/072_\u8BA9\u6211\u770B\u770B.cee96a9f.png",jj="/assets/073_\u53F9\u6C14.712846f3.png",Hj="/assets/074_\u82E6\u6DA9.4edf4f58.png",Wj="/assets/075_\u88C2\u5F00.3fb97804.png",Vj="/assets/076_\u5634\u5507.59b9c0be.png",Uj="/assets/077_\u7231\u5FC3.a09c823b.png",Yj="/assets/078_\u5FC3\u788E.9a4fb37d.png",Gj="/assets/079_\u62E5\u62B1.e529a46b.png",Kj="/assets/080_\u5F3A.64fe98a8.png",qj="/assets/081_\u5F31.07ddf3a5.png",Xj="/assets/082_\u63E1\u624B.aeb86265.png",Qj="/assets/083_\u80DC\u5229.e9ff0663.png",Zj="/assets/084_\u62B1\u62F3.0ae5f316.png",Jj="/assets/085_\u52FE\u5F15.a4c3a7b4.png",eH="/assets/086_\u62F3\u5934.2829fdbe.png",tH="/assets/087_OK.fc42db3d.png",nH="/assets/088_\u5408\u5341.58cd6a1d.png",rH="/assets/089_\u5564\u9152.2d022508.png",oH="/assets/090_\u5496\u5561.8f40dc95.png",iH="/assets/091_\u86CB\u7CD5.f01a91ed.png",aH="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAADAFBMVEUAAABBhg5CiQ4/hQtLjBCQUgtDhg6VIA+6HQk/hw1FiA6TIRBDhg0/hw2hIA5Ahw1DiBBDhw6fHw67HQuQIBCLHw9CiA64HwuqJQ2PIRGUIBCVIBCUIBCmHw2aHw9Dhg6QIRGSIRCTIRCUHxCUIBCrHgxOkRpFhw02fwQ/hQ2YIA9HixCvHgu91aton0BHixFcnSWJtGnAIgubHw5YbwxUaQllrhmAt0GKIBBTkxykxosxfQBIeQ5TcQ/EFQQ4WQraHgWSIBFAhg5kiQ3eHwXPGgU+eQyM0jBUeQzgIAbVHARNihme1UKPIBGFGQ3YHQVmpQzJGAWHvDltljNwyBJAgg1BiQ7uWEyOHg/GFQToPyx+FQzTGwXiJQvnOyfmNR+CFwzNGQXvW1A/fQ17FAv0cGvsUkSPIhOKHQ/tVUjkLxfIFgTpRjWMHQ7wYFbsTkDpQjHkMhvrTDzjKRA7awuAFgzhIgfcHgXwXlTjLBPxZV3qSTlljA06ZguUIRGIGw46XwrmOCPLFwTya2XyaWI9dgw9cAzzbmiUJRd2yhdssRDRGgSnOjGaLCB8yh+YKBtvwRE9hgw9XwpTjR28Uky1S0RHiRNuvBHxYllmlC1OdAs7gQq8GgfKYmDGXlyEnkc7jA5EhA5nlw2dGgq0FQXadHfBWFVehAztXVOl1kuT0TmqPjWgMymEzShlkg2uIg1agAys2VKwQztfkShqqw9Ymw+YHw6UFQnVcHPTXlqfMSXnLBRppg5ooA2lHAuHFQtCZAo3WArEHAbkb27tb2ycxkt5mj6kNitOhg1Gagu1IwqsGwozfgDTamqa0kFvxRFkshHAIw+RHA2NFgvQFATcX1mlzlGNrUlhoSBIgA3LJgxJbwvoXlVakCNvsSChKBlepw9biw1GewzOIAikNAaQpFDdVUzkTkDDQjXfRDN7ti/DMyLYKRFMkBBxPw5jVgyOTQniYFmZuFB+qjp3nzmKxjWzNyh+wieDLhB8VwqYPAjXRzloniraNiNeaA6FVgqyTg/pAAAAPnRSTlMAId7eGQZcshnuQZeI+FjUxp1yDfvyrDIm26WNf35jJfTp0cJNQTIO6bmebUwThXddUEU7+3RHKN+OKvnljHQ4FTYAAAwuSURBVHja7FldSFNxHN1LKAg+lNF39PkSPVUPPZkXWuDqTiTSq9M1l+3eLa+bW9vUaEuLGrkxRltZbUuZieFgsWCZgcL6EBQfNHvIiqLvKPqCou86//+2rNe4t6eOCLKXc+455/f7/3dV/Md//Md//C1m5c9fv2pVYeGqVevnz5ml+EfIL1y0sGD2unWFi1YuWFZUxFAUFS1bkbd41fqliwrWFMxem6+QD4ULWJfLxYgi4/L4fYDf42JyyP7FLliikAtL5/r7Q14P6x/09vf3e0fiEMCwLMdxoiBwHAsNnMixfIFMicyb6wv2hvyukWQyCfpBn58X3G51Fm61W2CZVMqt5vilClmwhA1FnrwQR8Aej/t8HtCDWKez2zUaTb3GrlOruZQyPalm8hSyIM/fe6nyA+v1gt2fo8/xE2h0bldYNWbnVtAMZBGgf8b54rmHBz3lBz2FXSe60h1jGrkELOGDl/RP74keD8O5c+w5ehqBwA8p62J2uSIoFJKRO5Vf7nEsmi+ifpSfwg4xajfHDtV1FA+r2dkKWZC/fDB6s9LQ8CJFFAiZCSDMaB9GQGRS4ZoOZY9dWDZPIQ8WutBCg9XybWLIRV0QoAK/IsDdS0yUOFVKZUzDrpyjkAdLmVBUbzQ3aC+XPAwnYliKLO9yYSve+/Dsy3Nt7eayGmXVDR0v2yrM86CFlYZ9WpOj1AmydHgsJnL+3vGDh1r11p2OElWHsviGmkcFZMFqzhu92YwMqnfWbi4pU9UolR3lKS509sruQ53GhqbSEpWyrv2ihl0gz3k0K48PRvqakYGlzVZKBdTVhSdHBs7uPnKo0WAxZQT0aNTMIunZ6VEwErnZSAQ0IIPNJcSB8pgnevYqBDQbLC2bIaC9fM/Fem75fIUMKGCCkTtUwL7qpkwGHWMiCWD3wVa9udqGDhIBsIBfrJAe8+diCzRCAFpYvdNW6ixRqdKTgwiACrBqswKqqi7Wy9KC2UIIBswIIBYM8SQAJNBZadXW5gT01KtlOJDnrMRR1NmYjWBnC0pQEhaTCAAGYAj2tdU6MwKKi29gF+E4krqC3sjbPwRsrkn5x0kARw62NhsbdkKAigqoGqoX+NVSC1iMCjaCvw97oAECaktLR8UgAqAJ6A2WjIC68j3FxeFhO79GagErfNFLRICeHAZaCHA8nIwPZA1orDRXNzkgoAMCYEGsnpO6hvOE/shbagASsGib4ECC7aUNxB7uM+6rNjmcZBVTAT0ad9EqaQUs4TADzc0wwIgE2iDgIdc/cIUGAAPIbiKDSRdBMWpoZwok5afXMfD36Y00AZOtNjeCGIE+o9XS1oLBJNuZCkAGyyWdg/yN8ehN8KMBNAGTbZoYAH4Y0AwDspshI4BmIO0crOP6o3f0egRgyCRgS/DRgat4/oOtnXqjFZqIANpCDCLmQOJbwWxcRQg/rSASaJnmvANXjhxBABkD2ky1VEB2FVVd1HCS3kwX4ipSCRgN5gYi4PIo2ztwlfI36kkr0MqMA7SFZBeJKyS8mM1a4Qs+IfxGM03g8stUfBwGIAA00Ew+shEBMy3s0QjL50l4EMyNB58YAQNNoOnyhBgauHrwIDEAZxMdC8eMAFICu5pfK+FRLIwEnxiMBgMxgFRgyBMZp/xooDmzF6iAspyA4mEds1TC26DgDT41EP59hM30ctI7fuXQoUOtvwxAAlSAKicAq0jCW8laIsBsJvwWCCAJjLdS/r6sATY48IeAixopd2GhCAFWq3UfDCAVSHh6x1uBTnJHpgaA/88IIGCNpAJCz8HeAANA9zI2GLnZ2drZ2ZhrQE6AakZAPbNQQgHCSPK5BQA/GUIXLiczZzNKSfmdSCAzhpI7sJobTD6vBrTaNiQwzSajfXp9n54sRlJK228C2n8JWCThGBb5vN+0YG8Dv+nyBBvqrQQIPyllxgBagcxZAAxLOgVzlvvjL3YCTU0mU4ttlA/1GgjMtJRZA7CJZyoQ1qmZQoV0WOkZfGECWlpI3xJ8KGglyPDTJYQAfk8A5/Gy9ZJeSf33bDZbLeBwlCb45LMGwGL5/flzBkAADiOJb4VrWY/noQNEhAoC+p/lGkl3YO75O7IJ0K8GedLeiBh2FDxgws8oH//QRgvRkqWn/Crw09sAbkR2qd8SrGHZVA2ek8A5wfoGTaQN1Hz6aRn4EUC2AbiXi8vypb2WFzFiguRMUI5X1dPk0YEZevr8CIDOgA57UFosZFgu7QQRoIzxfMJBuJ2bp6fphzU1yhw/cBEGSP3dbP5cRnCVo2h40poxlnU9hB/Osh/d3W9I+KCvK8/yV43hJclCyb+dzmZZd0wJLiDtYoQx4vynruMVXW9qwE4eH/kT9Ojs7HIZXhAUMJw7lkbSU1NTsEAYLSt703Xswo5A15upuvL28vY97XAAEzBcLxbJ8cJ+Th7DqcXwVPrR50eJFDMphidubT3ztXtv4Nbo1FR7cfjR58+jVYRfYBYhAOmRTxQMx74HAju6T31/9fHG667rj9/fP7C361P60acN3d0VFbce9ejAX6CQB3MK0INXgZPb7x4PBLoevH6w9cy7bSdub9p1a0MAZdix5XDX62GNKNu/bIAlc5lXp7c/PnNyx5ZdgYrAhTPXzh09v+lwRcXdkxe6d+0/UPFax+EeICPm/WzHfF7ThgI4/mpTh6KoG8huPQxcS7e1G/vBfhF4QhTcYWy+/APvX8jRQC4JNIeQGlA0h04voqAo1ZuCHpQKxcoOW0dZaQe7FLrD2tEddtiLdkyQwRjkucE+EHL8fvJ+5cu79BUZm93uQUoR8MbWWbfUqiZFfqt3dnB4lBRefXpNrujs5c4Tfuu0VtQOPyjQyJS1fDUp8GfdgdaKsnLu67UbwG48G7ncQbmsN9+hVGpYT2RZOfWmdp4vtKWNu5evANu56kIy11Dr+UQO4u1KVRLRXumgUuh35Ff3AA3uvUKCkK2Gw9s8FrJtluOHrQJ5K3D5OqDCU2LAsu1+H0GhQ/Jz2bbUkWToZwAdFu55IVZEiRV4LGLysJIgIxhkADXmAj4IIULINOEY1/J9QBXG7XGljL3jg8b2Oxm5VkKAOsx87OWLZ5FmOMpyDgbQZ24s8HwkMAco82uBB/fXPIFAwLPqDE1tSvsFmNXleRPBMV7/CpjEfoEHD71mKmYYRiwFMSfLGC6CCewWuL6yZMa2MoRve3uNkw8iq/A0BZhlM5bp9U5ffIlEyuV1tUKKim+ymdgrwDB++L63+bY7eDYolSLldD6cFKEHTGCrgM/thxkSXyyS/EhZI/mkHXjdYAq7RsBn5b+pFQelsrYeT7fC4baE/FMzYJsAqYej/FJ5PR6P6/VEItpReCeYxF4BY5yvjfLVSriQlJCP2kEk4VTv44/8XV3NhxP7Hdk7NQC2CQhkAj7XauP8dL0STmQ7AgyAKewSIAPwtki+f1dPW1WR5LMinJ86hGwT2N54//JFRFObzVa+QuILfVZErqktaKMANIyh2qokLMLVbJIVIIX8SQEkK/3+fjYaze63JVbkoINC/qTAuKKOkAQOegO2zv/0IhQRz0OEOY7DGPGugM2fPy3Q4RzO1aDf5/D5lgNOKvVw+m8IwALDML999v17pfTmg9u319bczMJMBB55/EuPd3ZMhLyO4EqIusDNJRizimYOIqvwuoL3KQuEdjIfN3sv3xsnPMYcJhbBEN0RcBmbn990v5zr6eHhCVZkDF2rVNdAEGZOa7VixGpb+rDxQVAQ6ZsMPYHbOynjfDAgApoW19P1bUHEvIeiAFmFZmNd09YtiIHaECTMB3z0zoFbJkJDK3yErtaPRGLgpSfwaAnhEz3+06B5REonpHgSPjSR3NB34xek1Va1I9AUuOk3Oe4wndbHArvpZqVPyvgWNQGyEaAiN1SVOOyOq3chKaIYPQFwawcpylGr2azXVdXqvtYVLTymJ2AZCOL+USWfr4zrJxkCc4+iADGAiiT1s9VqoVCtRrNtVuIaNAXA2vwGFkj3TBLIS1Iw1REgMJ55iLAiEKw/EuQNimtgzNxK0OHlCV6XP+iazT3hwqLb6XSHri/8rReVv+S/gB0CmeOIlp+hQCo21JuJxOwEIGq0CoXCrAQWHUhW2klCR3YsAvowREAQR2AHA2aAB/IXkJI+E9zOC9zgP3/Od9g51BFcCJb+AAAAAElFTkSuQmCC",lH="/assets/093_\u51CB\u8C22.aa715ee6.png",sH="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAADAFBMVEUAAAD4+PhuZ2D////8/Pw/JhF3d3d5eXk7IAlxZVp3d3d6eHd/fHrd3d2Xl5dCKhOBgYGYmJg5HwuYmJhnZ2c9JBBsamhWPSPu7u5NMxXGx8daPRs7IxFaWlplZWVaWlpCKROXl5ZoaGhaWlpDKhVdXV2GhoVBKRZiYmKNjY17e3tHMB1AKBN9fXxbPhs8JRJ0dHTCwsJXPCA/JxKkpKS1tbV3dHFnZ2djY2NBJxG6urpBJxE+JhJ5eXlaWlrW1taDg4PZ2dmdnZ11dXXb29tjY2NGLBRiYmKNjY2SkpKRkZFILhW9vb3CwsJfXFnPz8+hoaE6IxHBwcHj4+PS0tJycnKUlJR0dHS6urpmZmZ3d3d1dXXHx8dbW1tmZmaJiYmDg4NAJhLq6upHLRRiYmK7u7uOjo6fn5+WlpZzc3OamprHx8dZPBo7IxF9fX03Hgo6IhF9fX1fUkhzc3PIyMjFxcVgYGCGhoZ0dHTNzc12dna6urq5ubm6urq6urpiYmJ/f39jY2Pt7e1ZWVnV1dX///9dTD6dnZ3Dw8NOMBecnJzMzMzFxcXOzs6bm5utra3Hx8fKysqZmZmgoKB2dnZxcXGXl5eUlJRMLhaPj4/Jycm3t7dBKBOMjY15eXmqqqpzc3Nra2thYWHBwcGsrKyKi4ujo6N/f39GKxQ4IhCBgYFwcHBtbW2WlpZNLxbPz8+np6eTk5OHh4c1IA8lFwqRkZFSMxg/JhK5ubmFhYUuHA11dXU7JBEoGQumpqaSkpJmZmZUNhhKLhVILBW7u7uioqKDXyeAXSVEKhMyHw4sGww6IAuzs7N9fX14eHhjY2NbPBqDg4NZWVlgQRwhFAm9vb2EhIR/fn5cXFyDYCZKLRQ9Igx7e3toRx5YORmwsLCpqamJiYloaGiCXyZ9WiV7VyR3VCM9JRF8fHxeXl5vTSBkRB7W1tbR0dG/v79zUiHAwMBsSyDT09O1tbVxUCF7dXBwYFHQ0NBzZlqEb089KhxMMhl3bGN2aV5dRy6DXyjjKJ9PAAAAh3RSTlMACQRHaMNDJPRTMBcKBewnEOLc29vTPh4cFhQL9O/u5OLQxsG2sa+qpJiLfnBkVlBPTUREMiUc/Pf39u/o59LGwr+7trKYko+Gem9kY1ZKREM4NScZ+PPu7Obe0s63tKahnJuHgnFkY1xWVD44+fXz7+7l4d/X1tXCuJ2Zj4R9e3p5eG9rVjchCw8JAAAJT0lEQVR42uyXzWvTYBzH4w4KU8GDDBFUUBQdDDypF0UQ8eUgHhRRUTyIbwdBBBUvKh42sjbb0iSllsS8WANtRFMorARsD92tTWmhL4fBbE/tZQz8B3yeNlnmo1ieZ02L0O8/8Pn8fkme7xNqlFFGGWWU/ydj1FBz5fCh99QQc2VfuV6+MLwlTOwrF5v18vlhGUwcKKuGAQzubKeGkW0vIN9IAINDJ6jBZ/uhspqQLU7mlXb9zDZqIEH5nKTrNcky2uWBG+y6A/mFdCzWiC9bCbV+ZpwaZHYdrgN+LS1mzIxYakGDA4M02AH4cH4xLLCCKaZbXKLYPjBBDSpjR+uqwbWqYphlaEYIi+lCx2ArRRhyPkuDsB0DPtved5waSM63AX+5KpoCQ9PTNNxBJNk1eEz5n7EL63wW8KehAQsMdI5vquobyvfcV1VDlkqxjMBAPmpwn/I571RVsSDfmX+jgS0rqupzOT4+VVRkKb4+v2fwJdLQJVkpqr6W43HAtyDfm98zSDXiwCBbPLqD8itb93fnT3nzewqOgeGbAeRnIb+R+uLOjxrEOgbZu7soPzJ+E/BtvZHy9o8YCBnXwI8ryvjuDj8ZQeZHDEqgHJvZg9t94DcVnuvwGZTvvYpCRoQGSvZgvy8I23rx3R2YYrUFDJq7J/rMVwC/loyEUT66A9dAudnPcjxxUDHW+YgAYuBcEHhD2d+/ctzb5acjYQHlo6HdCwI0eNQn/pbDgA8vQD3md3cAiiFdAwZG8UF/BI5lOVsGfHf+XgqMY5BInOqHwc5jKhdaKsV7z4+UIzQoXt68wMWiHZpb+RRGCuDfCq4Bf/LSZvmXOvx8Lhpie/CRcgQGNs/zyuTm+JdPSqG5uXy0oq19YxFOrx00OgaJyU3xsw5/TZvRfjAYAoxTjrzMvyYvx4fO/Lk1TdNmZj4xWDtwDeRzpNU0lZBCKyuAvwr5IHM0jbMDwTGwXp0gu4Bcl5by+Z+Lle78MCs9Df6sZ5m3uNtE5Xiu8H0xGs1VNIcPEshP4+0gI0IDjszgXCy6Wll12K7Bz14GaDl2Dexb4wSPwDYXA4H5hYX5wAaDaAjXoLps8ZxEYjBlmblZEGAQ8AxyIQbTIF0ABsuntxJ8htfNytcgMPgwv9FgCceAdqqJa5EYPOLNSjAYRAwqn/F2AAwKHG8XnhFcUZ7cMHPBr6jB6nfHAKscudrTKRKDcG4WPobfXkXtG+4OoIGt62/xDa6eDi/+YRDQPhLtQNcnx/ANnqdQA+dYJjCIxycJdvAy4hg4XyPesez9v8dtYFC6h//vuuds5C87COQxisH9fyc2SEUX/mKAdSyDHYBytKR49Qj+BeFa1yA4+wE5lhnMcqzWpEKVxGDvkYy7A/JiYMHnGEuXksnkFEVg8KtdMwltIgrj+LgEFLHFSq3bQUHwoCiu4AKiiBc3XBAPgqh4UlFED+JyELVJO00nDbRpMsWDScgcmrZMmilhRkmiWaYeAi1IKq2FpA3UxGrVui/vzaKdN63JTC8e5n8Qb//f93/ffN97bTtcBMgAIegCGWicCM3Nnparh3S8j053uJxoBnAsl5yB3f7M+8ze0NDp8fy8vE4PQZOLEBeDguCxtVR/b/vgYLu31eP5kk1dWqPnjSQQoBm8LXEsA/+Hbnd9TYvnSzwW7ydXL9FFgNehfQDv66XV766vr7e3tIz3D8djmRGfqVzHO60VEtTCU5i4mh7WlFQ/9G9uGQ+m+kfjsfSwpWKjTgKIQOCKxWAtYi/5e5ubx/2WYOr1h+yv9NDAlf063opPXHhtG5qB+dW/h6Ls39n52e+3WIIDPSNDsXS8h923TDPBgRMu8yQZgLFctP7HnU8Ef4Hg3VAmltHVihsggZABgZd2X5f9Ozp+AH9R4R7YiukPkcqL2gnKxAzQxVBtnbp+8AG0NzV9h/4yAWjFLGjF4HLtM+lCWZcZrGc0g67JF4Ps39r00eGQ3MVjAK2YiWVTy9dqJ1gACOSRhNzX1fP3MfQfbGz8+M03AUBqxQxoRUZ7Kx5dgGSA3tfR+qH/15c+h19BEO55NxxPZ94lTFWaCRYiGUxxX5frb2h88ZWjyChKkBKm4qhDeysekwhs6sWg9n/Y0LpydTefzCX6HBaFwnAmxdJD4Z2aW3HLyqdIBtJYtqr9ra0rl86roHia8UUQAtCKcCZlU7lzeghs6lN45K5B/asbF27BsLnbkjxFKtvg70yKv2bOaG3F43tkAnQx1Kj9gda8DIVYMip9i2grwvVYNQ0Cs+rFYLcL/m5744LN4i/dV7G8QGBBFBbX4+g3zetx6Z4uNAP5vg79BwX/hoXQH6qqguJgI0qngLZifDiseSrOv+nCneoM8Pf2apC/6A/ql7VxTpKjmYTUiOhMimdHw8s3aiW49d4sEyjGstcL669/Zv3rL7YBIPBJHyPaCEOj/RGT5sfr7UkzIN64hQtATdlRbKLO5Hiekj9GdCaNjPQEGe13lDsCQZ0iA5yoJV65of9h5K8/TCzHU6SCoM/XJzXC61SUXKX9/X6+SyJw4n/8bbVtxHNvNfBHtLWC5UIKgkR3d3dCIBgYCCaYneWYdgIXTsgZiP5O8LO1Ory97CCm0qI5lIKgrxtKyCBocSRYchOmXQe2yxkQuFg/kBN/cw+bRHPn0BMJogKAT/i/P0JS5HpMDwHIQCaA9UN/86Oz9xdPQRCABOI8iLyEikB/hyPK0PoAsIPbCUJcTU6bTfQ37509awY2FQFPyfPAB/zFABzRBJsER6CXwAkIIAOUDUf81QR0LiHuBYc0Fvx9PiZJryjH9GnDSYKoa2srFAqf6or4iwRckgWNIE5lKQCSClHgM9RNADqxMJYfK3yyEebdiD9KsIMKBJLgGOQ7EgyCZJM8sxbTrcPXcGchn8+P1Rbxh3pQmePAMYAQRAQ/bACao3dUYfp17LrZNpbPFwjzLtRfrSWryVAvF6JZJuGLRqJRH6if40khAP0Ep3BbfkzyL6pz26gARKDYHMPkKDoUCLCmZdi0tBgQOCX/4tpUyYR6ewN8KAkU4np7KeQT0ENwA1ecf5FjWLMjFwoABiDwL7XiCDZtzbh7FvqXqiP7VjA0D905mjQh9evULA3+MIW1qyq3kSS507QfOX+9mj8f06iqI+vXbyqfiRkyZMiQIUOGDBkyZOg/0m/+aqodh3mGTQAAAABJRU5ErkJggg==",cH="/assets/095_\u70B8\u5F39.3dffd8e8.png",uH="/assets/096_\u4FBF\u4FBF.b0d5c50c.png",dH="/assets/097_\u6708\u4EAE.47389834.png",fH="/assets/098_\u592A\u9633.89c3d0ab.png",vH="/assets/099_\u5E86\u795D.2d9e8f8a.png",pH="/assets/100_\u793C\u7269.37ae5ec0.png",gH="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAC7lBMVEUAAADONgnVOQm5LQzLOSbHOCe8Lgy8LgvBMAvGMgvLNArRNwrONgq/LwzsvrHFMQzBMRTTOAm5LQy6LQzVOQjVOAfUOAnFMxO5LQzBMA7SORTBMAvUOQm6LQzVOQi6LQzUNwnMNQrUOQm5LQvfkYPdjnmzJyC3KSK1JyH0h0jPNzLRODO/LSe7KyXzgEf0ikjDMCnLNS/SOTS5LQvxbUbHMy3JNC7BLynyd0b0gke9LCa5KiT0hEfzfUfTOjTydEbze0fUOzXVOzbDLSfwZkXwY0XwYEXVOQnNNjDFMivEMCrwXUTNNzHyekfxcEbxckbWPDbya0bVOAi2KhTXPQ742Sn0jEjxakXwaEXziEbuW0TTQTPwXES7LQzTPzO+LwvBMAzLNAvXPDe8LgvUQzPGLinRPjLHMgnTNgf51yj40ifcdzzdejvROjLFMQn750fvWUT51SfBKiXONxXefTvIMCvCLCbQNwvRPDK/LwvJMwr52i3LMy363Sj5qxv52y/JNCz52yn5zyX4uiDRNQXKMSz5zCT4nhf640DLOC35xiP5vyHDMAnBMAnbdDz63zbCLyjLNCW3KRr4mRbKMg3IMQ3MMQzKMgX0ySzPNyfFMQ385UPonjXiWzT63zLOOi/2jkrnUj/bSDfWRDTWSjLuszDywSz5wyL5sRz5lBLPNAvONAXSOSjKMxTNNgv85j3hTjv74TrmlzbfYiz5yST4phq+IwDrV0HfSzrYTzHIMyv63yj5tB74oxjlWT7ggzniUjTjVzP98Ev97EXxfETrXkHYPTniiDjjjjbrqTL2zivFMiL4tx+8LB3uWEPbcDzwuTT30irBLx+4KxDzg0XhVDvsrDHqozHpkCrkbibofSXvmiTrdB/wfRn0yEXub0Hur0D85jbZWjT63i3zxSzfWSnrYz/0yDvlkTfpazPmZDPTPjLjfi/74ijgTCjvgx31jBbziUbxvkT42j3vqym7KyTdSR7ifzf21DX1rSG5JTuyAAAAJnRSTlMAC1+6U1PzU/T09PT0UlMsAvWa+O/evkKybCEK0sitiHhJiWBTU1yGCb8AAAkaSURBVHja7NMxasNAEIXhyLhLYQUkmTjG2OnUaFsJJKRuKiUgFoFvsL0KXcBncGfY2rcQ6AjqVSUQFwY3qTM5wY5gBxLwd4H3L8s83P1Zq93Mpt3CnbLuzjc+2OUFW4f++gBQZRMgf0bcX/i4riqQFoFSmEArcPD9Sl4/42F/u+2tGPqxk1jgLSkBr7j/PQqta4u0jq9YsHYIH+DhfqJrYZlOfwu25oBnqGSvhX26lAoC13iBG1AfgoXuFPgrU8DLGg5fOuRQj3jaS+MNeGwBosfrnhsDnhRPABqkogVcRGjAHpByCAegBZwvYcoiIgYcT2HCIY1aegCLrGkJAY/t8ZRGHJK+aQ//JCCJWEwIyDhMCIgyFiU9oOAwISArWMTNmRpQsqAHFDGHMucJoHsnB5Q5B3pAF+cs3sgBP8TOPUvDQBzH8V18JbpmdzDJEqhkkIREDgrxFg2CohyIOAndglBxSElp0kmtl6tDW4f4EILi0i7BrbYV2g6d2kFH+zAo1KYntPhd7pYf/8/K2lx6owIsXicfVmJzidm7uKQDxJh5FJP+GcDI1ABGpInpN3pEqqgBZ/eMRJEoNwMvDEPPa8qiSLNg9+KUAFGeliQHoe0AiBCC0LFdj5WkqaM/ANjoZDkoqgDpSyBbymrLywiqtsfKU1YzBHCuBnXQuKt1q9Vqt9a+0XSk2gE7bUYNYLmo2MCGSC3XEv7jKH+n+lTSoeZx0TsuNxuA5wC9UTP9ne98v7UNkOrykcOAGsDxk+M8FcCPnm+aPwCm6eNUFoEiHxEtIB4NKDgQtDFOmP0So0ZfXCnpahgFEKgAC/HkVUbghQkpNoDPdUISGGNCjGEEDxikXslCrTBhyfNCxsnFz6kAp/toEoF3gd6xDEJwK1+xjg8HHVuf+VQPE6P+CoCj/H5eKaY39+kBu6tpVxE2xhIKGmq8WH2BkSpvV47Whx3my1utumFY7x1ddYXxlZJxbg92V0/oAV+klE9r2nAYx0877K3oab6AQJKLZZdcvJgQqERFfxFMqUWqqcZQoQru0oEFqfin1sMOxbZoteBt1VJsvVhbb2sPg663XXbb88SsqXQb6fY9GBB/+X6eT57IsitrW9W28F7wLkToBALXj6kUlF3JpF/UsF8bEtJK7X7YTd0VTwK10fMz4ENoV8twO5b1I8AbWwBLLIsI/oeDtrBwu3YtchjWQDqUTQgZjIFA3ZPJ2fkdfudRpxG+4rUCs3ci/jWstwDsGcDAwbR40I4KQnQe7wEfmKqhRCqVSng8JRgc5r/vk9WGmkjgd1qjHqh6oxCw5Y1WquXuygprxp+0DZD0s2bgePehUxmZCNVAvREOeRLYr42/EnKtjgdE3oNlQIBQWLmJSG34oRCtHNS2WHN2CApw2wRY33EkY35kMD2sxNwiQIyEUS1+mA0r0GY8+2IfuktAoRmrmPAoYWUa4CujSqdW7mK51e7fTDqc2zYBPjFONyBYx9fQY/qh2pEi3zIZUID1qvqI9mXS0nrm66BkMt8lXkyDOWy36mNYT3PLdgE+cxQgbKKFBYolyTXNoAIcfzgcTgayLK+WJsPJOfaHwpmsLklb+NQXh3c7XDTn45bX7QL4fAztciRBwwJCWorPskcZJQRlgwIhRDZCSKGkGgDZXL7Ol5+rj8WS7xxOiuE4n12A9SAAQDhAAA24DRaAODvKZY1nUJJXMWAAP4ca9CuZo339hC8/taN6t9NFMz7IawHwAEPNGQDiyUBu/yiMCpQiplXoN/CK8xsCLtDAUznMTjMw+6sBOCM+jmNoyulwv9sEEQDRlSLTfD4HaxjyaD3MdeFs/NiDJTQF5H9IfBnFYzvOju4583bMKwCsMAxFuQAiCSbSfPxW1+cKxg1Mi/Sv7huNe8XcAH0GAEa5k6KgfSG0LYC3FoAVWEmXw+F2i+Lh6YWhwNOaP/xfO6DON0C/FfnIy3ITYHs9aA/Ax7wIzdBgQuTrx0CACgaXBQhZlfFyWVJBwL5+2jyM8xRNM7/NPwNYoXnxttnU9+FFKO5hBqQ/wes5/Afk8qfNWV0UGcj/AASDO38EYPjAl+ONpo6voqapqlqCJeypqjbv39i4ifN/AfgYtAnwk9o6Zm0biAI4PrZL+yna5W45CaRuBnfSHVozHQgNQpsF3qJFqDFYKFVA5aaGgpfQ2GuNCjbRXEgDhW4GZfRsD/0AfRIxmWQd2EfwfzGa3s86PaGP/bYcuAVRI2h28QwA959gAZ7mixsHTqCt3hEAA+4sRFFMYRUugNAAzoZDWIDRXVSU8AScHw4I9gDwhPvzpCymsAtjIHz78+t+eDG+vB1Ni7KEFfBRfx8gkAT02tI1n/urJCkjINxejr//+DeG1w/8/TJJNp7DU9RrTT8YAFkx585KNIS7h9FnGD56mEZFIpLNjeOlpt5rbXAMAKa1YL4VAg4iaoKzT4SYVR7Mp1bvYEAQfO3r7WnEAMGimgkoaRIwfrN2OE/JEuvtDa6D7HAANvKl7znOutrOdm0f514zn9q6YgBk05ylHAiL9ap6hKr5wvO551NCNP04AB3vS6M5oRMg+A73IA6/3E9ZTmKE9yULyDoAA40RQmh6znf5kyXJCVsirBqwE1BCcpgYp3VxfUXgCuEjAb50ADDSDEagHIJIHTUR7ghJAV5nVwDoyjYpI88xGlsIdwOyKzkARl3VH4oGZQwUjFHDtJBE9nX2850kQCbb1kwzjk3NthGSBbztBrg1QEUAcE8FgGwlWfIAS0nyAEtTkysJ+P3iAM1UUiwNMJuUAN5LAQxFua776qUBb6QAVFHyAKYmOUAY/mVETWEYngjgg6JOA/C/XTpGYRAIojA8IphKlLVQEbEIGAtTTRGIx7B+bLE38l422bOkT9IHdosdZMHvBD+Pl2n9eswytNaXKAL22UE84CkknoC7kKMD3pEEGLMvQowxXgHb4iAecBNyBkQSALNNQgD4BEAy4NAFxngCRhlxBHQZWDIgJ4cyBa+jjA3ICnIZADvKWBl9Qi41S02wMaDIqUsBSLxgsoyqILe6AhB+g9UyMJCPln/sGpK1/NUk5OWasQhVkqdCVRxa1edE/pKLatJwGtUWJZ3++QAvYm03quwEIQAAAABJRU5ErkJggg==",hH="/assets/102_\u767C.f43fee5c.png",mH="/assets/103_\u798F.58c94555.png",yH="/assets/104_\u70DF\u82B1.61568e1e.png",bH="/assets/105_\u7206\u7AF9.35531687.png",SH="/assets/106_\u732A\u5934.7eb8ff1d.png",CH="/assets/107_\u8DF3\u8DF3.24101efa.png",xH="/assets/108_\u53D1\u6296.3eabd306.png",wH="/assets/109_\u8F6C\u5708.67669ca4.png",m1={"[\u5FAE\u7B11]":w9,"[\u6487\u5634]":$9,"[\u8272]":E9,"[\u53D1\u5446]":M9,"[\u5F97\u610F]":O9,"[\u6D41\u6CEA]":R9,"[\u5BB3\u7F9E]":I9,"[\u95ED\u5634]":P9,"[\u7761]":T9,"[\u5927\u54ED]":N9,"[\u5C34\u5C2C]":_9,"[\u53D1\u6012]":A9,"[\u8C03\u76AE]":D9,"[\u5472\u7259]":L9,"[\u60CA\u8BB6]":z9,"[\u96BE\u8FC7]":F9,"[\u56E7]":k9,"[\u6293\u72C2]":B9,"[\u5410]":j9,"[\u5077\u7B11]":H9,"[\u6109\u5FEB]":W9,"[\u767D\u773C]":V9,"[\u50B2\u6162]":U9,"[\u56F0]":Y9,"[\u60CA\u6050]":G9,"[\u61A8\u7B11]":K9,"[\u60A0\u95F2]":q9,"[\u5492\u9A82]":X9,"[\u7591\u95EE]":Q9,"[\u5618]":Z9,"[\u6655]":J9,"[\u8870]":ej,"[\u9AB7\u9AC5]":tj,"[\u6572\u6253]":nj,"[\u518D\u89C1]":rj,"[\u64E6\u6C57]":oj,"[\u62A0\u9F3B]":ij,"[\u9F13\u638C]":aj,"[\u574F\u7B11]":lj,"[\u53F3\u54FC\u54FC]":sj,"[\u9119\u89C6]":cj,"[\u59D4\u5C48]":uj,"[\u5FEB\u54ED\u4E86]":dj,"[\u9634\u9669]":fj,"[\u4EB2\u4EB2]":vj,"[\u53EF\u601C]":pj,"[\u7B11\u8138]":gj,"[\u751F\u75C5]":hj,"[\u8138\u7EA2]":mj,"[\u7834\u6D95\u4E3A\u7B11]":yj,"[\u6050\u60E7]":bj,"[\u5931\u671B]":Sj,"[\u65E0\u8BED]":Cj,"[\u563F\u54C8]":xj,"[\u6342\u8138]":wj,"[\u5978\u7B11]":$j,"[\u673A\u667A]":Ej,"[\u76B1\u7709]":Mj,"[\u8036]":Oj,"[\u5403\u74DC]":Rj,"[\u52A0\u6CB9]":Ij,"[\u6C57]":Pj,"[\u5929\u554A]":Tj,"[Emm]":Nj,"[\u793E\u4F1A\u793E\u4F1A]":_j,"[\u65FA\u67F4]":Aj,"[\u597D\u7684]":Dj,"[\u6253\u8138]":Lj,"[\u54C7]":zj,"[\u7FFB\u767D\u773C]":Fj,"[666]":kj,"[\u8BA9\u6211\u770B\u770B]":Bj,"[\u53F9\u6C14]":jj,"[\u82E6\u6DA9]":Hj,"[\u88C2\u5F00]":Wj,"[\u5634\u5507]":Vj,"[\u7231\u5FC3]":Uj,"[\u5FC3\u788E]":Yj,"[\u62E5\u62B1]":Gj,"[\u5F3A]":Kj,"[\u5F31]":qj,"[\u63E1\u624B]":Xj,"[\u80DC\u5229]":Qj,"[\u62B1\u62F3]":Zj,"[\u52FE\u5F15]":Jj,"[\u62F3\u5934]":eH,"[OK]":tH,"[\u5408\u5341]":nH,"[\u5564\u9152]":rH,"[\u5496\u5561]":oH,"[\u86CB\u7CD5]":iH,"[\u73AB\u7470]":aH,"[\u51CB\u8C22]":lH,"[\u83DC\u5200]":sH,"[\u70B8\u5F39]":cH,"[\u4FBF\u4FBF]":uH,"[\u6708\u4EAE]":dH,"[\u592A\u9633]":fH,"[\u5E86\u795D]":vH,"[\u793C\u7269]":pH,"[\u7EA2\u5305]":gH,"[\u767C]":hH,"[\u798F]":mH,"[\u70DF\u82B1]":yH,"[\u7206\u7AF9]":bH,"[\u732A\u5934]":SH,"[\u8DF3\u8DF3]":CH,"[\u53D1\u6296]":xH,"[\u8F6C\u5708]":wH},$H=e=>{const t=Object.keys(e).map(n=>n.replace(/[\[\]]/g,"\\$&"));return new RegExp(t.join("|"),"g")},EH=(e,t,n)=>{const r=[];let o=0;e.replace(n,(a,l)=>(o{typeof a=="string"?a.split(`
+`).forEach((c,u)=>{u>0&&i.push(C("br",{},`${l}-${u}`)),i.push(c)}):i.push(a)}),i};function Dm(e){const t=f.exports.useMemo(()=>$H(m1),[]),[n,r]=f.exports.useState([]);return f.exports.useEffect(()=>{const o=EH(e.text,m1,t);r(o)},[e.text,t]),C(m$,{className:"CardMessageText "+e.className,size:"small",children:C(Tt,{children:n})})}const MH=e=>!!e&&e[0]==="o",y1=Gn.exports.unstable_batchedUpdates||(e=>e()),aa=(e,t,n=1e-4)=>Math.abs(e-t)e===!0||!!(e&&e[t]),kr=(e,t)=>typeof e=="function"?e(t):e,Lm=(e,t)=>(t&&Object.keys(t).forEach(n=>{const r=e[n],o=t[n];typeof o=="function"&&r?e[n]=(...i)=>{o(...i),r(...i)}:e[n]=o}),e),OH=e=>{if(typeof e!="string")return{top:0,right:0,bottom:0,left:0};const t=e.trim().split(/\s+/,4).map(parseFloat),n=isNaN(t[0])?0:t[0],r=isNaN(t[1])?n:t[1];return{top:n,right:r,bottom:isNaN(t[2])?n:t[2],left:isNaN(t[3])?r:t[3]}},Pv=e=>{for(;e;){if(e=e.parentNode,!e||e===document.body||!e.parentNode)return;const{overflow:t,overflowX:n,overflowY:r}=getComputedStyle(e);if(/auto|scroll|overlay|hidden/.test(t+r+n))return e}};function z$(e,t){return{"aria-disabled":e||void 0,tabIndex:t?0:-1}}function b1(e,t){for(let n=0;nf.exports.useMemo(()=>{const o=t?`${e}__${t}`:e;let i=o;n&&Object.keys(n).forEach(l=>{const s=n[l];s&&(i+=` ${o}--${s===!0?l:`${l}-${s}`}`)});let a=typeof r=="function"?r(n):r;return typeof a=="string"&&(a=a.trim(),a&&(i+=` ${a}`)),i},[e,t,n,r]),RH="szh-menu-container",du="szh-menu",IH="arrow",PH="item",F$=f.exports.createContext(),k$=f.exports.createContext({}),S1=f.exports.createContext({}),B$=f.exports.createContext({}),TH=f.exports.createContext({}),zm=f.exports.createContext({}),co=Object.freeze({ENTER:"Enter",ESC:"Escape",SPACE:" ",HOME:"Home",END:"End",LEFT:"ArrowLeft",RIGHT:"ArrowRight",UP:"ArrowUp",DOWN:"ArrowDown"}),rn=Object.freeze({RESET:0,SET:1,UNSET:2,INCREASE:3,DECREASE:4,FIRST:5,LAST:6,SET_INDEX:7}),Ns=Object.freeze({CLICK:"click",CANCEL:"cancel",BLUR:"blur",SCROLL:"scroll"}),C1=Object.freeze({FIRST:"first",LAST:"last"}),Tv="absolute",NH="presentation",j$="menuitem",x1={"aria-hidden":!0,role:j$},_H=({className:e,containerRef:t,containerProps:n,children:r,isOpen:o,theming:i,transition:a,onClose:l})=>{const s=_g(a,"item");return C("div",{...Lm({onKeyDown:({key:d})=>{switch(d){case co.ESC:kr(l,{key:d,reason:Ns.CANCEL});break}},onBlur:d=>{o&&!d.currentTarget.contains(d.relatedTarget)&&kr(l,{reason:Ns.BLUR})}},n),className:sd({block:RH,modifiers:f.exports.useMemo(()=>({theme:i,itemTransition:s}),[i,s]),className:e}),style:{position:"absolute",...n==null?void 0:n.style},ref:t,children:r})},AH=()=>{let e,t=0;return{toggle:n=>{n?t++:t--,t=Math.max(t,0)},on:(n,r,o)=>{t?e||(e=setTimeout(()=>{e=0,r()},n)):o==null||o()},off:()=>{e&&(clearTimeout(e),e=0)}}},DH=(e,t)=>{const[n,r]=f.exports.useState(),i=f.exports.useRef({items:[],hoverIndex:-1,sorted:!1}).current,a=f.exports.useCallback((s,c)=>{const{items:u}=i;if(!s)i.items=[];else if(c)u.push(s);else{const d=u.indexOf(s);d>-1&&(u.splice(d,1),s.contains(document.activeElement)&&(t.current.focus(),r()))}i.hoverIndex=-1,i.sorted=!1},[i,t]),l=f.exports.useCallback((s,c,u)=>{const{items:d,hoverIndex:v}=i,h=()=>{if(i.sorted)return;const b=e.current.querySelectorAll(".szh-menu__item");d.sort((m,y)=>b1(b,m)-b1(b,y)),i.sorted=!0};let g=-1,p;switch(s){case rn.RESET:break;case rn.SET:p=c;break;case rn.UNSET:p=b=>b===c?void 0:b;break;case rn.FIRST:h(),g=0,p=d[g];break;case rn.LAST:h(),g=d.length-1,p=d[g];break;case rn.SET_INDEX:h(),g=u,p=d[g];break;case rn.INCREASE:h(),g=v,g<0&&(g=d.indexOf(c)),g++,g>=d.length&&(g=0),p=d[g];break;case rn.DECREASE:h(),g=v,g<0&&(g=d.indexOf(c)),g--,g<0&&(g=d.length-1),p=d[g];break}p||(g=-1),r(p),i.hoverIndex=g},[e,i]);return{hoverItem:n,dispatch:l,updateItems:a}},LH=(e,t,n,r)=>{const o=t.current.getBoundingClientRect(),i=e.current.getBoundingClientRect(),a=n===window?{left:0,top:0,right:document.documentElement.clientWidth,bottom:window.innerHeight}:n.getBoundingClientRect(),l=OH(r),s=g=>g+i.left-a.left-l.left,c=g=>g+i.left+o.width-a.right+l.right,u=g=>g+i.top-a.top-l.top,d=g=>g+i.top+o.height-a.bottom+l.bottom;return{menuRect:o,containerRect:i,getLeftOverflow:s,getRightOverflow:c,getTopOverflow:u,getBottomOverflow:d,confineHorizontally:g=>{let p=s(g);if(p<0)g-=p;else{const b=c(g);b>0&&(g-=b,p=s(g),p<0&&(g-=p))}return g},confineVertically:g=>{let p=u(g);if(p<0)g-=p;else{const b=d(g);b>0&&(g-=b,p=u(g),p<0&&(g-=p))}return g}}},zH=({arrowRef:e,menuY:t,anchorRect:n,containerRect:r,menuRect:o})=>{let i=n.top-r.top-t+n.height/2;const a=e.current.offsetHeight*1.25;return i=Math.max(a,i),i=Math.min(i,o.height-a),i},FH=({anchorRect:e,containerRect:t,menuRect:n,placeLeftorRightY:r,placeLeftX:o,placeRightX:i,getLeftOverflow:a,getRightOverflow:l,confineHorizontally:s,confineVertically:c,arrowRef:u,arrow:d,direction:v,position:h})=>{let g=v,p=r;h!=="initial"&&(p=c(p),h==="anchor"&&(p=Math.min(p,e.bottom-t.top),p=Math.max(p,e.top-t.top-n.height)));let b,m,y;return g==="left"?(b=o,h!=="initial"&&(m=a(b),m<0&&(y=l(i),(y<=0||-m>y)&&(b=i,g="right")))):(b=i,h!=="initial"&&(y=l(b),y>0&&(m=a(o),(m>=0||-m{let i=n.left-r.left-t+n.width/2;const a=e.current.offsetWidth*1.25;return i=Math.max(a,i),i=Math.min(i,o.width-a),i},BH=({anchorRect:e,containerRect:t,menuRect:n,placeToporBottomX:r,placeTopY:o,placeBottomY:i,getTopOverflow:a,getBottomOverflow:l,confineHorizontally:s,confineVertically:c,arrowRef:u,arrow:d,direction:v,position:h})=>{let g=v==="top"?"top":"bottom",p=r;h!=="initial"&&(p=s(p),h==="anchor"&&(p=Math.min(p,e.right-t.left),p=Math.max(p,e.left-t.left-n.width)));let b,m,y;return g==="top"?(b=o,h!=="initial"&&(m=a(b),m<0&&(y=l(i),(y<=0||-m>y)&&(b=i,g="bottom")))):(b=i,h!=="initial"&&(y=l(b),y>0&&(m=a(o),(m>=0||-m{const{menuRect:c,containerRect:u}=s,d=n==="left"||n==="right";let v=d?r:o,h=d?o:r;if(e){const $=l.current;d?v+=$.offsetWidth:h+=$.offsetHeight}const g=a.left-u.left-c.width-v,p=a.right-u.left+v,b=a.top-u.top-c.height-h,m=a.bottom-u.top+h;let y,S;t==="end"?(y=a.right-u.left-c.width,S=a.bottom-u.top-c.height):t==="center"?(y=a.left-u.left-(c.width-a.width)/2,S=a.top-u.top-(c.height-a.height)/2):(y=a.left-u.left,S=a.top-u.top),y+=v,S+=h;const x={...s,anchorRect:a,placeLeftX:g,placeRightX:p,placeLeftorRightY:S,placeTopY:b,placeBottomY:m,placeToporBottomX:y,arrowRef:l,arrow:e,direction:n,position:i};switch(n){case"left":case"right":return FH(x);case"top":case"bottom":default:return BH(x)}},fu=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u"?f.exports.useLayoutEffect:f.exports.useEffect;function w1(e,t){typeof e=="function"?e(t):e.current=t}const H$=(e,t)=>f.exports.useMemo(()=>e?t?n=>{w1(e,n),w1(t,n)}:e:t,[e,t]),$1=-9999,HH=({ariaLabel:e,menuClassName:t,menuStyle:n,arrow:r,arrowProps:o={},anchorPoint:i,anchorRef:a,containerRef:l,containerProps:s,focusProps:c,externalRef:u,parentScrollingRef:d,align:v="start",direction:h="bottom",position:g="auto",overflow:p="visible",setDownOverflow:b,repositionFlag:m,captureFocus:y=!0,state:S,endTransition:x,isDisabled:$,menuItemFocus:E,gap:w=0,shift:R=0,children:P,onClose:N,...I})=>{const[z,F]=f.exports.useState({x:$1,y:$1}),[T,D]=f.exports.useState({}),[_,O]=f.exports.useState(),[M,L]=f.exports.useState(h),[A]=f.exports.useState(AH),[B,k]=f.exports.useReducer(Ue=>Ue+1,1),{transition:j,boundingBoxRef:H,boundingBoxPadding:W,rootMenuRef:Y,rootAnchorRef:K,scrollNodesRef:q,reposition:ee,viewScroll:Z,submenuCloseDelay:Q}=f.exports.useContext(zm),{submenuCtx:ne,reposSubmenu:ae=m}=f.exports.useContext(S1),J=f.exports.useRef(null),re=f.exports.useRef(),fe=f.exports.useRef(),ve=f.exports.useRef(!1),pe=f.exports.useRef({width:0,height:0}),oe=f.exports.useRef(()=>{}),{hoverItem:se,dispatch:le,updateItems:Ce}=DH(J,re),ce=MH(S),de=_g(j,"open"),xe=_g(j,"close"),he=q.current,ke=Ue=>{switch(Ue.key){case co.HOME:le(rn.FIRST);break;case co.END:le(rn.LAST);break;case co.UP:le(rn.DECREASE,se);break;case co.DOWN:le(rn.INCREASE,se);break;case co.SPACE:Ue.target&&Ue.target.className.indexOf(du)!==-1&&Ue.preventDefault();return;default:return}Ue.preventDefault(),Ue.stopPropagation()},we=()=>{S==="closing"&&O(),kr(x)},ge=Ue=>{Ue.stopPropagation(),A.on(Q,()=>{le(rn.RESET),re.current.focus()})},Pe=Ue=>{Ue.target===Ue.currentTarget&&A.off()},Se=f.exports.useCallback(Ue=>{var He;const Xe=a?(He=a.current)==null?void 0:He.getBoundingClientRect():i?{left:i.x,right:i.x,top:i.y,bottom:i.y,width:0,height:0}:null;if(!Xe)return;he.menu||(he.menu=(H?H.current:Pv(Y.current))||window);const Le=LH(l,J,he.menu,W);let{arrowX:Re,arrowY:be,x:Ae,y:Me,computedDirection:$e}=jH({arrow:r,align:v,direction:h,gap:w,shift:R,position:g,anchorRect:Xe,arrowRef:fe,positionHelpers:Le});const{menuRect:Te}=Le;let ye=Te.height;if(!Ue&&p!=="visible"){const{getTopOverflow:Ge,getBottomOverflow:Ze}=Le;let et,ht;const mt=pe.current.height,ct=Ze(Me);if(ct>0||aa(ct,0)&&aa(ye,mt))et=ye-ct,ht=ct;else{const We=Ge(Me);(We<0||aa(We,0)&&aa(ye,mt))&&(et=ye+We,ht=0-We,et>=0&&(Me-=We))}et>=0?(ye=et,O({height:et,overflowAmt:ht})):O()}r&&D({x:Re,y:be}),F({x:Ae,y:Me}),L($e),pe.current={width:Te.width,height:ye}},[r,v,W,h,w,R,g,p,i,a,l,H,Y,he]);fu(()=>{ce&&(Se(),ve.current&&k()),ve.current=ce,oe.current=Se},[ce,Se,ae]),fu(()=>{_&&!b&&(J.current.scrollTop=0)},[_,b]),fu(()=>Ce,[Ce]),f.exports.useEffect(()=>{let{menu:Ue}=he;if(!ce||!Ue)return;if(Ue=Ue.addEventListener?Ue:window,!he.anchors){he.anchors=[];let Re=Pv(K&&K.current);for(;Re&&Re!==Ue;)he.anchors.push(Re),Re=Pv(Re)}let He=Z;if(he.anchors.length&&He==="initial"&&(He="auto"),He==="initial")return;const Xe=()=>{He==="auto"?y1(()=>Se(!0)):kr(N,{reason:Ns.SCROLL})},Le=he.anchors.concat(Z!=="initial"?Ue:[]);return Le.forEach(Re=>Re.addEventListener("scroll",Xe)),()=>Le.forEach(Re=>Re.removeEventListener("scroll",Xe))},[K,he,ce,N,Z,Se]);const st=!!_&&_.overflowAmt>0;f.exports.useEffect(()=>{if(st||!ce||!d)return;const Ue=()=>y1(Se),He=d.current;return He.addEventListener("scroll",Ue),()=>He.removeEventListener("scroll",Ue)},[ce,st,d,Se]),f.exports.useEffect(()=>{if(typeof ResizeObserver!="function"||ee==="initial")return;const Ue=new ResizeObserver(([Xe])=>{const{borderBoxSize:Le,target:Re}=Xe;let be,Ae;if(Le){const{inlineSize:Me,blockSize:$e}=Le[0]||Le;be=Me,Ae=$e}else{const Me=Re.getBoundingClientRect();be=Me.width,Ae=Me.height}be===0||Ae===0||aa(be,pe.current.width,1)&&aa(Ae,pe.current.height,1)||Gn.exports.flushSync(()=>{oe.current(),k()})}),He=J.current;return Ue.observe(He,{box:"border-box"}),()=>Ue.unobserve(He)},[ee]),f.exports.useEffect(()=>{if(!ce){le(rn.RESET),xe||O();return}const{position:Ue,alwaysUpdate:He}=E||{},Xe=()=>{Ue===C1.FIRST?le(rn.FIRST):Ue===C1.LAST?le(rn.LAST):Ue>=-1&&le(rn.SET_INDEX,void 0,Ue)};if(He)Xe();else if(y){const Le=setTimeout(()=>{const Re=J.current;Re&&!Re.contains(document.activeElement)&&(re.current.focus(),Xe())},de?170:100);return()=>clearTimeout(Le)}},[ce,de,xe,y,E,le]);const nt=f.exports.useMemo(()=>({isParentOpen:ce,submenuCtx:A,dispatch:le,updateItems:Ce}),[ce,A,le,Ce]);let Ne,Ee;_&&(b?Ee=_.overflowAmt:Ne=_.height);const _e=f.exports.useMemo(()=>({reposSubmenu:B,submenuCtx:A,overflow:p,overflowAmt:Ee,parentMenuRef:J,parentDir:M}),[B,A,p,Ee,M]),Be=Ne>=0?{maxHeight:Ne,overflow:p}:void 0,qe=f.exports.useMemo(()=>({state:S,dir:M}),[S,M]),it=f.exports.useMemo(()=>({dir:M}),[M]),ft=sd({block:du,element:IH,modifiers:it,className:o.className}),ut=ie("ul",{role:"menu","aria-label":e,...z$($),...Lm({onPointerEnter:ne==null?void 0:ne.off,onPointerMove:ge,onPointerLeave:Pe,onKeyDown:ke,onAnimationEnd:we},I),ref:H$(u,J),className:sd({block:du,modifiers:qe,className:t}),style:{...n,...Be,margin:0,display:S==="closed"?"none":void 0,position:Tv,left:z.x,top:z.y},children:[C("li",{tabIndex:-1,style:{position:Tv,left:0,top:0,display:"block",outline:"none"},ref:re,...x1,...c}),r&&C("li",{...x1,...o,className:ft,style:{display:"block",position:Tv,left:T.x,top:T.y,...o.style},ref:fe}),C(S1.Provider,{value:_e,children:C(k$.Provider,{value:nt,children:C(F$.Provider,{value:se,children:kr(P,qe)})})})]});return s?C(_H,{...s,isOpen:ce,children:ut}):ut},W$=f.exports.forwardRef(function({"aria-label":t,className:n,containerProps:r,initialMounted:o,unmountOnClose:i,transition:a,transitionTimeout:l,boundingBoxRef:s,boundingBoxPadding:c,reposition:u="auto",submenuOpenDelay:d=300,submenuCloseDelay:v=150,viewScroll:h="initial",portal:g,theming:p,onItemClick:b,...m},y){const S=f.exports.useRef(null),x=f.exports.useRef({}),{anchorRef:$,state:E,onClose:w}=m,R=f.exports.useMemo(()=>({initialMounted:o,unmountOnClose:i,transition:a,transitionTimeout:l,boundingBoxRef:s,boundingBoxPadding:c,rootMenuRef:S,rootAnchorRef:$,scrollNodesRef:x,reposition:u,viewScroll:h,submenuOpenDelay:d,submenuCloseDelay:v}),[o,i,a,l,$,s,c,u,h,d,v]),P=f.exports.useMemo(()=>({handleClick(I,z){I.stopPropagation||kr(b,I);let F=I.keepOpen;F===void 0&&(F=z&&I.key===co.SPACE),F||kr(w,{value:I.value,key:I.key,reason:Ns.CLICK})},handleClose(I){kr(w,{key:I,reason:Ns.CLICK})}}),[b,w]);if(!E)return null;const N=C(zm.Provider,{value:R,children:C(B$.Provider,{value:P,children:C(HH,{...m,ariaLabel:t||"Menu",externalRef:y,containerRef:S,containerProps:{className:n,containerRef:S,containerProps:r,theming:p,transition:a,onClose:w}})})});return g===!0&&typeof document<"u"?Gn.exports.createPortal(N,document.body):g?g.target?Gn.exports.createPortal(N,g.target):g.stablePosition?null:N:N}),WH=(e,t)=>{const n=f.exports.memo(t),r=f.exports.forwardRef((o,i)=>{const a=f.exports.useRef(null);return C(n,{...o,itemRef:a,externalRef:i,isHovering:f.exports.useContext(F$)===a.current})});return r.displayName=`WithHovering(${e})`,r},VH=(e,t,n)=>{fu(()=>{if(e)return;const r=t.current;return n(r,!0),()=>{n(r)}},[e,t,n])},UH=(e,t,n,r)=>{const{submenuCloseDelay:o}=f.exports.useContext(zm),{isParentOpen:i,submenuCtx:a,dispatch:l,updateItems:s}=f.exports.useContext(k$),c=()=>{!n&&!r&&l(rn.SET,e.current)},u=()=>{!r&&l(rn.UNSET,e.current)},d=g=>{n&&!g.currentTarget.contains(g.relatedTarget)&&u()},v=g=>{r||(g.stopPropagation(),a.on(o,c,c))},h=(g,p)=>{a.off(),!p&&u()};return VH(r,e,s),f.exports.useEffect(()=>{n&&i&&t.current&&t.current.focus()},[t,n,i]),{setHover:c,onBlur:d,onPointerMove:v,onPointerLeave:h}},cd=WH("MenuItem",function({className:t,value:n,href:r,type:o,checked:i,disabled:a,children:l,onClick:s,isHovering:c,itemRef:u,externalRef:d,...v}){const h=!!a,{setHover:g,...p}=UH(u,u,c,h),b=f.exports.useContext(B$),m=f.exports.useContext(TH),y=o==="radio",S=o==="checkbox",x=!!r&&!h&&!y&&!S,$=y?m.value===n:S?!!i:!1,E=I=>{if(h){I.stopPropagation(),I.preventDefault();return}const z={value:n,syntheticEvent:I};I.key!==void 0&&(z.key=I.key),S&&(z.checked=!$),y&&(z.name=m.name),kr(s,z),y&&kr(m.onRadioChange,z),b.handleClick(z,S||y)},w=I=>{if(!!c)switch(I.key){case co.ENTER:I.preventDefault();case co.SPACE:x?u.current.click():E(I)}},R=f.exports.useMemo(()=>({type:o,disabled:h,hover:c,checked:$,anchor:x}),[o,h,c,$,x]),P=Lm({...p,onPointerDown:g,onKeyDown:w,onClick:E},v),N={role:y?"menuitemradio":S?"menuitemcheckbox":j$,"aria-checked":y||S?$:void 0,...z$(h,c),...P,ref:H$(d,u),className:sd({block:du,element:PH,modifiers:R,className:t}),children:f.exports.useMemo(()=>kr(l,R),[l,R])};return x?C("li",{role:NH,children:C("a",{href:r,...N})}):C("li",{...N})});var V$={exports:{}};/*!
+ * clipboard.js v2.0.11
+ * https://clipboardjs.com/
+ *
+ * Licensed MIT © Zeno Rocha
+ */(function(e,t){(function(r,o){e.exports=o()})(Hr,function(){return function(){var n={686:function(i,a,l){l.d(a,{default:function(){return B}});var s=l(279),c=l.n(s),u=l(370),d=l.n(u),v=l(817),h=l.n(v);function g(k){try{return document.execCommand(k)}catch{return!1}}var p=function(j){var H=h()(j);return g("cut"),H},b=p;function m(k){var j=document.documentElement.getAttribute("dir")==="rtl",H=document.createElement("textarea");H.style.fontSize="12pt",H.style.border="0",H.style.padding="0",H.style.margin="0",H.style.position="absolute",H.style[j?"right":"left"]="-9999px";var W=window.pageYOffset||document.documentElement.scrollTop;return H.style.top="".concat(W,"px"),H.setAttribute("readonly",""),H.value=k,H}var y=function(j,H){var W=m(j);H.container.appendChild(W);var Y=h()(W);return g("copy"),W.remove(),Y},S=function(j){var H=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},W="";return typeof j=="string"?W=y(j,H):j instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(j==null?void 0:j.type)?W=y(j.value,H):(W=h()(j),g("copy")),W},x=S;function $(k){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?$=function(H){return typeof H}:$=function(H){return H&&typeof Symbol=="function"&&H.constructor===Symbol&&H!==Symbol.prototype?"symbol":typeof H},$(k)}var E=function(){var j=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},H=j.action,W=H===void 0?"copy":H,Y=j.container,K=j.target,q=j.text;if(W!=="copy"&&W!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(K!==void 0)if(K&&$(K)==="object"&&K.nodeType===1){if(W==="copy"&&K.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(W==="cut"&&(K.hasAttribute("readonly")||K.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(q)return x(q,{container:Y});if(K)return W==="cut"?b(K):x(K,{container:Y})},w=E;function R(k){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?R=function(H){return typeof H}:R=function(H){return H&&typeof Symbol=="function"&&H.constructor===Symbol&&H!==Symbol.prototype?"symbol":typeof H},R(k)}function P(k,j){if(!(k instanceof j))throw new TypeError("Cannot call a class as a function")}function N(k,j){for(var H=0;H"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch{return!1}}function M(k){return M=Object.setPrototypeOf?Object.getPrototypeOf:function(H){return H.__proto__||Object.getPrototypeOf(H)},M(k)}function L(k,j){var H="data-clipboard-".concat(k);if(!!j.hasAttribute(H))return j.getAttribute(H)}var A=function(k){z(H,k);var j=T(H);function H(W,Y){var K;return P(this,H),K=j.call(this),K.resolveOptions(Y),K.listenClick(W),K}return I(H,[{key:"resolveOptions",value:function(){var Y=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof Y.action=="function"?Y.action:this.defaultAction,this.target=typeof Y.target=="function"?Y.target:this.defaultTarget,this.text=typeof Y.text=="function"?Y.text:this.defaultText,this.container=R(Y.container)==="object"?Y.container:document.body}},{key:"listenClick",value:function(Y){var K=this;this.listener=d()(Y,"click",function(q){return K.onClick(q)})}},{key:"onClick",value:function(Y){var K=Y.delegateTarget||Y.currentTarget,q=this.action(K)||"copy",ee=w({action:q,container:this.container,target:this.target(K),text:this.text(K)});this.emit(ee?"success":"error",{action:q,text:ee,trigger:K,clearSelection:function(){K&&K.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(Y){return L("action",Y)}},{key:"defaultTarget",value:function(Y){var K=L("target",Y);if(K)return document.querySelector(K)}},{key:"defaultText",value:function(Y){return L("text",Y)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(Y){var K=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return x(Y,K)}},{key:"cut",value:function(Y){return b(Y)}},{key:"isSupported",value:function(){var Y=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],K=typeof Y=="string"?[Y]:Y,q=!!document.queryCommandSupported;return K.forEach(function(ee){q=q&&!!document.queryCommandSupported(ee)}),q}}]),H}(c()),B=A},828:function(i){var a=9;if(typeof Element<"u"&&!Element.prototype.matches){var l=Element.prototype;l.matches=l.matchesSelector||l.mozMatchesSelector||l.msMatchesSelector||l.oMatchesSelector||l.webkitMatchesSelector}function s(c,u){for(;c&&c.nodeType!==a;){if(typeof c.matches=="function"&&c.matches(u))return c;c=c.parentNode}}i.exports=s},438:function(i,a,l){var s=l(828);function c(v,h,g,p,b){var m=d.apply(this,arguments);return v.addEventListener(g,m,b),{destroy:function(){v.removeEventListener(g,m,b)}}}function u(v,h,g,p,b){return typeof v.addEventListener=="function"?c.apply(null,arguments):typeof g=="function"?c.bind(null,document).apply(null,arguments):(typeof v=="string"&&(v=document.querySelectorAll(v)),Array.prototype.map.call(v,function(m){return c(m,h,g,p,b)}))}function d(v,h,g,p){return function(b){b.delegateTarget=s(b.target,h),b.delegateTarget&&p.call(v,b)}}i.exports=u},879:function(i,a){a.node=function(l){return l!==void 0&&l instanceof HTMLElement&&l.nodeType===1},a.nodeList=function(l){var s=Object.prototype.toString.call(l);return l!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in l&&(l.length===0||a.node(l[0]))},a.string=function(l){return typeof l=="string"||l instanceof String},a.fn=function(l){var s=Object.prototype.toString.call(l);return s==="[object Function]"}},370:function(i,a,l){var s=l(879),c=l(438);function u(g,p,b){if(!g&&!p&&!b)throw new Error("Missing required arguments");if(!s.string(p))throw new TypeError("Second argument must be a String");if(!s.fn(b))throw new TypeError("Third argument must be a Function");if(s.node(g))return d(g,p,b);if(s.nodeList(g))return v(g,p,b);if(s.string(g))return h(g,p,b);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function d(g,p,b){return g.addEventListener(p,b),{destroy:function(){g.removeEventListener(p,b)}}}function v(g,p,b){return Array.prototype.forEach.call(g,function(m){m.addEventListener(p,b)}),{destroy:function(){Array.prototype.forEach.call(g,function(m){m.removeEventListener(p,b)})}}}function h(g,p,b){return c(document.body,g,p,b)}i.exports=u},817:function(i){function a(l){var s;if(l.nodeName==="SELECT")l.focus(),s=l.value;else if(l.nodeName==="INPUT"||l.nodeName==="TEXTAREA"){var c=l.hasAttribute("readonly");c||l.setAttribute("readonly",""),l.select(),l.setSelectionRange(0,l.value.length),c||l.removeAttribute("readonly"),s=l.value}else{l.hasAttribute("contenteditable")&&l.focus();var u=window.getSelection(),d=document.createRange();d.selectNodeContents(l),u.removeAllRanges(),u.addRange(d),s=u.toString()}return s}i.exports=a},279:function(i){function a(){}a.prototype={on:function(l,s,c){var u=this.e||(this.e={});return(u[l]||(u[l]=[])).push({fn:s,ctx:c}),this},once:function(l,s,c){var u=this;function d(){u.off(l,d),s.apply(c,arguments)}return d._=s,this.on(l,d,c)},emit:function(l){var s=[].slice.call(arguments,1),c=((this.e||(this.e={}))[l]||[]).slice(),u=0,d=c.length;for(u;u{const l=new YH(".CardMessageLink-Copy");return()=>{l.destroy()}},[]);const[t,n]=f.exports.useState(!1),[r,o]=f.exports.useState({x:0,y:0}),i=l=>{typeof document.hasFocus=="function"&&!document.hasFocus()||(l.preventDefault(),o({x:l.clientX,y:l.clientY}),n(!0))},a=()=>{i9(e.info.Url)};return ie("div",{className:"CardMessage CardMessageLink",size:"small",onDoubleClick:a,onContextMenu:i,children:[C("div",{className:"CardMessage-Title",children:e.info.Title}),ie("div",{className:"CardMessage-Content",children:[C("div",{className:"CardMessage-Desc",children:e.info.Description}),C(cu,{className:"CardMessageLink-Image",src:e.image,height:45,width:45,preview:!1,fallback:C9})]}),C("div",{className:e.info.DisPlayName===""?"CardMessageLink-Line-None":"CardMessageLink-Line"}),C("div",{className:"CardMessageLink-Name",children:e.info.DisPlayName}),ie(W$,{anchorPoint:r,state:t?"open":"closed",direction:"right",onClose:()=>n(!1),menuClassName:"CardMessage-Menu",children:[C(cd,{onClick:a,children:"\u6253\u5F00"}),C(cd,{className:"CardMessageLink-Copy",onClick:()=>handleOpenFile("fiexplorerle"),"data-clipboard-text":e.info.Url,children:"\u590D\u5236\u94FE\u63A5"})]})]})}function qH(e){const[t,n]=f.exports.useState(!1),[r,o]=f.exports.useState(!1),[i,a]=f.exports.useState({x:0,y:0}),l=u=>{typeof document.hasFocus=="function"&&!document.hasFocus()||(u.preventDefault(),a({x:u.clientX,y:u.clientY}),o(!0))},s=u=>{JB(e.info.filePath,u==="explorer").then(d=>{JSON.parse(d).status==="failed"&&n(!0)})},c=({hover:u})=>u?"CardMessage-Menu-hover":"CardMessage-Menu";return ie("div",{className:"CardMessage CardMessageFile",size:"small",onDoubleClick:()=>s("file"),onContextMenu:l,children:[C("div",{className:"CardMessage-Title",children:e.info.fileName}),ie("div",{className:"CardMessage-Content",children:[ie("div",{className:"CardMessage-Desc",children:[e.info.fileSize,C("span",{className:"CardMessage-Desc-Span",children:t?"\u6587\u4EF6\u4E0D\u5B58\u5728":""})]}),C("div",{className:"CardMessageFile-Icon",children:C(cx,{})})]}),ie(W$,{anchorPoint:i,state:r?"open":"closed",direction:"right",onClose:()=>o(!1),menuClassName:"CardMessage-Menu",children:[C(cd,{className:c,onClick:()=>s("file"),children:"\u6253\u5F00"}),C(cd,{className:c,onClick:()=>s("fiexplorerle"),children:"\u5728\u6587\u4EF6\u5939\u4E2D\u663E\u793A"})]})]})}function XH(e){let t=null,n=null;switch(e.info.Type){case Fm:switch(e.info.SubType){case Q$:n=C(cx,{});break;case X$:n=C(mP,{});break}case U$:t=ie("div",{className:"MessageRefer-Content-Text",children:[e.info.Displayname,":",n,e.info.Content]});break;case q$:t=C(v4,{});break;case Y$:t=C(LP,{});break;case K$:t=C(S4,{});break;case G$:t=C(RI,{});break;default:t=ie("div",{children:["\u672A\u77E5\u7684\u5F15\u7528\u7C7B\u578B ID:",e.info.Svrid,"Type:",e.info.Type]})}return ie("div",{className:e.position==="left"?"MessageRefer-Left":"MessageRefer-Right",children:[C(Dm,{className:"MessageRefer-MessageText",text:e.content}),C("div",{className:"MessageRefer-Content",children:t})]})}function J$(e){switch(e.content.type){case U$:return C(Dm,{text:e.content.content});case Y$:return C(cu,{src:e.content.ThumbPath,preview:{src:e.content.ImagePath}});case K$:return C(cu,{src:e.content.ThumbPath,preview:{imageRender:(t,n)=>C("video",{className:"video_view",height:"100%",width:"100%",controls:!0,src:e.content.VideoPath}),onVisibleChange:(t,n,r)=>{t===!1&&n===!0&&document.getElementsByClassName("video_view")[0].pause()}}});case G$:return C(m$,{className:"CardMessageText",children:C("audio",{className:"CardMessageAudio",controls:!0,src:e.content.VoicePath})});case q$:return C(cu,{src:e.content.EmojiPath,height:"110px",width:"110px",preview:!1,fallback:x9});case GH:return C("div",{className:"System-Text",children:e.content.content});case Fm:switch(e.content.SubType){case X$:return C(KH,{info:e.content.LinkInfo,image:e.content.ThumbPath,tmp:e.content.MsgSvrId});case Z$:return C(XH,{content:e.content.content,info:e.content.ReferInfo,position:e.content.IsSender?"right":"left"});case Q$:return C(qH,{info:e.content.fileInfo})}default:return ie("div",{children:["ID: ",e.content.LocalId,"\u672A\u77E5\u7C7B\u578B: ",e.content.type," \u5B50\u7C7B\u578B: ",e.content.SubType]})}}function QH(e){let t=J$(e);return e.content.type==Fm&&e.content.SubType==Z$&&(t=C(Dm,{text:e.content.content})),t}function ZH(e){return C(Tt,{children:e.selectTag===""?C(_d,{}):ie("div",{className:"SearchInputIcon",children:[C($I,{className:"SearchInputIcon-size SearchInputIcon-first"}),C("div",{className:"SearchInputIcon-size SearchInputIcon-second",children:e.selectTag}),C(eo,{className:"SearchInputIcon-size SearchInputIcon-third",onClick:()=>e.onClickClose()})]})})}function eE(e){const t=r=>{e.onChange&&e.onChange(r.target.value)},n=r=>{r.stopPropagation()};return C("div",{className:"wechat-SearchInput",children:C(ai,{theme:{components:{Input:{activeBorderColor:"#E3E4E5",activeShadow:"#E3E4E5",hoverBorderColor:"#E3E4E5"}}},children:C(C$,{className:"wechat-SearchInput-Input",placeholder:e.selectTag===""?"\u641C\u7D22":"",prefix:C(ZH,{selectTag:e.selectTag,onClickClose:()=>e.onClickClose()}),allowClear:!0,onChange:t,onClick:n})})})}function JH(e){const t=f.exports.useMemo(()=>e.renderMessageContent(e.message),[e.message]);return ie("div",{className:"MessageBubble RecordsUi-MessageBubble",onDoubleClick:()=>{e.onDoubleClick&&e.onDoubleClick(e.message)},children:[C("time",{className:"Time",dateTime:Lt(e.message.createdAt).format(),children:Lt(e.message.createdAt*1e3).format("YYYY\u5E74M\u6708D\u65E5 HH:mm")}),ie("div",{className:"MessageBubble-content-left",children:[C("div",{className:"MessageBubble-content-Avatar",children:C(Yo,{className:"MessageBubble-Avatar-left",src:e.message.user.avatar,size:{xs:40,sm:40,md:40,lg:40,xl:40,xxl:40},shape:"square",alt:"\u65E0\u6CD5\u52A0\u8F7D\u5934\u50CF"})}),ie("div",{className:"Bubble-left",children:[C("div",{className:"MessageBubble-Name-left",truncate:1,children:e.message.user.name}),t]})]})]})}function eW(e){const t=f.exports.useRef(0),n=f.exports.useRef(null),r=i=>{i.srcElement.scrollTop===0?(t.current=i.srcElement.scrollHeight,n.current=i.srcElement,e.atBottom&&e.atBottom()):(t.current=0,n.current=null)};function o(){e.next()}return f.exports.useEffect(()=>{t.current!==0&&n.current&&(n.current.scrollTop=-(n.current.scrollHeight-t.current),t.current=0,n.current=null)},[e.messages]),C("div",{id:"RecordsUiscrollableDiv",children:C(D$,{scrollableTarget:"RecordsUiscrollableDiv",dataLength:e.messages.length,next:o,hasMore:e.hasMore,inverse:!0,onScroll:r,children:e.messages.map(i=>C(JH,{message:i,renderMessageContent:e.renderMessageContent,onDoubleClick:e.onDoubleClick},i.key))})})}function tW(e){return C("div",{className:"RecordsUi",children:C(eW,{messages:e.messages,next:e.fetchMoreData,hasMore:e.hasMore,renderMessageContent:e.renderMessageContent,atBottom:e.atBottom,onDoubleClick:e.onDoubleClick})})}var nW={locale:"zh_CN",yearFormat:"YYYY\u5E74",cellDateFormat:"D",cellMeridiemFormat:"A",today:"\u4ECA\u5929",now:"\u6B64\u523B",backToToday:"\u8FD4\u56DE\u4ECA\u5929",ok:"\u786E\u5B9A",timeSelect:"\u9009\u62E9\u65F6\u95F4",dateSelect:"\u9009\u62E9\u65E5\u671F",weekSelect:"\u9009\u62E9\u5468",clear:"\u6E05\u9664",month:"\u6708",year:"\u5E74",previousMonth:"\u4E0A\u4E2A\u6708 (\u7FFB\u9875\u4E0A\u952E)",nextMonth:"\u4E0B\u4E2A\u6708 (\u7FFB\u9875\u4E0B\u952E)",monthSelect:"\u9009\u62E9\u6708\u4EFD",yearSelect:"\u9009\u62E9\u5E74\u4EFD",decadeSelect:"\u9009\u62E9\u5E74\u4EE3",previousYear:"\u4E0A\u4E00\u5E74 (Control\u952E\u52A0\u5DE6\u65B9\u5411\u952E)",nextYear:"\u4E0B\u4E00\u5E74 (Control\u952E\u52A0\u53F3\u65B9\u5411\u952E)",previousDecade:"\u4E0A\u4E00\u5E74\u4EE3",nextDecade:"\u4E0B\u4E00\u5E74\u4EE3",previousCentury:"\u4E0A\u4E00\u4E16\u7EAA",nextCentury:"\u4E0B\u4E00\u4E16\u7EAA"};const rW={placeholder:"\u8BF7\u9009\u62E9\u65F6\u95F4",rangePlaceholder:["\u5F00\u59CB\u65F6\u95F4","\u7ED3\u675F\u65F6\u95F4"]},oW=rW,tE={lang:Object.assign({placeholder:"\u8BF7\u9009\u62E9\u65E5\u671F",yearPlaceholder:"\u8BF7\u9009\u62E9\u5E74\u4EFD",quarterPlaceholder:"\u8BF7\u9009\u62E9\u5B63\u5EA6",monthPlaceholder:"\u8BF7\u9009\u62E9\u6708\u4EFD",weekPlaceholder:"\u8BF7\u9009\u62E9\u5468",rangePlaceholder:["\u5F00\u59CB\u65E5\u671F","\u7ED3\u675F\u65E5\u671F"],rangeYearPlaceholder:["\u5F00\u59CB\u5E74\u4EFD","\u7ED3\u675F\u5E74\u4EFD"],rangeMonthPlaceholder:["\u5F00\u59CB\u6708\u4EFD","\u7ED3\u675F\u6708\u4EFD"],rangeQuarterPlaceholder:["\u5F00\u59CB\u5B63\u5EA6","\u7ED3\u675F\u5B63\u5EA6"],rangeWeekPlaceholder:["\u5F00\u59CB\u5468","\u7ED3\u675F\u5468"]},nW),timePickerLocale:Object.assign({},oW)};tE.lang.ok="\u786E\u5B9A";const iW=tE;var aW={exports:{}};(function(e,t){(function(n,r){e.exports=r($m.exports)})(Hr,function(n){function r(a){return a&&typeof a=="object"&&"default"in a?a:{default:a}}var o=r(n),i={name:"zh-cn",weekdays:"\u661F\u671F\u65E5_\u661F\u671F\u4E00_\u661F\u671F\u4E8C_\u661F\u671F\u4E09_\u661F\u671F\u56DB_\u661F\u671F\u4E94_\u661F\u671F\u516D".split("_"),weekdaysShort:"\u5468\u65E5_\u5468\u4E00_\u5468\u4E8C_\u5468\u4E09_\u5468\u56DB_\u5468\u4E94_\u5468\u516D".split("_"),weekdaysMin:"\u65E5_\u4E00_\u4E8C_\u4E09_\u56DB_\u4E94_\u516D".split("_"),months:"\u4E00\u6708_\u4E8C\u6708_\u4E09\u6708_\u56DB\u6708_\u4E94\u6708_\u516D\u6708_\u4E03\u6708_\u516B\u6708_\u4E5D\u6708_\u5341\u6708_\u5341\u4E00\u6708_\u5341\u4E8C\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),ordinal:function(a,l){return l==="W"?a+"\u5468":a+"\u65E5"},weekStart:1,yearStart:4,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5E74M\u6708D\u65E5",LLL:"YYYY\u5E74M\u6708D\u65E5Ah\u70B9mm\u5206",LLLL:"YYYY\u5E74M\u6708D\u65E5ddddAh\u70B9mm\u5206",l:"YYYY/M/D",ll:"YYYY\u5E74M\u6708D\u65E5",lll:"YYYY\u5E74M\u6708D\u65E5 HH:mm",llll:"YYYY\u5E74M\u6708D\u65E5dddd HH:mm"},relativeTime:{future:"%s\u5185",past:"%s\u524D",s:"\u51E0\u79D2",m:"1 \u5206\u949F",mm:"%d \u5206\u949F",h:"1 \u5C0F\u65F6",hh:"%d \u5C0F\u65F6",d:"1 \u5929",dd:"%d \u5929",M:"1 \u4E2A\u6708",MM:"%d \u4E2A\u6708",y:"1 \u5E74",yy:"%d \u5E74"},meridiem:function(a,l){var s=100*a+l;return s<600?"\u51CC\u6668":s<900?"\u65E9\u4E0A":s<1100?"\u4E0A\u5348":s<1300?"\u4E2D\u5348":s<1800?"\u4E0B\u5348":"\u665A\u4E0A"}};return o.default.locale(i,null,!0),i})})(aW);var nE={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(Hr,function(){var n="minute",r=/[+-]\d\d(?::?\d\d)?/g,o=/([+-]|\d\d)/g;return function(i,a,l){var s=a.prototype;l.utc=function(p){var b={date:p,utc:!0,args:arguments};return new a(b)},s.utc=function(p){var b=l(this.toDate(),{locale:this.$L,utc:!0});return p?b.add(this.utcOffset(),n):b},s.local=function(){return l(this.toDate(),{locale:this.$L,utc:!1})};var c=s.parse;s.parse=function(p){p.utc&&(this.$u=!0),this.$utils().u(p.$offset)||(this.$offset=p.$offset),c.call(this,p)};var u=s.init;s.init=function(){if(this.$u){var p=this.$d;this.$y=p.getUTCFullYear(),this.$M=p.getUTCMonth(),this.$D=p.getUTCDate(),this.$W=p.getUTCDay(),this.$H=p.getUTCHours(),this.$m=p.getUTCMinutes(),this.$s=p.getUTCSeconds(),this.$ms=p.getUTCMilliseconds()}else u.call(this)};var d=s.utcOffset;s.utcOffset=function(p,b){var m=this.$utils().u;if(m(p))return this.$u?0:m(this.$offset)?d.call(this):this.$offset;if(typeof p=="string"&&(p=function($){$===void 0&&($="");var E=$.match(r);if(!E)return null;var w=(""+E[0]).match(o)||["-",0,0],R=w[0],P=60*+w[1]+ +w[2];return P===0?0:R==="+"?P:-P}(p),p===null))return this;var y=Math.abs(p)<=16?60*p:p,S=this;if(b)return S.$offset=y,S.$u=p===0,S;if(p!==0){var x=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();(S=this.local().add(y+x,n)).$offset=y,S.$x.$localOffset=x}else S=this.utc();return S};var v=s.format;s.format=function(p){var b=p||(this.$u?"YYYY-MM-DDTHH:mm:ss[Z]":"");return v.call(this,b)},s.valueOf=function(){var p=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*p},s.isUTC=function(){return!!this.$u},s.toISOString=function(){return this.toDate().toISOString()},s.toString=function(){return this.toDate().toUTCString()};var h=s.toDate;s.toDate=function(p){return p==="s"&&this.$offset?l(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate():h.call(this)};var g=s.diff;s.diff=function(p,b,m){if(p&&this.$u===p.$u)return g.call(this,p,b,m);var y=this.local(),S=l(p).local();return g.call(y,S,b,m)}}})})(nE);const lW=nE.exports;var rE={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(Hr,function(){var n={year:0,month:1,day:2,hour:3,minute:4,second:5},r={};return function(o,i,a){var l,s=function(v,h,g){g===void 0&&(g={});var p=new Date(v),b=function(m,y){y===void 0&&(y={});var S=y.timeZoneName||"short",x=m+"|"+S,$=r[x];return $||($=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:m,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:S}),r[x]=$),$}(h,g);return b.formatToParts(p)},c=function(v,h){for(var g=s(v,h),p=[],b=0;b=0&&(p[x]=parseInt(S,10))}var $=p[3],E=$===24?0:$,w=p[0]+"-"+p[1]+"-"+p[2]+" "+E+":"+p[4]+":"+p[5]+":000",R=+v;return(a.utc(w).valueOf()-(R-=R%1e3))/6e4},u=i.prototype;u.tz=function(v,h){v===void 0&&(v=l);var g=this.utcOffset(),p=this.toDate(),b=p.toLocaleString("en-US",{timeZone:v}),m=Math.round((p-new Date(b))/1e3/60),y=a(b,{locale:this.$L}).$set("millisecond",this.$ms).utcOffset(15*-Math.round(p.getTimezoneOffset()/15)-m,!0);if(h){var S=y.utcOffset();y=y.add(g-S,"minute")}return y.$x.$timezone=v,y},u.offsetName=function(v){var h=this.$x.$timezone||a.tz.guess(),g=s(this.valueOf(),h,{timeZoneName:v}).find(function(p){return p.type.toLowerCase()==="timezonename"});return g&&g.value};var d=u.startOf;u.startOf=function(v,h){if(!this.$x||!this.$x.$timezone)return d.call(this,v,h);var g=a(this.format("YYYY-MM-DD HH:mm:ss:SSS"),{locale:this.$L});return d.call(g,v,h).tz(this.$x.$timezone,!0)},a.tz=function(v,h,g){var p=g&&h,b=g||h||l,m=c(+a(),b);if(typeof v!="string")return a(v).tz(b);var y=function(E,w,R){var P=E-60*w*1e3,N=c(P,R);if(w===N)return[P,w];var I=c(P-=60*(N-w)*1e3,R);return N===I?[P,N]:[E-60*Math.min(N,I)*1e3,Math.max(N,I)]}(a.utc(v,p).valueOf(),m,b),S=y[0],x=y[1],$=a(S).utcOffset(x);return $.$x.$timezone=b,$},a.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},a.tz.setDefault=function(v){l=v}}})})(rE);const sW=rE.exports,cW=()=>C("div",{className:"CalendarLoading",children:C(oB,{tip:"\u52A0\u8F7D\u4E2D...",size:"large",children:C("div",{className:"content"})})}),uW=({info:e,selectDate:t})=>{const[n,r]=f.exports.useState([]),[o,i]=f.exports.useState(!0),a=f.exports.useRef(null);f.exports.useEffect(()=>{Lt.extend(lW),Lt.extend(sW),Lt.tz.setDefault()},[]),f.exports.useEffect(()=>{XB(e.UserName).then(c=>{r(JSON.parse(c).Date),i(!1)})},[e.UserName]);const l=c=>{for(let u=0;u{u.source==="date"&&(a.current=c,t&&t(c.valueOf()/1e3))};return C(Tt,{children:o?C(cW,{}):C(cF,{className:"CalendarChoose",disabledDate:l,fullscreen:!1,locale:iW,validRange:n.length>0?[Lt(n[n.length-1]),Lt(n[0])]:void 0,defaultValue:a.current?a.current:n.length>0?Lt(n[0]):void 0,onSelect:s})})};const dW=["\u6587\u4EF6","\u56FE\u7247\u4E0E\u89C6\u9891","\u94FE\u63A5","\u65E5\u671F"],fW=["\u6587\u4EF6","\u56FE\u7247\u4E0E\u89C6\u9891","\u94FE\u63A5","\u65E5\u671F","\u7FA4\u6210\u5458"];function vW(e){const[t,n]=f.exports.useState(!1),r=()=>{e.info.UserName&&n(!0)},o=()=>{n(!1)},{messages:i,prependMsgs:a,appendMsgs:l,setMsgs:s}=L$([]),[c,u]=f.exports.useState(!1),[d,v]=f.exports.useState(!0),[h,g]=f.exports.useState(""),[p,b]=f.exports.useState(""),[m,y]=f.exports.useState(1),[S,x]=f.exports.useState(!1),[$,E]=f.exports.useState(e.info.Time),[w,R]=f.exports.useState(!1),[P,N]=f.exports.useState("");f.exports.useEffect(()=>{e.info.UserName&&$>0&&p!="\u65E5\u671F"&&(u(!0),QB(e.info.UserName,$,h,p,30).then(A=>{let B=JSON.parse(A);B.Total==0&&(v(!1),i.length==0&&R(!0));let k=[];B.Rows.forEach(j=>{k.unshift({_id:j.MsgSvrId,content:j,position:j.type===1e4?"middle":j.IsSender===1?"right":"left",user:{avatar:j.userInfo.SmallHeadImgUrl,name:j.userInfo.ReMark===""?j.userInfo.NickName:j.userInfo.ReMark},createdAt:j.createTime,key:j.MsgSvrId})}),u(!1),a(k)}))},[e.info.UserName,$,h,p]);const I=()=>{Ts("fetchMoreData"),c||setTimeout(()=>{E(i[0].createdAt-1)},300)},z=A=>{console.log("onKeyWordChange",A),E(e.info.Time),s([]),y(m+1),g(A),R(!1)},F=f.exports.useCallback(oE(A=>{z(A)},600),[]),T=A=>{console.log("onFilterTag",A),A!=="\u7FA4\u6210\u5458"&&(s([]),y(m+1),E(e.info.Time),b(A),R(!1),x(A==="\u65E5\u671F"),N(""))},D=()=>{s([]),y(m+1),E(e.info.Time),b(""),R(!1),N("")},_=e.info.IsGroup?fW:dW,O=A=>{o(),e.onSelectMessage&&e.onSelectMessage(A)},M=A=>{o(),e.onSelectDate&&e.onSelectDate(A)},L=A=>{console.log(A),b("\u7FA4\u6210\u5458"+A.UserName),N(A.NickName),E(e.info.Time),s([]),y(m+1),g(""),R(!1),x(!1)};return ie("div",{children:[C("div",{onClick:r,children:e.children}),C(js,{className:"ChattingRecords-Modal",overlayClassName:"ChattingRecords-Modal-Overlay",isOpen:t,onRequestClose:o,children:ie("div",{className:"ChattingRecords-Modal-Body",children:[ie("div",{className:"ChattingRecords-Modal-Bar",children:[ie("div",{className:"ChattingRecords-Modal-Bar-Top",children:[C("div",{children:e.info.NickName}),C("div",{className:"ChattingRecords-Modal-Bar-button",title:"\u5173\u95ED",onClick:o,children:C(eo,{className:"ChattingRecords-Modal-Bar-button-icon"})})]}),C(eE,{onChange:F,selectTag:p.includes("\u7FA4\u6210\u5458")?"\u7FA4\u6210\u5458":p,onClickClose:D}),C("div",{className:"ChattingRecords-Modal-Bar-Tag",children:_.map(A=>C("div",{onClick:()=>T(A),children:A==="\u7FA4\u6210\u5458"?C(gW,{info:e.info,onClick:L,children:A}):A},Am()))})]}),S==!1?w?C(pW,{text:h!==""?h:P}):C(tW,{messages:i,fetchMoreData:I,hasMore:d&&!c,renderMessageContent:QH,onDoubleClick:O},m):C(uW,{info:e.info,selectDate:M})]})})]})}function oE(e,t){let n;return function(...r){n&&clearTimeout(n),n=setTimeout(()=>{e.apply(this,r)},t)}}const pW=({text:e})=>C("div",{className:"NotMessageContent",children:ie("div",{children:["\u6CA1\u6709\u627E\u5230\u4E0E",ie("span",{className:"NotMessageContent-keyword",children:['"',e,'"']}),"\u76F8\u5173\u7684\u8BB0\u5F55"]})}),gW=e=>{const[t,n]=f.exports.useState(!1),[r,o]=f.exports.useState(!0),[i,a]=f.exports.useState([]),[l,s]=f.exports.useState("");f.exports.useEffect(()=>{t&&qB(e.info.UserName).then(b=>{let m=JSON.parse(b);a(m.Users),o(!1)})},[e.info,t]);const c=b=>{b.stopPropagation(),console.log("showModal"),n(!0),o(!0)},u=b=>{n(!1)},d=b=>{s(b)},v=f.exports.useCallback(oE(b=>{d(b)},400),[]),h=()=>{},g=b=>{n(!1),e.onClick&&e.onClick(b)},p=i.filter(b=>b.NickName.includes(l));return ie("div",{className:"ChattingRecords-ChatRoomUserList-Parent",children:[C("div",{onClick:c,children:e.children}),ie(js,{className:"ChattingRecords-ChatRoomUserList",overlayClassName:"ChattingRecords-ChatRoomUserList-Overlay",isOpen:t,onRequestClose:u,children:[C(eE,{onChange:v,selectTag:"",onClickClose:h}),r?C("div",{className:"ChattingRecords-ChatRoomUserList-Loading",children:"\u52A0\u8F7D\u4E2D..."}):C(hW,{userList:p,onClick:g})]})]})},hW=e=>ie("div",{className:"ChattingRecords-ChatRoomUserList-List",children:[e.userList.map(t=>C(mW,{info:t,onClick:()=>e.onClick(t)},Am())),C("div",{className:"ChattingRecords-ChatRoomUserList-List-End",children:"- \u5DF2\u7ECF\u5230\u5E95\u5566 -"})]}),mW=e=>ie("div",{className:"ChattingRecords-ChatRoomUserList-User",onClick:n=>{n.stopPropagation(),e.onClick&&e.onClick()},children:[C(Yo,{className:"ChattingRecords-ChatRoomUserList-Avatar",src:e.info.SmallHeadImgUrl,size:{xs:35,sm:35,md:35,lg:35,xl:35,xxl:35},shape:"square",alt:"\u65E0\u6CD5\u52A0\u8F7D\u5934\u50CF"}),C("div",{className:"ChattingRecords-ChatRoomUserList-Name",children:e.info.NickName})]});function yW(e){const[t,n]=f.exports.useState(!1);return ie("div",{className:"wechat-UserDialog-Bar",children:[C("div",{className:"wechat-UserDialog-text wechat-UserDialog-name",children:e.name}),ie("div",{className:"wechat-UserDialog-Bar-button-block",children:[ie("div",{className:"wechat-UserDialog-Bar-button-list",children:[C("div",{className:"wechat-UserDialog-Bar-button",title:"\u6700\u5C0F\u5316",onClick:()=>e.onClickButton("min"),children:C(RP,{className:"wechat-UserDialog-Bar-button-icon"})}),C("div",{className:"wechat-UserDialog-Bar-button",title:t?"\u8FD8\u539F":"\u6700\u5927\u5316",onClick:()=>{n(!t),e.onClickButton("max")},children:t?C(NP,{className:"wechat-UserDialog-Bar-button-icon"}):C(VP,{className:"wechat-UserDialog-Bar-button-icon"})}),C("div",{className:"wechat-UserDialog-Bar-button",title:"\u5173\u95ED",onClick:()=>e.onClickButton("close"),children:C(eo,{className:"wechat-UserDialog-Bar-button-icon"})})]}),C(vW,{info:e.info,onSelectMessage:e.onSelectMessage,onSelectDate:e.onSelectDate,children:e.name===""?C(Tt,{}):C("div",{className:"wechat-UserDialog-Bar-button wechat-UserDialog-Bar-button-msg",title:"\u804A\u5929\u8BB0\u5F55",onClick:()=>e.onClickButton("msg"),children:C($P,{className:"wechat-UserDialog-Bar-button-icon2"})})})]})]})}function bW(e){const{messages:t,prependMsgs:n,appendMsgs:r,setMsgs:o}=L$([]),[i,a]=f.exports.useState(e.info.Time),[l,s]=f.exports.useState("forward"),[c,u]=f.exports.useState(!1),[d,v]=f.exports.useState(!0),[h,g]=f.exports.useState(1),[p,b]=f.exports.useState(""),[m,y]=f.exports.useState(0),S=f.exports.useDeferredValue(t);f.exports.useEffect(()=>{e.info.UserName&&i>0&&(u(!0),p1(e.info.UserName,i,30,l).then(R=>{let P=JSON.parse(R);P.Total==0&&l=="forward"&&v(!1),console.log(P.Total,l);let N=[];P.Rows.forEach(I=>{N.unshift({_id:I.MsgSvrId,content:I,position:I.type===1e4?"middle":I.IsSender===1?"right":"left",user:{avatar:I.userInfo.SmallHeadImgUrl,name:I.userInfo.ReMark===""?I.userInfo.NickName:I.userInfo.ReMark},createdAt:I.createTime,key:I.MsgSvrId})}),u(!1),l==="backward"?r(N):n(N)}))},[e.info.UserName,l,i]),f.exports.useEffect(()=>{e.info.UserName&&m>0&&(u(!0),p1(e.info.UserName,m,1,"backward").then(R=>{let P=JSON.parse(R);P.Rows.length==1&&(g(N=>N+1),o([]),a(P.Rows[0].createTime),s("both"),b(P.Rows[0].MsgSvrId)),u(!1)}))},[e.info.UserName,m]);const x=()=>{Ts("fetchMoreData"),c||setTimeout(()=>{a(t[0].createdAt-1),s("forward"),b("")},100)},$=()=>{Ts("fetchMoreDataDown"),c||setTimeout(()=>{a(t[t.length-1].createdAt+1),s("backward"),b("")},100)},E=R=>{g(P=>P+1),o([]),a(R.createdAt),s("both"),b(R.key)},w=R=>{y(R)};return ie("div",{className:"wechat-UserDialog",children:[C(yW,{name:e.info.NickName===null?"":e.info.NickName,onClickButton:e.onClickButton,info:e.info,onSelectMessage:E,onSelectDate:w}),C(S9,{messages:S,fetchMoreData:x,hasMore:d&&!c,renderMessageContent:J$,scrollIntoId:p,atBottom:$},h)]})}function SW(){const[e,t]=f.exports.useState(0),[n,r]=f.exports.useState(1),[o,i]=f.exports.useState(!1),[a,l]=f.exports.useState(null),[s,c]=f.exports.useState({}),u=v=>{Ts(v),v==="setting"?i(!0):v==="exit"&&(r(n+1),t(h=>h+1))},d=v=>{switch(v){case"min":o9();break;case"max":r9();break;case"close":a9();break}};return f.exports.useEffect(()=>{t(1)},[]),f.exports.useEffect(()=>{if(e!=0)return e9(),_$("selfInfo",v=>{l(JSON.parse(v))}),()=>{A$("selfInfo")}},[e]),ie("div",{id:"App",children:[C(g9,{onClickItem:v=>{console.log(v),u(v)},Avatar:a?a.SmallHeadImgUrl:""}),C(d9,{selfName:a?a.UserName:"",onClickItem:v=>{c(v),Ts("click: "+v.UserName)}},n),C(bW,{info:s,onClickButton:d},s.UserName)]})}const CW=document.getElementById("root"),xW=AC(CW);js.setAppElement("#root");xW.render(C(lt.StrictMode,{children:C(SW,{})}));
diff --git a/frontend/dist/assets/index.de7292ad.css b/frontend/dist/assets/index.de7292ad.css
new file mode 100644
index 0000000..65557f2
--- /dev/null
+++ b/frontend/dist/assets/index.de7292ad.css
@@ -0,0 +1 @@
+@charset "UTF-8";html{background-color:#f5f5f5}body{margin:0;font-family:Nunito,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}@font-face{font-family:Nunito;font-style:normal;font-weight:400;src:local(""),url(/assets/nunito-v16-latin-regular.06f3af3f.woff2) format("woff2")}#app{height:100vh;text-align:center}#App{height:100vh;text-align:center;display:flex;flex-direction:row}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-thumb{--tw-border-opacity: 1;background-color:#b6b4b4cc;border-color:rgba(181,180,178,var(--tw-border-opacity));border-radius:9999px;border-width:1px}.wechat-UserList{width:275px;height:100%;background-color:#eae8e7}.wechat-SearchBar{height:60px;background-color:#f7f7f7;--wails-draggable:drag}.wechat-SearchBar-Input{height:26px;width:240px;background-color:#e6e6e6;margin-top:22px;--wails-draggable:no-drag}.wechat-UserList-Items{height:calc(100% - 60px);overflow:auto}.wechat-UserItem{display:flex;justify-content:space-between;height:64px}.wechat-UserItem{transition:background-color .3s ease}.wechat-UserItem:hover{background-color:#dcdad9}.wechat-UserItem:focus{background-color:#c9c8c6}.selectedItem{background-color:#c9c8c6}#wechat-UserItem-content-Avatar-id{border-radius:0}.wechat-UserItem-content-Avatar{margin-top:12px;margin-left:9px;margin-right:9px}.wechat-UserItem-content{flex:1;width:55%;display:flex;flex-direction:column;justify-content:space-between}.wechat-UserItem-content-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.wechat-UserItem-content-name{color:#000;font-size:95%;margin-top:12px}.wechat-UserItem-content-msg{color:#999;font-size:80%;margin-bottom:10px}.wechat-UserItem-date{color:#999;font-size:80%;margin-top:12px;margin-right:9px}.Setting-Modal{width:500px;background-color:#f5f5f5;position:fixed;top:35%;left:50%;transform:translate(-50%,-50%);padding:20px;border-radius:5px;box-shadow:2px 2px 2px #a2a2a2}.Setting-Modal-Overlay{position:fixed;top:0;left:0;right:0;bottom:0}.WechatInfoTable{display:flex;flex-direction:column;font-size:.9rem;border-top:1px solid #b9b9b9}.WechatInfoTable-column{display:flex;margin-top:8px}.WechatInfoTable-column-tag{margin-left:8px}.Setting-Modal-export-button{margin-top:10px}.Setting-Modal-button{position:absolute;top:10px;right:10px;padding:5px 10px;border:none;cursor:pointer}.Setting-Modal-confirm{background-color:#f5f5f5;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);padding:20px;border-radius:5px;box-shadow:2px 2px 2px #a2a2a2}.Setting-Modal-confirm-Overlay{position:fixed;top:0;left:0;right:0;bottom:0}.Setting-Modal-confirm-title{text-align:center}.Setting-Modal-confirm-buttons{display:flex;gap:10px}.wechat-menu{display:flex;flex-direction:column;width:52px;justify-content:flex-start;height:100%;background-color:#2e2e2e;--wails-draggable:drag}.wechat-menu-item{margin-left:auto;margin-right:auto;margin-top:30px;--wails-draggable:no-drag}#wechat-menu-item-Avatar{border-radius:0}.wechat-menu-item-icon{background-color:#2e2e2e}.wechat-menu-selectedColor{color:#07c160}.ChatUi{background-color:#f3f3f3;height:calc(100% - 60px)}.ChatUiBar{display:flex;justify-content:space-between;align-items:center;padding:4% 2% 2%;border-bottom:.5px solid #dddbdb;background-color:#fff}.ChatUiBar--Text{flex:1;text-align:center;margin:1%}.ChatUiBar--Btn>.Icon{height:1.5em;width:1.5em}#scrollableDiv{height:100%;overflow:auto;display:flex;flex-direction:column-reverse}.MessageBubble{display:flex;flex-direction:column;justify-content:space-between;align-items:center;padding:10px}.MessageBubble>.Time{text-align:center;font-size:.8rem;margin-bottom:3px;background-color:#c9c8c6;color:#fff;padding:2px 3px;border-radius:4px}.MessageBubble-content-left{align-self:flex-start;display:flex;max-width:60%}.MessageBubble-content-right{align-self:flex-end;display:flex;max-width:60%}.Bubble-right>.Bubble{background-color:#95ec69}.MessageBubble-Avatar-left{margin-right:2px;border-radius:10%}.MessageBubble-Avatar-right{margin-left:2px;border-radius:10%}.Bubble-left{display:flex;flex-direction:column;align-items:flex-start;flex:1 1;max-width:100%}.MessageBubble-Name-left{color:#383838;font-size:small;margin-bottom:1px}.Bubble-right{display:flex;flex-direction:column;align-items:flex-end;flex:1 1;max-width:100%}.MessageBubble-Name-right{color:#383838;font-size:small;margin-bottom:1px}.CardMessageText{text-align:start;max-width:100%;word-break:break-all;padding:0}.MessageText-emoji{width:1.2rem;height:1.2rem;vertical-align:text-bottom}div.Bubble-right>div.CardMessageText{background-color:#95ec69}.System-Text{font-size:.8rem;color:#686868}.CardMessage{background-color:#fff;border-radius:3%;height:130px;width:260px;flex:1;display:flex;flex-direction:column;justify-content:space-between;text-align:start;padding:12px;cursor:pointer}.CardMessage-Content{display:flex;flex-direction:row;justify-content:space-between;max-width:100%;max-height:70%;padding-bottom:5px}.CardMessage-Title{overflow:hidden;text-overflow:ellipsis;word-break:break-all;max-width:95%}.CardMessage-Desc{overflow:hidden;text-overflow:ellipsis;max-width:80%;font-size:.75rem;height:90%;padding-top:5px;padding-bottom:5px;color:#949292}.CardMessage-Desc-Span{color:#bd0b0b}.CardMessageLink-Line{height:1px;width:100%;background-color:#f6f4f4}.CardMessageLink-Line-None{display:none}.CardMessageLink-Name{padding-top:4px;font-size:.65rem}.MessageRefer-Right{display:flex;flex-direction:column;align-items:flex-end}.MessageRefer-Left{display:flex;flex-direction:column;align-items:flex-start}.MessageRefer-Content{margin-top:6px;font-size:.8rem;color:#595959;background-color:#c9c8c6;border-radius:2px;padding:4px}.MessageRefer-Content-Text{max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.CardMessageFile-Icon{font-size:45px;color:#595959}.CardMessage-Menu{font-size:.8rem}.CardMessageAudio{max-width:100%}.szh-menu{margin:0;padding:0;list-style:none;box-sizing:border-box;width:max-content;z-index:100;border:1px solid rgba(0,0,0,.1);background-color:#fff}.szh-menu:focus{outline:none}.szh-menu__arrow{box-sizing:border-box;width:.75rem;height:.75rem;background-color:#fff;border:1px solid transparent;border-left-color:#0000001a;border-top-color:#0000001a;z-index:-1}.szh-menu__arrow--dir-left{right:-.375rem;transform:translateY(-50%) rotate(135deg)}.szh-menu__arrow--dir-right{left:-.375rem;transform:translateY(-50%) rotate(-45deg)}.szh-menu__arrow--dir-top{bottom:-.375rem;transform:translate(-50%) rotate(-135deg)}.szh-menu__arrow--dir-bottom{top:-.375rem;transform:translate(-50%) rotate(45deg)}.szh-menu__item{cursor:pointer}.szh-menu__item:focus{outline:none}.szh-menu__item--hover{background-color:#ebebeb}.szh-menu__item--focusable{cursor:default;background-color:inherit}.szh-menu__item--disabled{cursor:default;color:#aaa}.szh-menu__group{box-sizing:border-box}.szh-menu__radio-group{margin:0;padding:0;list-style:none}.szh-menu__divider{height:1px;margin:.5rem 0;background-color:#0000001f}.szh-menu-button{box-sizing:border-box}.szh-menu{user-select:none;color:#212529;border:none;border-radius:.25rem;box-shadow:0 3px 7px #0002,0 .6px 2px #0000001a;min-width:10rem;padding:.5rem 0}.szh-menu__item{display:flex;align-items:center;position:relative;padding:.375rem 1.5rem}.szh-menu-container--itemTransition .szh-menu__item{transition-property:background-color,color;transition-duration:.15s;transition-timing-function:ease-in-out}.szh-menu__item--type-radio{padding-left:2.2rem}.szh-menu__item--type-radio:before{content:"\25cb";position:absolute;left:.8rem;top:.55rem;font-size:.8rem}.szh-menu__item--type-radio.szh-menu__item--checked:before{content:"\25cf"}.szh-menu__item--type-checkbox{padding-left:2.2rem}.szh-menu__item--type-checkbox:before{position:absolute;left:.8rem}.szh-menu__item--type-checkbox.szh-menu__item--checked:before{content:"\2714"}.szh-menu__submenu>.szh-menu__item{padding-right:2.5rem}.szh-menu__submenu>.szh-menu__item:after{content:"\276f";position:absolute;right:1rem}.szh-menu__header{color:#888;font-size:.8rem;padding:.2rem 1.5rem;text-transform:uppercase}.SearchInputIcon{background-color:#f5f4f4;display:flex;align-items:center}.SearchInputIcon-second{font-size:12px;margin:0 3px;cursor:default}#RecordsUiscrollableDiv{height:400px;overflow:auto;display:flex;flex-direction:column-reverse;border-top:1px solid #efefef}#RecordsUiscrollableDiv>div>div>.MessageBubble:hover{background-color:#dcdad9}.RecordsUi-MessageBubble>.MessageBubble-content-left{max-width:95%}.CalendarChoose{height:400px}.CalendarLoading{height:220px;padding-top:180px}.ChattingRecords-Modal{width:500px;background-color:#f5f5f5;position:fixed;top:45%;left:50%;transform:translate(-50%,-50%);padding:20px;border-radius:5px;box-shadow:2px 2px 2px #a2a2a2}.ChattingRecords-Modal-Overlay{position:fixed;top:0;left:0;right:0;bottom:0}.ChattingRecords-Modal-Bar-Tag{display:flex;flex-direction:row;justify-content:space-around;margin-top:5px;margin-bottom:5px;cursor:default;color:#576b95;font-size:.9rem}.ChattingRecords-Modal-Bar-Top{display:flex;flex-direction:row;justify-content:space-between;padding:0 5px 5px}.NotMessageContent{height:400px;display:flex;justify-content:center;align-items:center}.NotMessageContent-keyword{color:#07c160}.ChattingRecords-ChatRoomUserList{width:260px;height:300px;background-color:#f5f5f5;position:fixed;top:48%;left:70%;transform:translate(-50%,-50%);padding:20px;border-radius:5px;box-shadow:2px 2px 2px #a2a2a2}.ChattingRecords-ChatRoomUserList-Overlay{position:fixed;top:0;left:0;right:0;bottom:0}.ChattingRecords-ChatRoomUserList>.wechat-SearchInput{margin-bottom:10px}.ChattingRecords-ChatRoomUserList-List{overflow:auto;height:90%}.ChattingRecords-ChatRoomUserList-User{display:flex;padding-bottom:5px;align-items:center}.ChattingRecords-ChatRoomUserList-User:hover{background-color:#dcdad9}.ChattingRecords-ChatRoomUserList-Name{padding-left:8px;font-size:.85rem}.ChattingRecords-ChatRoomUserList-Loading{padding:20px;text-align:center}.ChattingRecords-ChatRoomUserList-List-End{padding:5px;text-align:center;font-size:.85rem}.wechat-UserDialog{flex-grow:1;background-color:#f5f5f5;flex:1;height:100%;display:flex;flex-direction:column;justify-content:space-between;width:calc(100% - 327px)}.wechat-UserDialog-Bar{height:60px;background-color:#f5f5f5;border-left:1px solid #E6E6E6;border-bottom:1px solid #E6E6E6;display:flex;flex-direction:row;justify-content:space-between;--wails-draggable:drag}.wechat-UserDialog-Bar-button-block{display:flex;flex-direction:column}.wechat-UserDialog-Bar-button-list{display:flex;flex-direction:row;--wails-draggable:no-drag}.wechat-UserDialog-Bar-button{width:34px;height:22px;color:#131212}.wechat-UserDialog-Bar-button-icon{width:12px;height:10px}.wechat-UserDialog-Bar-button-msg{margin-left:auto;margin-top:5px;--wails-draggable:no-drag}.wechat-UserDialog-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.wechat-UserDialog-name{color:#000;font-size:large;margin-top:20px;margin-left:16px;--wails-draggable:no-drag}
diff --git a/frontend/dist/assets/nunito-v16-latin-regular.06f3af3f.woff2 b/frontend/dist/assets/nunito-v16-latin-regular.06f3af3f.woff2
new file mode 100644
index 0000000..2f9cc59
Binary files /dev/null and b/frontend/dist/assets/nunito-v16-latin-regular.06f3af3f.woff2 differ
diff --git a/frontend/dist/index.html b/frontend/dist/index.html
new file mode 100644
index 0000000..5a21f74
--- /dev/null
+++ b/frontend/dist/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+ wechatDataBackup
+
+
+
+
+
+
+
+
+
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..eab7e5e
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,70 @@
+module wechatDataBackup
+
+go 1.21
+
+toolchain go1.21.0
+
+require (
+ github.com/beevik/etree v1.3.0
+ github.com/mattn/go-sqlite3 v1.14.22
+ github.com/pierrec/lz4 v2.6.1+incompatible
+ github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
+ github.com/shirou/gopsutil v2.21.11+incompatible
+ github.com/shirou/gopsutil/v3 v3.24.2
+ github.com/spf13/viper v1.18.2
+ github.com/wailsapp/wails/v2 v2.9.1
+ golang.org/x/sys v0.20.0
+ google.golang.org/protobuf v1.31.0
+)
+
+require (
+ github.com/bep/debounce v1.2.1 // indirect
+ github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/go-ole/go-ole v1.2.6 // indirect
+ github.com/godbus/dbus/v5 v5.1.0 // indirect
+ github.com/google/uuid v1.4.0 // indirect
+ github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
+ github.com/labstack/echo/v4 v4.10.2 // indirect
+ github.com/labstack/gommon v0.4.0 // indirect
+ github.com/leaanthony/go-ansi-parser v1.6.0 // indirect
+ github.com/leaanthony/gosod v1.0.3 // indirect
+ github.com/leaanthony/slicer v1.6.0 // indirect
+ github.com/leaanthony/u v1.1.0 // indirect
+ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
+ github.com/magiconair/properties v1.8.7 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.19 // indirect
+ github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/pelletier/go-toml/v2 v2.1.0 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
+ github.com/rivo/uniseg v0.4.4 // indirect
+ github.com/sagikazarmark/locafero v0.4.0 // indirect
+ github.com/sagikazarmark/slog-shim v0.1.0 // indirect
+ github.com/samber/lo v1.38.1 // indirect
+ github.com/shoenig/go-m1cpu v0.1.6 // indirect
+ github.com/sourcegraph/conc v0.3.0 // indirect
+ github.com/spf13/afero v1.11.0 // indirect
+ github.com/spf13/cast v1.6.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ github.com/subosito/gotenv v1.6.0 // indirect
+ github.com/tklauser/go-sysconf v0.3.13 // indirect
+ github.com/tklauser/numcpus v0.7.0 // indirect
+ github.com/tkrajina/go-reflector v0.5.6 // indirect
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
+ github.com/valyala/fasttemplate v1.2.2 // indirect
+ github.com/wailsapp/go-webview2 v1.0.10 // indirect
+ github.com/wailsapp/mimetype v1.4.1 // indirect
+ github.com/yusufpapurcu/wmi v1.2.4 // indirect
+ go.uber.org/atomic v1.9.0 // indirect
+ go.uber.org/multierr v1.9.0 // indirect
+ golang.org/x/crypto v0.23.0 // indirect
+ golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
+ golang.org/x/net v0.25.0 // indirect
+ golang.org/x/text v0.15.0 // indirect
+ gopkg.in/ini.v1 v1.67.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
+
+// replace github.com/wailsapp/wails/v2 v2.8.0 => C:\Users\HAL\go\pkg\mod
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..74987f2
--- /dev/null
+++ b/main.go
@@ -0,0 +1,79 @@
+package main
+
+import (
+ "embed"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "os"
+ "strings"
+
+ "github.com/wailsapp/wails/v2"
+ "github.com/wailsapp/wails/v2/pkg/options"
+ "github.com/wailsapp/wails/v2/pkg/options/assetserver"
+)
+
+//go:embed all:frontend/dist
+var assets embed.FS
+
+type FileLoader struct {
+ http.Handler
+}
+
+func NewFileLoader() *FileLoader {
+ return &FileLoader{}
+}
+
+func (h *FileLoader) ServeHTTP(res http.ResponseWriter, req *http.Request) {
+ var err error
+ requestedFilename := strings.TrimPrefix(req.URL.Path, "/")
+ // println("Requesting file:", requestedFilename)
+ fileData, err := os.ReadFile(requestedFilename)
+ if err != nil {
+ res.WriteHeader(http.StatusBadRequest)
+ res.Write([]byte(fmt.Sprintf("Could not load file %s", requestedFilename)))
+ }
+
+ res.Write(fileData)
+}
+
+func init() {
+ log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
+}
+
+func main() {
+ file, _ := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
+ defer file.Close()
+
+ multiWriter := io.MultiWriter(file, os.Stdout)
+ // 设置日志输出目标为文件
+ log.SetOutput(multiWriter)
+ log.Println("====================== wechatDataBackup ======================")
+ // Create an instance of the app structure
+ app := NewApp()
+
+ // Create application with options
+ err := wails.Run(&options.App{
+ Title: "wechatDataBackup",
+ MinWidth: 800,
+ MinHeight: 600,
+ Width: 1024,
+ Height: 768,
+ AssetServer: &assetserver.Options{
+ Assets: assets,
+ Handler: NewFileLoader(),
+ },
+ BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
+ OnStartup: app.startup,
+ OnBeforeClose: app.beforeClose,
+ Bind: []interface{}{
+ app,
+ },
+ Frameless: true,
+ })
+
+ if err != nil {
+ println("Error:", err.Error())
+ }
+}
diff --git a/pkg/lame/.gitignore b/pkg/lame/.gitignore
new file mode 100644
index 0000000..8365624
--- /dev/null
+++ b/pkg/lame/.gitignore
@@ -0,0 +1,23 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
diff --git a/pkg/lame/LICENSE b/pkg/lame/LICENSE
new file mode 100644
index 0000000..63280d0
--- /dev/null
+++ b/pkg/lame/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2019 Pavel Vorobyov
+
+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.
diff --git a/pkg/lame/README.md b/pkg/lame/README.md
new file mode 100644
index 0000000..b618755
--- /dev/null
+++ b/pkg/lame/README.md
@@ -0,0 +1,43 @@
+lame
+====
+
+Simple libmp3lame powered mp3 encoder for Go
+
+**Note:** this project is obsolete, consider moving to https://github.com/viert/go-lame
+
+Example:
+
+```Go
+package main
+
+import (
+ "bufio"
+ "lame"
+ "os"
+)
+
+func main() {
+ f, err := os.Open("input.raw")
+ if err != nil {
+ panic(err)
+ }
+ defer f.Close()
+ reader := bufio.NewReader(f)
+
+ of, err := os.Create("output.mp3")
+ if err != nil {
+ panic(err)
+ }
+ defer of.Close()
+
+ wr := lame.NewWriter(of)
+ wr.Encoder.SetBitrate(112)
+ wr.Encoder.SetQuality(1)
+
+ // IMPORTANT!
+ wr.Encoder.InitParams()
+
+ reader.WriteTo(wr)
+
+}
+```
diff --git a/pkg/lame/clame/VbrTag.c b/pkg/lame/clame/VbrTag.c
new file mode 100644
index 0000000..5800a44
--- /dev/null
+++ b/pkg/lame/clame/VbrTag.c
@@ -0,0 +1,1082 @@
+/*
+ * Xing VBR tagging for LAME.
+ *
+ * Copyright (c) 1999 A.L. Faber
+ * Copyright (c) 2001 Jonathan Dee
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: VbrTag.c,v 1.106 2017/08/06 18:15:47 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "bitstream.h"
+#include "VbrTag.h"
+#include "lame_global_flags.h"
+#include "tables.h"
+
+#ifdef __sun__
+/* woraround for SunOS 4.x, it has SEEK_* defined here */
+#include
+#endif
+
+
+#ifdef _DEBUG
+/* #define DEBUG_VBRTAG */
+#endif
+
+/*
+ * 4 bytes for Header Tag
+ * 4 bytes for Header Flags
+ * 100 bytes for entry (NUMTOCENTRIES)
+ * 4 bytes for FRAME SIZE
+ * 4 bytes for STREAM_SIZE
+ * 4 bytes for VBR SCALE. a VBR quality indicator: 0=best 100=worst
+ * 20 bytes for LAME tag. for example, "LAME3.12 (beta 6)"
+ * ___________
+ * 140 bytes
+*/
+#define VBRHEADERSIZE (NUMTOCENTRIES+4+4+4+4+4)
+
+#define LAMEHEADERSIZE (VBRHEADERSIZE + 9 + 1 + 1 + 8 + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2)
+
+/* the size of the Xing header (MPEG1 and MPEG2) in kbps */
+#define XING_BITRATE1 128
+#define XING_BITRATE2 64
+#define XING_BITRATE25 32
+
+extern const char* get_lame_tag_encoder_short_version(void);
+
+static const char VBRTag0[] = { "Xing" };
+static const char VBRTag1[] = { "Info" };
+
+
+
+
+/* Lookup table for fast CRC computation
+ * See 'CRC_update_lookup'
+ * Uses the polynomial x^16+x^15+x^2+1 */
+
+static const unsigned int crc16_lookup[256] = {
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+
+
+
+
+/***********************************************************************
+ * Robert Hegemann 2001-01-17
+ ***********************************************************************/
+
+static void
+addVbr(VBR_seek_info_t * v, int bitrate)
+{
+ int i;
+
+ v->nVbrNumFrames++;
+ v->sum += bitrate;
+ v->seen++;
+
+ if (v->seen < v->want) {
+ return;
+ }
+
+ if (v->pos < v->size) {
+ v->bag[v->pos] = v->sum;
+ v->pos++;
+ v->seen = 0;
+ }
+ if (v->pos == v->size) {
+ for (i = 1; i < v->size; i += 2) {
+ v->bag[i / 2] = v->bag[i];
+ }
+ v->want *= 2;
+ v->pos /= 2;
+ }
+}
+
+static void
+Xing_seek_table(VBR_seek_info_t const* v, unsigned char *t)
+{
+ int i, indx;
+ int seek_point;
+
+ if (v->pos <= 0)
+ return;
+
+ for (i = 1; i < NUMTOCENTRIES; ++i) {
+ float j = i / (float) NUMTOCENTRIES, act, sum;
+ indx = (int) (floor(j * v->pos));
+ if (indx > v->pos - 1)
+ indx = v->pos - 1;
+ act = v->bag[indx];
+ sum = v->sum;
+ seek_point = (int) (256. * act / sum);
+ if (seek_point > 255)
+ seek_point = 255;
+ t[i] = seek_point;
+ }
+}
+
+#ifdef DEBUG_VBR_SEEKING_TABLE
+static void
+print_seeking(unsigned char *t)
+{
+ int i;
+
+ printf("seeking table ");
+ for (i = 0; i < NUMTOCENTRIES; ++i) {
+ printf(" %d ", t[i]);
+ }
+ printf("\n");
+}
+#endif
+
+
+/****************************************************************************
+ * AddVbrFrame: Add VBR entry, used to fill the VBR the TOC entries
+ * Paramters:
+ * nStreamPos: how many bytes did we write to the bitstream so far
+ * (in Bytes NOT Bits)
+ ****************************************************************************
+*/
+void
+AddVbrFrame(lame_internal_flags * gfc)
+{
+ int kbps = bitrate_table[gfc->cfg.version][gfc->ov_enc.bitrate_index];
+ assert(gfc->VBR_seek_table.bag);
+ addVbr(&gfc->VBR_seek_table, kbps);
+}
+
+
+/*-------------------------------------------------------------*/
+static int
+ExtractI4(const unsigned char *buf)
+{
+ int x;
+ /* big endian extract */
+ x = buf[0];
+ x <<= 8;
+ x |= buf[1];
+ x <<= 8;
+ x |= buf[2];
+ x <<= 8;
+ x |= buf[3];
+ return x;
+}
+
+static void
+CreateI4(unsigned char *buf, uint32_t nValue)
+{
+ /* big endian create */
+ buf[0] = (nValue >> 24) & 0xff;
+ buf[1] = (nValue >> 16) & 0xff;
+ buf[2] = (nValue >> 8) & 0xff;
+ buf[3] = (nValue) & 0xff;
+}
+
+
+
+static void
+CreateI2(unsigned char *buf, int nValue)
+{
+ /* big endian create */
+ buf[0] = (nValue >> 8) & 0xff;
+ buf[1] = (nValue) & 0xff;
+}
+
+/* check for magic strings*/
+static int
+IsVbrTag(const unsigned char *buf)
+{
+ int isTag0, isTag1;
+
+ isTag0 = ((buf[0] == VBRTag0[0]) && (buf[1] == VBRTag0[1]) && (buf[2] == VBRTag0[2])
+ && (buf[3] == VBRTag0[3]));
+ isTag1 = ((buf[0] == VBRTag1[0]) && (buf[1] == VBRTag1[1]) && (buf[2] == VBRTag1[2])
+ && (buf[3] == VBRTag1[3]));
+
+ return (isTag0 || isTag1);
+}
+
+#define SHIFT_IN_BITS_VALUE(x,n,v) ( x = (x << (n)) | ( (v) & ~(-1 << (n)) ) )
+
+static void
+setLameTagFrameHeader(lame_internal_flags const *gfc, unsigned char *buffer)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t const *const eov = &gfc->ov_enc;
+ char abyte, bbyte;
+
+ SHIFT_IN_BITS_VALUE(buffer[0], 8u, 0xffu);
+
+ SHIFT_IN_BITS_VALUE(buffer[1], 3u, 7);
+ SHIFT_IN_BITS_VALUE(buffer[1], 1u, (cfg->samplerate_out < 16000) ? 0 : 1);
+ SHIFT_IN_BITS_VALUE(buffer[1], 1u, cfg->version);
+ SHIFT_IN_BITS_VALUE(buffer[1], 2u, 4 - 3);
+ SHIFT_IN_BITS_VALUE(buffer[1], 1u, (!cfg->error_protection) ? 1 : 0);
+
+ SHIFT_IN_BITS_VALUE(buffer[2], 4u, eov->bitrate_index);
+ SHIFT_IN_BITS_VALUE(buffer[2], 2u, cfg->samplerate_index);
+ SHIFT_IN_BITS_VALUE(buffer[2], 1u, 0);
+ SHIFT_IN_BITS_VALUE(buffer[2], 1u, cfg->extension);
+
+ SHIFT_IN_BITS_VALUE(buffer[3], 2u, cfg->mode);
+ SHIFT_IN_BITS_VALUE(buffer[3], 2u, eov->mode_ext);
+ SHIFT_IN_BITS_VALUE(buffer[3], 1u, cfg->copyright);
+ SHIFT_IN_BITS_VALUE(buffer[3], 1u, cfg->original);
+ SHIFT_IN_BITS_VALUE(buffer[3], 2u, cfg->emphasis);
+
+ /* the default VBR header. 48 kbps layer III, no padding, no crc */
+ /* but sampling freq, mode andy copyright/copy protection taken */
+ /* from first valid frame */
+ buffer[0] = (uint8_t) 0xff;
+ abyte = (buffer[1] & (unsigned char) 0xf1);
+ {
+ int bitrate;
+ if (1 == cfg->version) {
+ bitrate = XING_BITRATE1;
+ }
+ else {
+ if (cfg->samplerate_out < 16000)
+ bitrate = XING_BITRATE25;
+ else
+ bitrate = XING_BITRATE2;
+ }
+
+ if (cfg->vbr == vbr_off)
+ bitrate = cfg->avg_bitrate;
+
+ if (cfg->free_format)
+ bbyte = 0x00;
+ else
+ bbyte = 16 * BitrateIndex(bitrate, cfg->version, cfg->samplerate_out);
+ }
+
+ /* Use as much of the info from the real frames in the
+ * Xing header: samplerate, channels, crc, etc...
+ */
+ if (cfg->version == 1) {
+ /* MPEG1 */
+ buffer[1] = abyte | (char) 0x0a; /* was 0x0b; */
+ abyte = buffer[2] & (char) 0x0d; /* AF keep also private bit */
+ buffer[2] = (char) bbyte | abyte; /* 64kbs MPEG1 frame */
+ }
+ else {
+ /* MPEG2 */
+ buffer[1] = abyte | (char) 0x02; /* was 0x03; */
+ abyte = buffer[2] & (char) 0x0d; /* AF keep also private bit */
+ buffer[2] = (char) bbyte | abyte; /* 64kbs MPEG2 frame */
+ }
+}
+
+#if 0
+static int CheckVbrTag(unsigned char *buf);
+
+/*-------------------------------------------------------------*/
+/* Same as GetVbrTag below, but only checks for the Xing tag.
+ requires buf to contain only 40 bytes */
+/*-------------------------------------------------------------*/
+int
+CheckVbrTag(unsigned char *buf)
+{
+ int h_id, h_mode;
+
+ /* get selected MPEG header data */
+ h_id = (buf[1] >> 3) & 1;
+ h_mode = (buf[3] >> 6) & 3;
+
+ /* determine offset of header */
+ if (h_id) {
+ /* mpeg1 */
+ if (h_mode != 3)
+ buf += (32 + 4);
+ else
+ buf += (17 + 4);
+ }
+ else {
+ /* mpeg2 */
+ if (h_mode != 3)
+ buf += (17 + 4);
+ else
+ buf += (9 + 4);
+ }
+
+ return IsVbrTag(buf);
+}
+#endif
+
+int
+GetVbrTag(VBRTAGDATA * pTagData, const unsigned char *buf)
+{
+ int i, head_flags;
+ int h_bitrate, h_id, h_mode, h_sr_index, h_layer;
+ int enc_delay, enc_padding;
+
+ /* get Vbr header data */
+ pTagData->flags = 0;
+
+ /* get selected MPEG header data */
+ h_layer = (buf[1] >> 1) & 3;
+ if ( h_layer != 0x01 ) {
+ /* the following code assumes Layer-3, so give up here */
+ return 0;
+ }
+ h_id = (buf[1] >> 3) & 1;
+ h_sr_index = (buf[2] >> 2) & 3;
+ h_mode = (buf[3] >> 6) & 3;
+ h_bitrate = ((buf[2] >> 4) & 0xf);
+ h_bitrate = bitrate_table[h_id][h_bitrate];
+
+ /* check for FFE syncword */
+ if ((buf[1] >> 4) == 0xE)
+ pTagData->samprate = samplerate_table[2][h_sr_index];
+ else
+ pTagData->samprate = samplerate_table[h_id][h_sr_index];
+ /* if( h_id == 0 ) */
+ /* pTagData->samprate >>= 1; */
+
+
+
+ /* determine offset of header */
+ if (h_id) {
+ /* mpeg1 */
+ if (h_mode != 3)
+ buf += (32 + 4);
+ else
+ buf += (17 + 4);
+ }
+ else {
+ /* mpeg2 */
+ if (h_mode != 3)
+ buf += (17 + 4);
+ else
+ buf += (9 + 4);
+ }
+
+ if (!IsVbrTag(buf))
+ return 0;
+
+ buf += 4;
+
+ pTagData->h_id = h_id;
+
+ head_flags = pTagData->flags = ExtractI4(buf);
+ buf += 4; /* get flags */
+
+ if (head_flags & FRAMES_FLAG) {
+ pTagData->frames = ExtractI4(buf);
+ buf += 4;
+ }
+
+ if (head_flags & BYTES_FLAG) {
+ pTagData->bytes = ExtractI4(buf);
+ buf += 4;
+ }
+
+ if (head_flags & TOC_FLAG) {
+ if (pTagData->toc != NULL) {
+ for (i = 0; i < NUMTOCENTRIES; i++)
+ pTagData->toc[i] = buf[i];
+ }
+ buf += NUMTOCENTRIES;
+ }
+
+ pTagData->vbr_scale = -1;
+
+ if (head_flags & VBR_SCALE_FLAG) {
+ pTagData->vbr_scale = ExtractI4(buf);
+ buf += 4;
+ }
+
+ pTagData->headersize = ((h_id + 1) * 72000 * h_bitrate) / pTagData->samprate;
+
+ buf += 21;
+ enc_delay = buf[0] << 4;
+ enc_delay += buf[1] >> 4;
+ enc_padding = (buf[1] & 0x0F) << 8;
+ enc_padding += buf[2];
+ /* check for reasonable values (this may be an old Xing header, */
+ /* not a INFO tag) */
+ if (enc_delay < 0 || enc_delay > 3000)
+ enc_delay = -1;
+ if (enc_padding < 0 || enc_padding > 3000)
+ enc_padding = -1;
+
+ pTagData->enc_delay = enc_delay;
+ pTagData->enc_padding = enc_padding;
+
+#ifdef DEBUG_VBRTAG
+ fprintf(stderr, "\n\n********************* VBR TAG INFO *****************\n");
+ fprintf(stderr, "tag :%s\n", VBRTag);
+ fprintf(stderr, "head_flags :%d\n", head_flags);
+ fprintf(stderr, "bytes :%d\n", pTagData->bytes);
+ fprintf(stderr, "frames :%d\n", pTagData->frames);
+ fprintf(stderr, "VBR Scale :%d\n", pTagData->vbr_scale);
+ fprintf(stderr, "enc_delay = %i \n", enc_delay);
+ fprintf(stderr, "enc_padding= %i \n", enc_padding);
+ fprintf(stderr, "toc:\n");
+ if (pTagData->toc != NULL) {
+ for (i = 0; i < NUMTOCENTRIES; i++) {
+ if ((i % 10) == 0)
+ fprintf(stderr, "\n");
+ fprintf(stderr, " %3d", (int) (pTagData->toc[i]));
+ }
+ }
+ fprintf(stderr, "\n***************** END OF VBR TAG INFO ***************\n");
+#endif
+ return 1; /* success */
+}
+
+
+/****************************************************************************
+ * InitVbrTag: Initializes the header, and write empty frame to stream
+ * Paramters:
+ * fpStream: pointer to output file stream
+ * nMode : Channel Mode: 0=STEREO 1=JS 2=DS 3=MONO
+ ****************************************************************************
+*/
+int
+InitVbrTag(lame_global_flags * gfp)
+{
+ lame_internal_flags *gfc = gfp->internal_flags;
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int kbps_header;
+
+#define MAXFRAMESIZE 2880 /* or 0xB40, the max freeformat 640 32kHz framesize */
+
+ /*
+ * Xing VBR pretends to be a 48kbs layer III frame. (at 44.1kHz).
+ * (at 48kHz they use 56kbs since 48kbs frame not big enough for
+ * table of contents)
+ * let's always embed Xing header inside a 64kbs layer III frame.
+ * this gives us enough room for a LAME version string too.
+ * size determined by sampling frequency (MPEG1)
+ * 32kHz: 216 bytes@48kbs 288bytes@ 64kbs
+ * 44.1kHz: 156 bytes 208bytes@64kbs (+1 if padding = 1)
+ * 48kHz: 144 bytes 192
+ *
+ * MPEG 2 values are the same since the framesize and samplerate
+ * are each reduced by a factor of 2.
+ */
+
+
+ if (1 == cfg->version) {
+ kbps_header = XING_BITRATE1;
+ }
+ else {
+ if (cfg->samplerate_out < 16000)
+ kbps_header = XING_BITRATE25;
+ else
+ kbps_header = XING_BITRATE2;
+ }
+
+ if (cfg->vbr == vbr_off)
+ kbps_header = cfg->avg_bitrate;
+
+ /** make sure LAME Header fits into Frame
+ */
+ {
+ int total_frame_size = ((cfg->version + 1) * 72000 * kbps_header) / cfg->samplerate_out;
+ int header_size = (cfg->sideinfo_len + LAMEHEADERSIZE);
+ gfc->VBR_seek_table.TotalFrameSize = total_frame_size;
+ if (total_frame_size < header_size || total_frame_size > MAXFRAMESIZE) {
+ /* disable tag, it wont fit */
+ gfc->cfg.write_lame_tag = 0;
+ return 0;
+ }
+ }
+
+ gfc->VBR_seek_table.nVbrNumFrames = 0;
+ gfc->VBR_seek_table.nBytesWritten = 0;
+ gfc->VBR_seek_table.sum = 0;
+
+ gfc->VBR_seek_table.seen = 0;
+ gfc->VBR_seek_table.want = 1;
+ gfc->VBR_seek_table.pos = 0;
+
+ if (gfc->VBR_seek_table.bag == NULL) {
+ gfc->VBR_seek_table.bag = lame_calloc(int, 400);
+ if (gfc->VBR_seek_table.bag != NULL) {
+ gfc->VBR_seek_table.size = 400;
+ }
+ else {
+ gfc->VBR_seek_table.size = 0;
+ ERRORF(gfc, "Error: can't allocate VbrFrames buffer\n");
+ gfc->cfg.write_lame_tag = 0;
+ return -1;
+ }
+ }
+
+ /* write dummy VBR tag of all 0's into bitstream */
+ {
+ uint8_t buffer[MAXFRAMESIZE];
+ size_t i, n;
+
+ memset(buffer, 0, sizeof(buffer));
+ setLameTagFrameHeader(gfc, buffer);
+ n = gfc->VBR_seek_table.TotalFrameSize;
+ for (i = 0; i < n; ++i) {
+ add_dummy_byte(gfc, buffer[i], 1);
+ }
+ }
+ /* Success */
+ return 0;
+}
+
+
+
+/* fast CRC-16 computation - uses table crc16_lookup 8*/
+static uint16_t
+CRC_update_lookup(uint16_t value, uint16_t crc)
+{
+ uint16_t tmp;
+ tmp = crc ^ value;
+ crc = (crc >> 8) ^ crc16_lookup[tmp & 0xff];
+ return crc;
+}
+
+void
+UpdateMusicCRC(uint16_t * crc, unsigned char const *buffer, int size)
+{
+ int i;
+ for (i = 0; i < size; ++i)
+ *crc = CRC_update_lookup(buffer[i], *crc);
+}
+
+
+
+
+
+/****************************************************************************
+ * Jonathan Dee 2001/08/31
+ *
+ * PutLameVBR: Write LAME info: mini version + info on various switches used
+ * Paramters:
+ * pbtStreamBuffer : pointer to output buffer
+ * id3v2size : size of id3v2 tag in bytes
+ * crc : computation of crc-16 of Lame Tag so far (starting at frame sync)
+ *
+ ****************************************************************************
+*/
+static int
+PutLameVBR(lame_global_flags const *gfp, size_t nMusicLength, uint8_t * pbtStreamBuffer, uint16_t crc)
+{
+ lame_internal_flags const *gfc = gfp->internal_flags;
+ SessionConfig_t const *const cfg = &gfc->cfg;
+
+ int nBytesWritten = 0;
+ int i;
+
+ int enc_delay = gfc->ov_enc.encoder_delay; /* encoder delay */
+ int enc_padding = gfc->ov_enc.encoder_padding; /* encoder padding */
+
+ /*recall: cfg->vbr_q is for example set by the switch -V */
+ /* gfp->quality by -q, -h, -f, etc */
+
+ int nQuality = (100 - 10 * gfp->VBR_q - gfp->quality);
+
+
+ /*
+ NOTE:
+ Even though the specification for the LAME VBR tag
+ did explicitly mention other encoders than LAME,
+ many SW/HW decoder seem to be able to make use of
+ this tag only, if the encoder version starts with LAME.
+ To be compatible with such decoders, ANY encoder will
+ be forced to write a fake LAME version string!
+ As a result, the encoder version info becomes worthless.
+ */
+ const char *szVersion = get_lame_tag_encoder_short_version();
+ uint8_t nVBR;
+ uint8_t nRevision = 0x00;
+ uint8_t nRevMethod;
+ uint8_t vbr_type_translator[] = { 1, 5, 3, 2, 4, 0, 3 }; /*numbering different in vbr_mode vs. Lame tag */
+
+ uint8_t nLowpass =
+ (((cfg->lowpassfreq / 100.0) + .5) > 255 ? 255 : (cfg->lowpassfreq / 100.0) + .5);
+
+ uint32_t nPeakSignalAmplitude = 0;
+
+ uint16_t nRadioReplayGain = 0;
+ uint16_t nAudiophileReplayGain = 0;
+
+ uint8_t nNoiseShaping = cfg->noise_shaping;
+ uint8_t nStereoMode = 0;
+ int bNonOptimal = 0;
+ uint8_t nSourceFreq = 0;
+ uint8_t nMisc = 0;
+ uint16_t nMusicCRC = 0;
+
+ /*psy model type: Gpsycho or NsPsytune */
+ unsigned char bExpNPsyTune = 1; /* only NsPsytune */
+ unsigned char bSafeJoint = (cfg->use_safe_joint_stereo) != 0;
+
+ unsigned char bNoGapMore = 0;
+ unsigned char bNoGapPrevious = 0;
+
+ int nNoGapCount = gfp->nogap_total;
+ int nNoGapCurr = gfp->nogap_current;
+
+
+ uint8_t nAthType = cfg->ATHtype; /*4 bits. */
+
+ uint8_t nFlags = 0;
+
+ /* if ABR, {store bitrate <=255} else { store "-b"} */
+ int nABRBitrate;
+ switch (cfg->vbr) {
+ case vbr_abr:{
+ nABRBitrate = cfg->vbr_avg_bitrate_kbps;
+ break;
+ }
+ case vbr_off:{
+ nABRBitrate = cfg->avg_bitrate;
+ break;
+ }
+ default:{ /*vbr modes */
+ nABRBitrate = bitrate_table[cfg->version][cfg->vbr_min_bitrate_index];;
+ }
+ }
+
+
+ /*revision and vbr method */
+ if (cfg->vbr < sizeof(vbr_type_translator))
+ nVBR = vbr_type_translator[cfg->vbr];
+ else
+ nVBR = 0x00; /*unknown. */
+
+ nRevMethod = 0x10 * nRevision + nVBR;
+
+
+ /* ReplayGain */
+ if (cfg->findReplayGain) {
+ int RadioGain = gfc->ov_rpg.RadioGain;
+ if (RadioGain > 0x1FE)
+ RadioGain = 0x1FE;
+ if (RadioGain < -0x1FE)
+ RadioGain = -0x1FE;
+
+ nRadioReplayGain = 0x2000; /* set name code */
+ nRadioReplayGain |= 0xC00; /* set originator code to `determined automatically' */
+
+ if (RadioGain >= 0)
+ nRadioReplayGain |= RadioGain; /* set gain adjustment */
+ else {
+ nRadioReplayGain |= 0x200; /* set the sign bit */
+ nRadioReplayGain |= -RadioGain; /* set gain adjustment */
+ }
+ }
+
+ /* peak sample */
+ if (cfg->findPeakSample)
+ nPeakSignalAmplitude =
+ abs((int) ((((FLOAT) gfc->ov_rpg.PeakSample) / 32767.0) * pow(2, 23) + .5));
+
+ /*nogap */
+ if (nNoGapCount != -1) {
+ if (nNoGapCurr > 0)
+ bNoGapPrevious = 1;
+
+ if (nNoGapCurr < nNoGapCount - 1)
+ bNoGapMore = 1;
+ }
+
+ /*flags */
+
+ nFlags = nAthType + (bExpNPsyTune << 4)
+ + (bSafeJoint << 5)
+ + (bNoGapMore << 6)
+ + (bNoGapPrevious << 7);
+
+
+ if (nQuality < 0)
+ nQuality = 0;
+
+ /*stereo mode field... a bit ugly. */
+
+ switch (cfg->mode) {
+ case MONO:
+ nStereoMode = 0;
+ break;
+ case STEREO:
+ nStereoMode = 1;
+ break;
+ case DUAL_CHANNEL:
+ nStereoMode = 2;
+ break;
+ case JOINT_STEREO:
+ if (cfg->force_ms)
+ nStereoMode = 4;
+ else
+ nStereoMode = 3;
+ break;
+ case NOT_SET:
+ /* FALLTHROUGH */
+ default:
+ nStereoMode = 7;
+ break;
+ }
+
+ /*Intensity stereo : nStereoMode = 6. IS is not implemented */
+
+ if (cfg->samplerate_in <= 32000)
+ nSourceFreq = 0x00;
+ else if (cfg->samplerate_in == 48000)
+ nSourceFreq = 0x02;
+ else if (cfg->samplerate_in > 48000)
+ nSourceFreq = 0x03;
+ else
+ nSourceFreq = 0x01; /*default is 44100Hz. */
+
+
+ /*Check if the user overrided the default LAME behaviour with some nasty options */
+
+ if (cfg->short_blocks == short_block_forced || cfg->short_blocks == short_block_dispensed || ((cfg->lowpassfreq == -1) && (cfg->highpassfreq == -1)) || /* "-k" */
+ (cfg->disable_reservoir && cfg->avg_bitrate < 320) ||
+ cfg->noATH || cfg->ATHonly || (nAthType == 0) || cfg->samplerate_in <= 32000)
+ bNonOptimal = 1;
+
+ nMisc = nNoiseShaping + (nStereoMode << 2)
+ + (bNonOptimal << 5)
+ + (nSourceFreq << 6);
+
+
+ nMusicCRC = gfc->nMusicCRC;
+
+
+ /*Write all this information into the stream */
+ CreateI4(&pbtStreamBuffer[nBytesWritten], nQuality);
+ nBytesWritten += 4;
+
+ strncpy((char *) &pbtStreamBuffer[nBytesWritten], szVersion, 9);
+ nBytesWritten += 9;
+
+ pbtStreamBuffer[nBytesWritten] = nRevMethod;
+ nBytesWritten++;
+
+ pbtStreamBuffer[nBytesWritten] = nLowpass;
+ nBytesWritten++;
+
+ CreateI4(&pbtStreamBuffer[nBytesWritten], nPeakSignalAmplitude);
+ nBytesWritten += 4;
+
+ CreateI2(&pbtStreamBuffer[nBytesWritten], nRadioReplayGain);
+ nBytesWritten += 2;
+
+ CreateI2(&pbtStreamBuffer[nBytesWritten], nAudiophileReplayGain);
+ nBytesWritten += 2;
+
+ pbtStreamBuffer[nBytesWritten] = nFlags;
+ nBytesWritten++;
+
+ if (nABRBitrate >= 255)
+ pbtStreamBuffer[nBytesWritten] = 0xFF;
+ else
+ pbtStreamBuffer[nBytesWritten] = nABRBitrate;
+ nBytesWritten++;
+
+ pbtStreamBuffer[nBytesWritten] = enc_delay >> 4; /* works for win32, does it for unix? */
+ pbtStreamBuffer[nBytesWritten + 1] = (enc_delay << 4) + (enc_padding >> 8);
+ pbtStreamBuffer[nBytesWritten + 2] = enc_padding;
+
+ nBytesWritten += 3;
+
+ pbtStreamBuffer[nBytesWritten] = nMisc;
+ nBytesWritten++;
+
+
+ pbtStreamBuffer[nBytesWritten++] = 0; /*unused in rev0 */
+
+ CreateI2(&pbtStreamBuffer[nBytesWritten], cfg->preset);
+ nBytesWritten += 2;
+
+ CreateI4(&pbtStreamBuffer[nBytesWritten], (int) nMusicLength);
+ nBytesWritten += 4;
+
+ CreateI2(&pbtStreamBuffer[nBytesWritten], nMusicCRC);
+ nBytesWritten += 2;
+
+ /*Calculate tag CRC.... must be done here, since it includes
+ *previous information*/
+
+ for (i = 0; i < nBytesWritten; i++)
+ crc = CRC_update_lookup(pbtStreamBuffer[i], crc);
+
+ CreateI2(&pbtStreamBuffer[nBytesWritten], crc);
+ nBytesWritten += 2;
+
+ return nBytesWritten;
+}
+
+static long
+skipId3v2(FILE * fpStream)
+{
+ size_t nbytes;
+ long id3v2TagSize;
+ unsigned char id3v2Header[10];
+
+ /* seek to the beginning of the stream */
+ if (fseek(fpStream, 0, SEEK_SET) != 0) {
+ return -2; /* not seekable, abort */
+ }
+ /* read 10 bytes in case there's an ID3 version 2 header here */
+ nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream);
+ if (nbytes != sizeof(id3v2Header)) {
+ return -3; /* not readable, maybe opened Write-Only */
+ }
+ /* does the stream begin with the ID3 version 2 file identifier? */
+ if (!strncmp((char *) id3v2Header, "ID3", 3)) {
+ /* the tag size (minus the 10-byte header) is encoded into four
+ * bytes where the most significant bit is clear in each byte */
+ id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21)
+ | ((id3v2Header[7] & 0x7f) << 14)
+ | ((id3v2Header[8] & 0x7f) << 7)
+ | (id3v2Header[9] & 0x7f))
+ + sizeof id3v2Header;
+ }
+ else {
+ /* no ID3 version 2 tag in this stream */
+ id3v2TagSize = 0;
+ }
+ return id3v2TagSize;
+}
+
+
+
+size_t
+lame_get_lametag_frame(lame_global_flags const *gfp, unsigned char *buffer, size_t size)
+{
+ lame_internal_flags *gfc;
+ SessionConfig_t const *cfg;
+ unsigned long stream_size;
+ unsigned int nStreamIndex;
+ uint8_t btToc[NUMTOCENTRIES];
+
+ if (gfp == 0) {
+ return 0;
+ }
+ gfc = gfp->internal_flags;
+ if (gfc == 0) {
+ return 0;
+ }
+ if (!is_lame_internal_flags_valid(gfc)) {
+ return 0;
+ }
+ cfg = &gfc->cfg;
+ if (cfg->write_lame_tag == 0) {
+ return 0;
+ }
+ if (gfc->VBR_seek_table.pos <= 0) {
+ return 0;
+ }
+ if (size < gfc->VBR_seek_table.TotalFrameSize) {
+ return gfc->VBR_seek_table.TotalFrameSize;
+ }
+ if (buffer == 0) {
+ return 0;
+ }
+
+ memset(buffer, 0, gfc->VBR_seek_table.TotalFrameSize);
+
+ /* 4 bytes frame header */
+
+ setLameTagFrameHeader(gfc, buffer);
+
+ /* Clear all TOC entries */
+ memset(btToc, 0, sizeof(btToc));
+
+ if (cfg->free_format) {
+ int i;
+ for (i = 1; i < NUMTOCENTRIES; ++i)
+ btToc[i] = 255 * i / 100;
+ }
+ else {
+ Xing_seek_table(&gfc->VBR_seek_table, btToc);
+ }
+#ifdef DEBUG_VBR_SEEKING_TABLE
+ print_seeking(btToc);
+#endif
+
+ /* Start writing the tag after the zero frame */
+ nStreamIndex = cfg->sideinfo_len;
+ /* note! Xing header specifies that Xing data goes in the
+ * ancillary data with NO ERROR PROTECTION. If error protecton
+ * in enabled, the Xing data still starts at the same offset,
+ * and now it is in sideinfo data block, and thus will not
+ * decode correctly by non-Xing tag aware players */
+ if (cfg->error_protection)
+ nStreamIndex -= 2;
+
+ /* Put Vbr tag */
+ if (cfg->vbr == vbr_off) {
+ buffer[nStreamIndex++] = VBRTag1[0];
+ buffer[nStreamIndex++] = VBRTag1[1];
+ buffer[nStreamIndex++] = VBRTag1[2];
+ buffer[nStreamIndex++] = VBRTag1[3];
+
+ }
+ else {
+ buffer[nStreamIndex++] = VBRTag0[0];
+ buffer[nStreamIndex++] = VBRTag0[1];
+ buffer[nStreamIndex++] = VBRTag0[2];
+ buffer[nStreamIndex++] = VBRTag0[3];
+ }
+
+ /* Put header flags */
+ CreateI4(&buffer[nStreamIndex], FRAMES_FLAG + BYTES_FLAG + TOC_FLAG + VBR_SCALE_FLAG);
+ nStreamIndex += 4;
+
+ /* Put Total Number of frames */
+ CreateI4(&buffer[nStreamIndex], gfc->VBR_seek_table.nVbrNumFrames);
+ nStreamIndex += 4;
+
+ /* Put total audio stream size, including Xing/LAME Header */
+ stream_size = gfc->VBR_seek_table.nBytesWritten + gfc->VBR_seek_table.TotalFrameSize;
+ CreateI4(&buffer[nStreamIndex], stream_size);
+ nStreamIndex += 4;
+
+ /* Put TOC */
+ memcpy(&buffer[nStreamIndex], btToc, sizeof(btToc));
+ nStreamIndex += sizeof(btToc);
+
+
+ if (cfg->error_protection) {
+ /* (jo) error_protection: add crc16 information to header */
+ CRC_writeheader(gfc, (char *) buffer);
+ }
+ {
+ /*work out CRC so far: initially crc = 0 */
+ uint16_t crc = 0x00;
+ unsigned int i;
+ for (i = 0; i < nStreamIndex; i++)
+ crc = CRC_update_lookup(buffer[i], crc);
+ /*Put LAME VBR info */
+ nStreamIndex += PutLameVBR(gfp, stream_size, buffer + nStreamIndex, crc);
+ }
+
+#ifdef DEBUG_VBRTAG
+ {
+ VBRTAGDATA TestHeader;
+ GetVbrTag(&TestHeader, buffer);
+ }
+#endif
+
+ return gfc->VBR_seek_table.TotalFrameSize;
+}
+
+/***********************************************************************
+ *
+ * PutVbrTag: Write final VBR tag to the file
+ * Paramters:
+ * lpszFileName: filename of MP3 bit stream
+ * nVbrScale : encoder quality indicator (0..100)
+ ****************************************************************************
+ */
+
+int
+PutVbrTag(lame_global_flags const *gfp, FILE * fpStream)
+{
+ lame_internal_flags *gfc = gfp->internal_flags;
+
+ long lFileSize;
+ long id3v2TagSize;
+ size_t nbytes;
+ uint8_t buffer[MAXFRAMESIZE];
+
+ if (gfc->VBR_seek_table.pos <= 0)
+ return -1;
+
+ /* Seek to end of file */
+ fseek(fpStream, 0, SEEK_END);
+
+ /* Get file size */
+ lFileSize = ftell(fpStream);
+
+ /* Abort if file has zero length. Yes, it can happen :) */
+ if (lFileSize == 0)
+ return -1;
+
+ /*
+ * The VBR tag may NOT be located at the beginning of the stream.
+ * If an ID3 version 2 tag was added, then it must be skipped to write
+ * the VBR tag data.
+ */
+
+ id3v2TagSize = skipId3v2(fpStream);
+
+ if (id3v2TagSize < 0) {
+ return id3v2TagSize;
+ }
+
+ /*Seek to the beginning of the stream */
+ fseek(fpStream, id3v2TagSize, SEEK_SET);
+
+ nbytes = lame_get_lametag_frame(gfp, buffer, sizeof(buffer));
+ if (nbytes > sizeof(buffer)) {
+ return -1;
+ }
+
+ if (nbytes < 1) {
+ return 0;
+ }
+
+ /* Put it all to disk again */
+ if (fwrite(buffer, nbytes, 1, fpStream) != 1) {
+ return -1;
+ }
+
+ return 0; /* success */
+}
diff --git a/pkg/lame/clame/VbrTag.h b/pkg/lame/clame/VbrTag.h
new file mode 100644
index 0000000..406af36
--- /dev/null
+++ b/pkg/lame/clame/VbrTag.h
@@ -0,0 +1,79 @@
+/*
+ * Xing VBR tagging for LAME.
+ *
+ * Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_VRBTAG_H
+#define LAME_VRBTAG_H
+
+
+/* -----------------------------------------------------------
+ * A Vbr header may be present in the ancillary
+ * data field of the first frame of an mp3 bitstream
+ * The Vbr header (optionally) contains
+ * frames total number of audio frames in the bitstream
+ * bytes total number of bytes in the bitstream
+ * toc table of contents
+
+ * toc (table of contents) gives seek points
+ * for random access
+ * the ith entry determines the seek point for
+ * i-percent duration
+ * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
+ * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes
+ */
+
+
+#define FRAMES_FLAG 0x0001
+#define BYTES_FLAG 0x0002
+#define TOC_FLAG 0x0004
+#define VBR_SCALE_FLAG 0x0008
+
+#define NUMTOCENTRIES 100
+
+#ifndef lame_internal_flags_defined
+#define lame_internal_flags_defined
+struct lame_internal_flags;
+typedef struct lame_internal_flags lame_internal_flags;
+#endif
+
+
+/*structure to receive extracted header */
+/* toc may be NULL*/
+typedef struct {
+ int h_id; /* from MPEG header, 0=MPEG2, 1=MPEG1 */
+ int samprate; /* determined from MPEG header */
+ int flags; /* from Vbr header data */
+ int frames; /* total bit stream frames from Vbr header data */
+ int bytes; /* total bit stream bytes from Vbr header data */
+ int vbr_scale; /* encoded vbr scale from Vbr header data */
+ unsigned char toc[NUMTOCENTRIES]; /* may be NULL if toc not desired */
+ int headersize; /* size of VBR header, in bytes */
+ int enc_delay; /* encoder delay */
+ int enc_padding; /* encoder paddign added at end of stream */
+} VBRTAGDATA;
+
+int GetVbrTag(VBRTAGDATA * pTagData, const unsigned char *buf);
+
+int InitVbrTag(lame_global_flags * gfp);
+int PutVbrTag(lame_global_flags const *gfp, FILE * fid);
+void AddVbrFrame(lame_internal_flags * gfc);
+void UpdateMusicCRC(uint16_t * crc, const unsigned char *buffer, int size);
+
+#endif
diff --git a/pkg/lame/clame/bitstream.c b/pkg/lame/clame/bitstream.c
new file mode 100644
index 0000000..aa35915
--- /dev/null
+++ b/pkg/lame/clame/bitstream.c
@@ -0,0 +1,1111 @@
+/*
+ * MP3 bitstream Output interface for LAME
+ *
+ * Copyright (c) 1999-2000 Mark Taylor
+ * Copyright (c) 1999-2002 Takehiro Tominaga
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * $Id: bitstream.c,v 1.99 2017/08/31 14:14:46 robert Exp $
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include
+#include
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "tables.h"
+#include "quantize_pvt.h"
+#include "lame_global_flags.h"
+#include "gain_analysis.h"
+#include "VbrTag.h"
+#include "bitstream.h"
+#include "tables.h"
+
+
+
+/* unsigned int is at least this large: */
+/* we work with ints, so when doing bit manipulation, we limit
+ * ourselves to MAX_LENGTH-2 just to be on the safe side */
+#define MAX_LENGTH 32
+
+
+
+#ifdef DEBUG
+static int hogege;
+#endif
+
+
+
+static int
+calcFrameLength(SessionConfig_t const *const cfg, int kbps, int pad)
+{
+ return 8 * ((cfg->version + 1) * 72000 * kbps / cfg->samplerate_out + pad);
+}
+
+
+/***********************************************************************
+ * compute bitsperframe and mean_bits for a layer III frame
+ **********************************************************************/
+int
+getframebits(const lame_internal_flags * gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t const *const eov = &gfc->ov_enc;
+ int bit_rate;
+
+ /* get bitrate in kbps [?] */
+ if (eov->bitrate_index)
+ bit_rate = bitrate_table[cfg->version][eov->bitrate_index];
+ else
+ bit_rate = cfg->avg_bitrate;
+ /*assert(bit_rate <= 550); */
+ assert(8 <= bit_rate && bit_rate <= 640);
+
+ /* main encoding routine toggles padding on and off */
+ /* one Layer3 Slot consists of 8 bits */
+ return calcFrameLength(cfg, bit_rate, eov->padding);
+}
+
+int
+get_max_frame_buffer_size_by_constraint(SessionConfig_t const * cfg, int constraint)
+{
+ int maxmp3buf = 0;
+ if (cfg->avg_bitrate > 320) {
+ /* in freeformat the buffer is constant */
+ if (constraint == MDB_STRICT_ISO) {
+ maxmp3buf = calcFrameLength(cfg, cfg->avg_bitrate, 0);
+ }
+ else {
+ /* maximum allowed bits per granule are 7680 */
+ maxmp3buf = 7680 * (cfg->version + 1);
+ }
+ }
+ else {
+ int max_kbps;
+ if (cfg->samplerate_out < 16000) {
+ max_kbps = bitrate_table[cfg->version][8]; /* default: allow 64 kbps (MPEG-2.5) */
+ }
+ else {
+ max_kbps = bitrate_table[cfg->version][14];
+ }
+ switch (constraint)
+ {
+ default:
+ case MDB_DEFAULT:
+ /* Bouvigne suggests this more lax interpretation of the ISO doc instead of using 8*960. */
+ /* All mp3 decoders should have enough buffer to handle this value: size of a 320kbps 32kHz frame */
+ maxmp3buf = 8 * 1440;
+ break;
+ case MDB_STRICT_ISO:
+ maxmp3buf = calcFrameLength(cfg, max_kbps, 0);
+ break;
+ case MDB_MAXIMUM:
+ maxmp3buf = 7680 * (cfg->version + 1);
+ break;
+ }
+ }
+ return maxmp3buf;
+}
+
+
+static void
+putheader_bits(lame_internal_flags * gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ Bit_stream_struc *bs = &gfc->bs;
+#ifdef DEBUG
+ hogege += cfg->sideinfo_len * 8;
+#endif
+ memcpy(&bs->buf[bs->buf_byte_idx], esv->header[esv->w_ptr].buf, cfg->sideinfo_len);
+ bs->buf_byte_idx += cfg->sideinfo_len;
+ bs->totbit += cfg->sideinfo_len * 8;
+ esv->w_ptr = (esv->w_ptr + 1) & (MAX_HEADER_BUF - 1);
+}
+
+
+
+
+/*write j bits into the bit stream */
+inline static void
+putbits2(lame_internal_flags * gfc, int val, int j)
+{
+ EncStateVar_t const *const esv = &gfc->sv_enc;
+ Bit_stream_struc *bs;
+ bs = &gfc->bs;
+
+ assert(j < MAX_LENGTH - 2);
+
+ while (j > 0) {
+ int k;
+ if (bs->buf_bit_idx == 0) {
+ bs->buf_bit_idx = 8;
+ bs->buf_byte_idx++;
+ assert(bs->buf_byte_idx < BUFFER_SIZE);
+ assert(esv->header[esv->w_ptr].write_timing >= bs->totbit);
+ if (esv->header[esv->w_ptr].write_timing == bs->totbit) {
+ putheader_bits(gfc);
+ }
+ bs->buf[bs->buf_byte_idx] = 0;
+ }
+
+ k = Min(j, bs->buf_bit_idx);
+ j -= k;
+
+ bs->buf_bit_idx -= k;
+
+ assert(j < MAX_LENGTH); /* 32 too large on 32 bit machines */
+ assert(bs->buf_bit_idx < MAX_LENGTH);
+
+ bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx);
+ bs->totbit += k;
+ }
+}
+
+/*write j bits into the bit stream, ignoring frame headers */
+inline static void
+putbits_noheaders(lame_internal_flags * gfc, int val, int j)
+{
+ Bit_stream_struc *bs;
+ bs = &gfc->bs;
+
+ assert(j < MAX_LENGTH - 2);
+
+ while (j > 0) {
+ int k;
+ if (bs->buf_bit_idx == 0) {
+ bs->buf_bit_idx = 8;
+ bs->buf_byte_idx++;
+ assert(bs->buf_byte_idx < BUFFER_SIZE);
+ bs->buf[bs->buf_byte_idx] = 0;
+ }
+
+ k = Min(j, bs->buf_bit_idx);
+ j -= k;
+
+ bs->buf_bit_idx -= k;
+
+ assert(j < MAX_LENGTH); /* 32 too large on 32 bit machines */
+ assert(bs->buf_bit_idx < MAX_LENGTH);
+
+ bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx);
+ bs->totbit += k;
+ }
+}
+
+
+/*
+ Some combinations of bitrate, Fs, and stereo make it impossible to stuff
+ out a frame using just main_data, due to the limited number of bits to
+ indicate main_data_length. In these situations, we put stuffing bits into
+ the ancillary data...
+*/
+
+inline static void
+drain_into_ancillary(lame_internal_flags * gfc, int remainingBits)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int i;
+ assert(remainingBits >= 0);
+
+ if (remainingBits >= 8) {
+ putbits2(gfc, 0x4c, 8);
+ remainingBits -= 8;
+ }
+ if (remainingBits >= 8) {
+ putbits2(gfc, 0x41, 8);
+ remainingBits -= 8;
+ }
+ if (remainingBits >= 8) {
+ putbits2(gfc, 0x4d, 8);
+ remainingBits -= 8;
+ }
+ if (remainingBits >= 8) {
+ putbits2(gfc, 0x45, 8);
+ remainingBits -= 8;
+ }
+
+ if (remainingBits >= 32) {
+ const char *const version = get_lame_short_version();
+ if (remainingBits >= 32)
+ for (i = 0; i < (int) strlen(version) && remainingBits >= 8; ++i) {
+ remainingBits -= 8;
+ putbits2(gfc, version[i], 8);
+ }
+ }
+
+ for (; remainingBits >= 1; remainingBits -= 1) {
+ putbits2(gfc, esv->ancillary_flag, 1);
+ esv->ancillary_flag ^= !cfg->disable_reservoir;
+ }
+
+ assert(remainingBits == 0);
+
+}
+
+/*write N bits into the header */
+inline static void
+writeheader(lame_internal_flags * gfc, int val, int j)
+{
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int ptr = esv->header[esv->h_ptr].ptr;
+
+ while (j > 0) {
+ int const k = Min(j, 8 - (ptr & 7));
+ j -= k;
+ assert(j < MAX_LENGTH); /* >> 32 too large for 32 bit machines */
+ esv->header[esv->h_ptr].buf[ptr >> 3]
+ |= ((val >> j)) << (8 - (ptr & 7) - k);
+ ptr += k;
+ }
+ esv->header[esv->h_ptr].ptr = ptr;
+}
+
+
+static int
+CRC_update(int value, int crc)
+{
+ int i;
+ value <<= 8;
+ for (i = 0; i < 8; i++) {
+ value <<= 1;
+ crc <<= 1;
+
+ if (((crc ^ value) & 0x10000))
+ crc ^= CRC16_POLYNOMIAL;
+ }
+ return crc;
+}
+
+
+void
+CRC_writeheader(lame_internal_flags const *gfc, char *header)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int crc = 0xffff; /* (jo) init crc16 for error_protection */
+ int i;
+
+ crc = CRC_update(((unsigned char *) header)[2], crc);
+ crc = CRC_update(((unsigned char *) header)[3], crc);
+ for (i = 6; i < cfg->sideinfo_len; i++) {
+ crc = CRC_update(((unsigned char *) header)[i], crc);
+ }
+
+ header[4] = crc >> 8;
+ header[5] = crc & 255;
+}
+
+inline static void
+encodeSideInfo2(lame_internal_flags * gfc, int bitsPerFrame)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t const *const eov = &gfc->ov_enc;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ III_side_info_t *l3_side;
+ int gr, ch;
+
+ l3_side = &gfc->l3_side;
+ esv->header[esv->h_ptr].ptr = 0;
+ memset(esv->header[esv->h_ptr].buf, 0, cfg->sideinfo_len);
+ if (cfg->samplerate_out < 16000)
+ writeheader(gfc, 0xffe, 12);
+ else
+ writeheader(gfc, 0xfff, 12);
+ writeheader(gfc, (cfg->version), 1);
+ writeheader(gfc, 4 - 3, 2);
+ writeheader(gfc, (!cfg->error_protection), 1);
+ writeheader(gfc, (eov->bitrate_index), 4);
+ writeheader(gfc, (cfg->samplerate_index), 2);
+ writeheader(gfc, (eov->padding), 1);
+ writeheader(gfc, (cfg->extension), 1);
+ writeheader(gfc, (cfg->mode), 2);
+ writeheader(gfc, (eov->mode_ext), 2);
+ writeheader(gfc, (cfg->copyright), 1);
+ writeheader(gfc, (cfg->original), 1);
+ writeheader(gfc, (cfg->emphasis), 2);
+ if (cfg->error_protection) {
+ writeheader(gfc, 0, 16); /* dummy */
+ }
+
+ if (cfg->version == 1) {
+ /* MPEG1 */
+ assert(l3_side->main_data_begin >= 0);
+ writeheader(gfc, (l3_side->main_data_begin), 9);
+
+ if (cfg->channels_out == 2)
+ writeheader(gfc, l3_side->private_bits, 3);
+ else
+ writeheader(gfc, l3_side->private_bits, 5);
+
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ int band;
+ for (band = 0; band < 4; band++) {
+ writeheader(gfc, l3_side->scfsi[ch][band], 1);
+ }
+ }
+
+ for (gr = 0; gr < 2; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info *const gi = &l3_side->tt[gr][ch];
+ writeheader(gfc, gi->part2_3_length + gi->part2_length, 12);
+ writeheader(gfc, gi->big_values / 2, 9);
+ writeheader(gfc, gi->global_gain, 8);
+ writeheader(gfc, gi->scalefac_compress, 4);
+
+ if (gi->block_type != NORM_TYPE) {
+ writeheader(gfc, 1, 1); /* window_switching_flag */
+ writeheader(gfc, gi->block_type, 2);
+ writeheader(gfc, gi->mixed_block_flag, 1);
+
+ if (gi->table_select[0] == 14)
+ gi->table_select[0] = 16;
+ writeheader(gfc, gi->table_select[0], 5);
+ if (gi->table_select[1] == 14)
+ gi->table_select[1] = 16;
+ writeheader(gfc, gi->table_select[1], 5);
+
+ writeheader(gfc, gi->subblock_gain[0], 3);
+ writeheader(gfc, gi->subblock_gain[1], 3);
+ writeheader(gfc, gi->subblock_gain[2], 3);
+ }
+ else {
+ writeheader(gfc, 0, 1); /* window_switching_flag */
+ if (gi->table_select[0] == 14)
+ gi->table_select[0] = 16;
+ writeheader(gfc, gi->table_select[0], 5);
+ if (gi->table_select[1] == 14)
+ gi->table_select[1] = 16;
+ writeheader(gfc, gi->table_select[1], 5);
+ if (gi->table_select[2] == 14)
+ gi->table_select[2] = 16;
+ writeheader(gfc, gi->table_select[2], 5);
+
+ assert(0 <= gi->region0_count && gi->region0_count < 16);
+ assert(0 <= gi->region1_count && gi->region1_count < 8);
+ writeheader(gfc, gi->region0_count, 4);
+ writeheader(gfc, gi->region1_count, 3);
+ }
+ writeheader(gfc, gi->preflag, 1);
+ writeheader(gfc, gi->scalefac_scale, 1);
+ writeheader(gfc, gi->count1table_select, 1);
+ }
+ }
+ }
+ else {
+ /* MPEG2 */
+ assert(l3_side->main_data_begin >= 0);
+ writeheader(gfc, (l3_side->main_data_begin), 8);
+ writeheader(gfc, l3_side->private_bits, cfg->channels_out);
+
+ gr = 0;
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info *const gi = &l3_side->tt[gr][ch];
+ writeheader(gfc, gi->part2_3_length + gi->part2_length, 12);
+ writeheader(gfc, gi->big_values / 2, 9);
+ writeheader(gfc, gi->global_gain, 8);
+ writeheader(gfc, gi->scalefac_compress, 9);
+
+ if (gi->block_type != NORM_TYPE) {
+ writeheader(gfc, 1, 1); /* window_switching_flag */
+ writeheader(gfc, gi->block_type, 2);
+ writeheader(gfc, gi->mixed_block_flag, 1);
+
+ if (gi->table_select[0] == 14)
+ gi->table_select[0] = 16;
+ writeheader(gfc, gi->table_select[0], 5);
+ if (gi->table_select[1] == 14)
+ gi->table_select[1] = 16;
+ writeheader(gfc, gi->table_select[1], 5);
+
+ writeheader(gfc, gi->subblock_gain[0], 3);
+ writeheader(gfc, gi->subblock_gain[1], 3);
+ writeheader(gfc, gi->subblock_gain[2], 3);
+ }
+ else {
+ writeheader(gfc, 0, 1); /* window_switching_flag */
+ if (gi->table_select[0] == 14)
+ gi->table_select[0] = 16;
+ writeheader(gfc, gi->table_select[0], 5);
+ if (gi->table_select[1] == 14)
+ gi->table_select[1] = 16;
+ writeheader(gfc, gi->table_select[1], 5);
+ if (gi->table_select[2] == 14)
+ gi->table_select[2] = 16;
+ writeheader(gfc, gi->table_select[2], 5);
+
+ assert(0 <= gi->region0_count && gi->region0_count < 16);
+ assert(0 <= gi->region1_count && gi->region1_count < 8);
+ writeheader(gfc, gi->region0_count, 4);
+ writeheader(gfc, gi->region1_count, 3);
+ }
+
+ writeheader(gfc, gi->scalefac_scale, 1);
+ writeheader(gfc, gi->count1table_select, 1);
+ }
+ }
+
+ if (cfg->error_protection) {
+ /* (jo) error_protection: add crc16 information to header */
+ CRC_writeheader(gfc, esv->header[esv->h_ptr].buf);
+ }
+
+ {
+ int const old = esv->h_ptr;
+ assert(esv->header[old].ptr == cfg->sideinfo_len * 8);
+
+ esv->h_ptr = (old + 1) & (MAX_HEADER_BUF - 1);
+ esv->header[esv->h_ptr].write_timing = esv->header[old].write_timing + bitsPerFrame;
+
+ if (esv->h_ptr == esv->w_ptr) {
+ /* yikes! we are out of header buffer space */
+ ERRORF(gfc, "Error: MAX_HEADER_BUF too small in bitstream.c \n");
+ }
+
+ }
+}
+
+
+inline static int
+huffman_coder_count1(lame_internal_flags * gfc, gr_info const *gi)
+{
+ /* Write count1 area */
+ struct huffcodetab const *const h = &ht[gi->count1table_select + 32];
+ int i, bits = 0;
+#ifdef DEBUG
+ int gegebo = gfc->bs.totbit;
+#endif
+
+ int const *ix = &gi->l3_enc[gi->big_values];
+ FLOAT const *xr = &gi->xr[gi->big_values];
+ assert(gi->count1table_select < 2);
+
+ for (i = (gi->count1 - gi->big_values) / 4; i > 0; --i) {
+ int huffbits = 0;
+ int p = 0, v;
+
+ v = ix[0];
+ if (v) {
+ p += 8;
+ if (xr[0] < 0.0f)
+ huffbits++;
+ assert(v <= 1);
+ }
+
+ v = ix[1];
+ if (v) {
+ p += 4;
+ huffbits *= 2;
+ if (xr[1] < 0.0f)
+ huffbits++;
+ assert(v <= 1);
+ }
+
+ v = ix[2];
+ if (v) {
+ p += 2;
+ huffbits *= 2;
+ if (xr[2] < 0.0f)
+ huffbits++;
+ assert(v <= 1);
+ }
+
+ v = ix[3];
+ if (v) {
+ p++;
+ huffbits *= 2;
+ if (xr[3] < 0.0f)
+ huffbits++;
+ assert(v <= 1);
+ }
+
+ ix += 4;
+ xr += 4;
+ putbits2(gfc, huffbits + h->table[p], h->hlen[p]);
+ bits += h->hlen[p];
+ }
+#ifdef DEBUG
+ DEBUGF(gfc, "count1: real: %ld counted:%d (bigv %d count1len %d)\n",
+ gfc->bs.totbit - gegebo, gi->count1bits, gi->big_values, gi->count1);
+#endif
+ return bits;
+}
+
+
+
+/*
+ Implements the pseudocode of page 98 of the IS
+ */
+inline static int
+Huffmancode(lame_internal_flags * const gfc, const unsigned int tableindex,
+ int start, int end, gr_info const *gi)
+{
+ struct huffcodetab const *const h = &ht[tableindex];
+ unsigned int const linbits = h->xlen;
+ int i, bits = 0;
+
+ assert(tableindex < 32u);
+ if (!tableindex)
+ return bits;
+
+ for (i = start; i < end; i += 2) {
+ int16_t cbits = 0;
+ uint16_t xbits = 0;
+ unsigned int xlen = h->xlen;
+ unsigned int ext = 0;
+ unsigned int x1 = gi->l3_enc[i];
+ unsigned int x2 = gi->l3_enc[i + 1];
+
+ assert(gi->l3_enc[i] >= 0);
+ assert(gi->l3_enc[i+1] >= 0);
+
+ if (x1 != 0u) {
+ if (gi->xr[i] < 0.0f)
+ ext++;
+ cbits--;
+ }
+
+ if (tableindex > 15u) {
+ /* use ESC-words */
+ if (x1 >= 15u) {
+ uint16_t const linbits_x1 = x1 - 15u;
+ assert(linbits_x1 <= h->linmax);
+ ext |= linbits_x1 << 1u;
+ xbits = linbits;
+ x1 = 15u;
+ }
+
+ if (x2 >= 15u) {
+ uint16_t const linbits_x2 = x2 - 15u;
+ assert(linbits_x2 <= h->linmax);
+ ext <<= linbits;
+ ext |= linbits_x2;
+ xbits += linbits;
+ x2 = 15u;
+ }
+ xlen = 16;
+ }
+
+ if (x2 != 0u) {
+ ext <<= 1;
+ if (gi->xr[i + 1] < 0.0f)
+ ext++;
+ cbits--;
+ }
+
+ assert((x1 | x2) < 16u);
+
+ x1 = x1 * xlen + x2;
+ xbits -= cbits;
+ cbits += h->hlen[x1];
+
+ assert(cbits <= MAX_LENGTH);
+ assert(xbits <= MAX_LENGTH);
+
+ putbits2(gfc, h->table[x1], cbits);
+ putbits2(gfc, (int)ext, xbits);
+ bits += cbits + xbits;
+ }
+ return bits;
+}
+
+/*
+ Note the discussion of huffmancodebits() on pages 28
+ and 29 of the IS, as well as the definitions of the side
+ information on pages 26 and 27.
+ */
+static int
+ShortHuffmancodebits(lame_internal_flags * gfc, gr_info const *gi)
+{
+ int bits;
+ int region1Start;
+
+ region1Start = 3 * gfc->scalefac_band.s[3];
+ if (region1Start > gi->big_values)
+ region1Start = gi->big_values;
+
+ /* short blocks do not have a region2 */
+ bits = Huffmancode(gfc, gi->table_select[0], 0, region1Start, gi);
+ bits += Huffmancode(gfc, gi->table_select[1], region1Start, gi->big_values, gi);
+ return bits;
+}
+
+static int
+LongHuffmancodebits(lame_internal_flags * gfc, gr_info const *gi)
+{
+ unsigned int i;
+ int bigvalues, bits;
+ int region1Start, region2Start;
+
+ bigvalues = gi->big_values;
+ assert(0 <= bigvalues && bigvalues <= 576);
+
+ assert(gi->region0_count >= -1);
+ assert(gi->region1_count >= -1);
+ i = gi->region0_count + 1;
+ assert((size_t) i < dimension_of(gfc->scalefac_band.l));
+ region1Start = gfc->scalefac_band.l[i];
+ i += gi->region1_count + 1;
+ assert((size_t) i < dimension_of(gfc->scalefac_band.l));
+ region2Start = gfc->scalefac_band.l[i];
+
+ if (region1Start > bigvalues)
+ region1Start = bigvalues;
+
+ if (region2Start > bigvalues)
+ region2Start = bigvalues;
+
+ bits = Huffmancode(gfc, gi->table_select[0], 0, region1Start, gi);
+ bits += Huffmancode(gfc, gi->table_select[1], region1Start, region2Start, gi);
+ bits += Huffmancode(gfc, gi->table_select[2], region2Start, bigvalues, gi);
+ return bits;
+}
+
+inline static int
+writeMainData(lame_internal_flags * const gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ III_side_info_t const *const l3_side = &gfc->l3_side;
+ int gr, ch, sfb, data_bits, tot_bits = 0;
+
+ if (cfg->version == 1) {
+ /* MPEG 1 */
+ for (gr = 0; gr < 2; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info const *const gi = &l3_side->tt[gr][ch];
+ int const slen1 = slen1_tab[gi->scalefac_compress];
+ int const slen2 = slen2_tab[gi->scalefac_compress];
+ data_bits = 0;
+#ifdef DEBUG
+ hogege = gfc->bs.totbit;
+#endif
+ for (sfb = 0; sfb < gi->sfbdivide; sfb++) {
+ if (gi->scalefac[sfb] == -1)
+ continue; /* scfsi is used */
+ putbits2(gfc, gi->scalefac[sfb], slen1);
+ data_bits += slen1;
+ }
+ for (; sfb < gi->sfbmax; sfb++) {
+ if (gi->scalefac[sfb] == -1)
+ continue; /* scfsi is used */
+ putbits2(gfc, gi->scalefac[sfb], slen2);
+ data_bits += slen2;
+ }
+ assert(data_bits == gi->part2_length);
+
+ if (gi->block_type == SHORT_TYPE) {
+ data_bits += ShortHuffmancodebits(gfc, gi);
+ }
+ else {
+ data_bits += LongHuffmancodebits(gfc, gi);
+ }
+ data_bits += huffman_coder_count1(gfc, gi);
+#ifdef DEBUG
+ DEBUGF(gfc, "<%ld> ", gfc->bs.totbit - hogege);
+#endif
+ /* does bitcount in quantize.c agree with actual bit count? */
+ assert(data_bits == gi->part2_3_length + gi->part2_length);
+ tot_bits += data_bits;
+ } /* for ch */
+ } /* for gr */
+ }
+ else {
+ /* MPEG 2 */
+ gr = 0;
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info const *const gi = &l3_side->tt[gr][ch];
+ int i, sfb_partition, scale_bits = 0;
+ assert(gi->sfb_partition_table);
+ data_bits = 0;
+#ifdef DEBUG
+ hogege = gfc->bs.totbit;
+#endif
+ sfb = 0;
+ sfb_partition = 0;
+
+ if (gi->block_type == SHORT_TYPE) {
+ for (; sfb_partition < 4; sfb_partition++) {
+ int const sfbs = gi->sfb_partition_table[sfb_partition] / 3;
+ int const slen = gi->slen[sfb_partition];
+ for (i = 0; i < sfbs; i++, sfb++) {
+ putbits2(gfc, Max(gi->scalefac[sfb * 3 + 0], 0), slen);
+ putbits2(gfc, Max(gi->scalefac[sfb * 3 + 1], 0), slen);
+ putbits2(gfc, Max(gi->scalefac[sfb * 3 + 2], 0), slen);
+ scale_bits += 3 * slen;
+ }
+ }
+ data_bits += ShortHuffmancodebits(gfc, gi);
+ }
+ else {
+ for (; sfb_partition < 4; sfb_partition++) {
+ int const sfbs = gi->sfb_partition_table[sfb_partition];
+ int const slen = gi->slen[sfb_partition];
+ for (i = 0; i < sfbs; i++, sfb++) {
+ putbits2(gfc, Max(gi->scalefac[sfb], 0), slen);
+ scale_bits += slen;
+ }
+ }
+ data_bits += LongHuffmancodebits(gfc, gi);
+ }
+ data_bits += huffman_coder_count1(gfc, gi);
+#ifdef DEBUG
+ DEBUGF(gfc, "<%ld> ", gfc->bs.totbit - hogege);
+#endif
+ /* does bitcount in quantize.c agree with actual bit count? */
+ assert(data_bits == gi->part2_3_length);
+ assert(scale_bits == gi->part2_length);
+ tot_bits += scale_bits + data_bits;
+ } /* for ch */
+ } /* for gf */
+ return tot_bits;
+} /* main_data */
+
+
+
+/* compute the number of bits required to flush all mp3 frames
+ currently in the buffer. This should be the same as the
+ reservoir size. Only call this routine between frames - i.e.
+ only after all headers and data have been added to the buffer
+ by format_bitstream().
+
+ Also compute total_bits_output =
+ size of mp3 buffer (including frame headers which may not
+ have yet been send to the mp3 buffer) +
+ number of bits needed to flush all mp3 frames.
+
+ total_bytes_output is the size of the mp3 output buffer if
+ lame_encode_flush_nogap() was called right now.
+
+ */
+int
+compute_flushbits(const lame_internal_flags * gfc, int *total_bytes_output)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t const *const esv = &gfc->sv_enc;
+ int flushbits, remaining_headers;
+ int bitsPerFrame;
+ int last_ptr, first_ptr;
+ first_ptr = esv->w_ptr; /* first header to add to bitstream */
+ last_ptr = esv->h_ptr - 1; /* last header to add to bitstream */
+ if (last_ptr == -1)
+ last_ptr = MAX_HEADER_BUF - 1;
+
+ /* add this many bits to bitstream so we can flush all headers */
+ flushbits = esv->header[last_ptr].write_timing - gfc->bs.totbit;
+ *total_bytes_output = flushbits;
+
+ if (flushbits >= 0) {
+ /* if flushbits >= 0, some headers have not yet been written */
+ /* reduce flushbits by the size of the headers */
+ remaining_headers = 1 + last_ptr - first_ptr;
+ if (last_ptr < first_ptr)
+ remaining_headers = 1 + last_ptr - first_ptr + MAX_HEADER_BUF;
+ flushbits -= remaining_headers * 8 * cfg->sideinfo_len;
+ }
+
+
+ /* finally, add some bits so that the last frame is complete
+ * these bits are not necessary to decode the last frame, but
+ * some decoders will ignore last frame if these bits are missing
+ */
+ bitsPerFrame = getframebits(gfc);
+ flushbits += bitsPerFrame;
+ *total_bytes_output += bitsPerFrame;
+ /* round up: */
+ if (*total_bytes_output % 8)
+ *total_bytes_output = 1 + (*total_bytes_output / 8);
+ else
+ *total_bytes_output = (*total_bytes_output / 8);
+ *total_bytes_output += gfc->bs.buf_byte_idx + 1;
+
+
+ if (flushbits < 0) {
+#if 0
+ /* if flushbits < 0, this would mean that the buffer looks like:
+ * (data...) last_header (data...) (extra data that should not be here...)
+ */
+ DEBUGF(gfc, "last header write_timing = %i \n", esv->header[last_ptr].write_timing);
+ DEBUGF(gfc, "first header write_timing = %i \n", esv->header[first_ptr].write_timing);
+ DEBUGF(gfc, "bs.totbit: %i \n", gfc->bs.totbit);
+ DEBUGF(gfc, "first_ptr, last_ptr %i %i \n", first_ptr, last_ptr);
+ DEBUGF(gfc, "remaining_headers = %i \n", remaining_headers);
+ DEBUGF(gfc, "bitsperframe: %i \n", bitsPerFrame);
+ DEBUGF(gfc, "sidelen: %i \n", cfg->sideinfo_len);
+#endif
+ ERRORF(gfc, "strange error flushing buffer ... \n");
+ }
+ return flushbits;
+}
+
+
+void
+flush_bitstream(lame_internal_flags * gfc)
+{
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ III_side_info_t *l3_side;
+ int nbytes;
+ int flushbits;
+ int last_ptr = esv->h_ptr - 1; /* last header to add to bitstream */
+ if (last_ptr == -1)
+ last_ptr = MAX_HEADER_BUF - 1;
+ l3_side = &gfc->l3_side;
+
+
+ if ((flushbits = compute_flushbits(gfc, &nbytes)) < 0)
+ return;
+ drain_into_ancillary(gfc, flushbits);
+
+ /* check that the 100% of the last frame has been written to bitstream */
+ assert(esv->header[last_ptr].write_timing + getframebits(gfc)
+ == gfc->bs.totbit);
+
+ /* we have padded out all frames with ancillary data, which is the
+ same as filling the bitreservoir with ancillary data, so : */
+ esv->ResvSize = 0;
+ l3_side->main_data_begin = 0;
+}
+
+
+
+
+void
+add_dummy_byte(lame_internal_flags * gfc, unsigned char val, unsigned int n)
+{
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int i;
+
+ while (n-- > 0u) {
+ putbits_noheaders(gfc, val, 8);
+
+ for (i = 0; i < MAX_HEADER_BUF; ++i)
+ esv->header[i].write_timing += 8;
+ }
+}
+
+
+/*
+ format_bitstream()
+
+ This is called after a frame of audio has been quantized and coded.
+ It will write the encoded audio to the bitstream. Note that
+ from a layer3 encoder's perspective the bit stream is primarily
+ a series of main_data() blocks, with header and side information
+ inserted at the proper locations to maintain framing. (See Figure A.7
+ in the IS).
+ */
+int
+format_bitstream(lame_internal_flags * gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int bits, nbytes;
+ III_side_info_t *l3_side;
+ int bitsPerFrame;
+ l3_side = &gfc->l3_side;
+
+ bitsPerFrame = getframebits(gfc);
+ drain_into_ancillary(gfc, l3_side->resvDrain_pre);
+
+ encodeSideInfo2(gfc, bitsPerFrame);
+ bits = 8 * cfg->sideinfo_len;
+ bits += writeMainData(gfc);
+ drain_into_ancillary(gfc, l3_side->resvDrain_post);
+ bits += l3_side->resvDrain_post;
+
+ l3_side->main_data_begin += (bitsPerFrame - bits) / 8;
+
+ /* compare number of bits needed to clear all buffered mp3 frames
+ * with what we think the resvsize is: */
+ if (compute_flushbits(gfc, &nbytes) != esv->ResvSize) {
+ ERRORF(gfc, "Internal buffer inconsistency. flushbits <> ResvSize");
+ }
+
+
+ /* compare main_data_begin for the next frame with what we
+ * think the resvsize is: */
+ if ((l3_side->main_data_begin * 8) != esv->ResvSize) {
+ ERRORF(gfc, "bit reservoir error: \n"
+ "l3_side->main_data_begin: %i \n"
+ "Resvoir size: %i \n"
+ "resv drain (post) %i \n"
+ "resv drain (pre) %i \n"
+ "header and sideinfo: %i \n"
+ "data bits: %i \n"
+ "total bits: %i (remainder: %i) \n"
+ "bitsperframe: %i \n",
+ 8 * l3_side->main_data_begin,
+ esv->ResvSize,
+ l3_side->resvDrain_post,
+ l3_side->resvDrain_pre,
+ 8 * cfg->sideinfo_len,
+ bits - l3_side->resvDrain_post - 8 * cfg->sideinfo_len,
+ bits, bits % 8, bitsPerFrame);
+
+ ERRORF(gfc, "This is a fatal error. It has several possible causes:");
+ ERRORF(gfc, "90%% LAME compiled with buggy version of gcc using advanced optimizations");
+ ERRORF(gfc, " 9%% Your system is overclocked");
+ ERRORF(gfc, " 1%% bug in LAME encoding library");
+
+ esv->ResvSize = l3_side->main_data_begin * 8;
+ };
+ assert(gfc->bs.totbit % 8 == 0);
+
+ if (gfc->bs.totbit > 1000000000) {
+ /* to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset bit counter */
+ int i;
+ for (i = 0; i < MAX_HEADER_BUF; ++i)
+ esv->header[i].write_timing -= gfc->bs.totbit;
+ gfc->bs.totbit = 0;
+ }
+
+
+ return 0;
+}
+
+
+static int
+do_gain_analysis(lame_internal_flags * gfc, unsigned char* buffer, int minimum)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ RpgStateVar_t const *const rsv = &gfc->sv_rpg;
+ RpgResult_t *const rov = &gfc->ov_rpg;
+#ifdef DECODE_ON_THE_FLY
+ if (cfg->decode_on_the_fly) { /* decode the frame */
+ sample_t pcm_buf[2][1152];
+ int mp3_in = minimum;
+ int samples_out = -1;
+
+ /* re-synthesis to pcm. Repeat until we get a samples_out=0 */
+ while (samples_out != 0) {
+
+ samples_out = hip_decode1_unclipped(gfc->hip, buffer, mp3_in, pcm_buf[0], pcm_buf[1]);
+ /* samples_out = 0: need more data to decode
+ * samples_out = -1: error. Lets assume 0 pcm output
+ * samples_out = number of samples output */
+
+ /* set the lenght of the mp3 input buffer to zero, so that in the
+ * next iteration of the loop we will be querying mpglib about
+ * buffered data */
+ mp3_in = 0;
+
+ if (samples_out == -1) {
+ /* error decoding. Not fatal, but might screw up
+ * the ReplayGain tag. What should we do? Ignore for now */
+ samples_out = 0;
+ }
+ if (samples_out > 0) {
+ /* process the PCM data */
+
+ /* this should not be possible, and indicates we have
+ * overflown the pcm_buf buffer */
+ assert(samples_out <= 1152);
+
+ if (cfg->findPeakSample) {
+ int i;
+ /* FIXME: is this correct? maybe Max(fabs(pcm),PeakSample) */
+ for (i = 0; i < samples_out; i++) {
+ if (pcm_buf[0][i] > rov->PeakSample)
+ rov->PeakSample = pcm_buf[0][i];
+ else if (-pcm_buf[0][i] > rov->PeakSample)
+ rov->PeakSample = -pcm_buf[0][i];
+ }
+ if (cfg->channels_out > 1)
+ for (i = 0; i < samples_out; i++) {
+ if (pcm_buf[1][i] > rov->PeakSample)
+ rov->PeakSample = pcm_buf[1][i];
+ else if (-pcm_buf[1][i] > rov->PeakSample)
+ rov->PeakSample = -pcm_buf[1][i];
+ }
+ }
+
+ if (cfg->findReplayGain)
+ if (AnalyzeSamples
+ (rsv->rgdata, pcm_buf[0], pcm_buf[1], samples_out,
+ cfg->channels_out) == GAIN_ANALYSIS_ERROR)
+ return -6;
+
+ } /* if (samples_out>0) */
+ } /* while (samples_out!=0) */
+ } /* if (gfc->decode_on_the_fly) */
+#endif
+ return minimum;
+}
+
+static int
+do_copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int size)
+{
+ Bit_stream_struc *const bs = &gfc->bs;
+ int const minimum = bs->buf_byte_idx + 1;
+ if (minimum <= 0)
+ return 0;
+ if (minimum > size)
+ return -1; /* buffer is too small */
+ memcpy(buffer, bs->buf, minimum);
+ bs->buf_byte_idx = -1;
+ bs->buf_bit_idx = 0;
+ return minimum;
+}
+
+/* copy data out of the internal MP3 bit buffer into a user supplied
+ unsigned char buffer.
+
+ mp3data=0 indicates data in buffer is an id3tags and VBR tags
+ mp3data=1 data is real mp3 frame data.
+
+
+*/
+int
+copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int size, int mp3data)
+{
+ int const minimum = do_copy_buffer(gfc, buffer, size);
+ if (minimum > 0 && mp3data) {
+ UpdateMusicCRC(&gfc->nMusicCRC, buffer, minimum);
+
+ /** sum number of bytes belonging to the mp3 stream
+ * this info will be written into the Xing/LAME header for seeking
+ */
+ gfc->VBR_seek_table.nBytesWritten += minimum;
+
+ return do_gain_analysis(gfc, buffer, minimum);
+ } /* if (mp3data) */
+ return minimum;
+}
+
+
+void
+init_bit_stream_w(lame_internal_flags * gfc)
+{
+ EncStateVar_t *const esv = &gfc->sv_enc;
+
+ esv->h_ptr = esv->w_ptr = 0;
+ esv->header[esv->h_ptr].write_timing = 0;
+
+ gfc->bs.buf = lame_calloc(unsigned char, BUFFER_SIZE);
+ gfc->bs.buf_size = BUFFER_SIZE;
+ gfc->bs.buf_byte_idx = -1;
+ gfc->bs.buf_bit_idx = 0;
+ gfc->bs.totbit = 0;
+}
+
+/* end of bitstream.c */
diff --git a/pkg/lame/clame/bitstream.h b/pkg/lame/clame/bitstream.h
new file mode 100644
index 0000000..3ae48d0
--- /dev/null
+++ b/pkg/lame/clame/bitstream.h
@@ -0,0 +1,40 @@
+/*
+ * MP3 bitstream Output interface for LAME
+ *
+ * Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_BITSTREAM_H
+#define LAME_BITSTREAM_H
+
+int getframebits(const lame_internal_flags * gfc);
+
+int format_bitstream(lame_internal_flags * gfc);
+
+void flush_bitstream(lame_internal_flags * gfc);
+void add_dummy_byte(lame_internal_flags * gfc, unsigned char val, unsigned int n);
+
+int copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int buffer_size,
+ int update_crc);
+void init_bit_stream_w(lame_internal_flags * gfc);
+void CRC_writeheader(lame_internal_flags const *gfc, char *buffer);
+int compute_flushbits(const lame_internal_flags * gfp, int *nbytes);
+
+int get_max_frame_buffer_size_by_constraint(SessionConfig_t const * cfg, int constraint);
+
+#endif
diff --git a/pkg/lame/clame/config.h b/pkg/lame/clame/config.h
new file mode 100644
index 0000000..4df73ee
--- /dev/null
+++ b/pkg/lame/clame/config.h
@@ -0,0 +1,30 @@
+#ifndef LAME_CONFIG_H
+#define LAME_CONFIG_H
+
+#define STDC_HEADERS
+
+/*
+#define __int8_t_defined
+#define uint8_t unsigned char
+#define uint16_t unsigned short
+#define uint32_t unsigned int
+#define uint64_t unsigned long long
+
+#define int8_t signed char
+#define int16_t signed short
+#define int32_t signed int
+#define int64_t signed long long
+*/
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+
+typedef long double ieee854_float80_t;
+typedef double ieee754_float64_t;
+typedef float ieee754_float32_t;
+#endif /* LAME_CONFIG_H */
diff --git a/pkg/lame/clame/encoder.c b/pkg/lame/clame/encoder.c
new file mode 100644
index 0000000..48f46c7
--- /dev/null
+++ b/pkg/lame/clame/encoder.c
@@ -0,0 +1,574 @@
+/*
+ * LAME MP3 encoding engine
+ *
+ * Copyright (c) 1999 Mark Taylor
+ * Copyright (c) 2000-2002 Takehiro Tominaga
+ * Copyright (c) 2000-2011 Robert Hegemann
+ * Copyright (c) 2001 Gabriel Bouvigne
+ * Copyright (c) 2001 John Dahlstrom
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: encoder.c,v 1.114 2017/08/26 10:54:57 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "lame_global_flags.h"
+#include "newmdct.h"
+#include "psymodel.h"
+#include "lame-analysis.h"
+#include "bitstream.h"
+#include "VbrTag.h"
+#include "quantize.h"
+#include "quantize_pvt.h"
+
+
+
+/*
+ * auto-adjust of ATH, useful for low volume
+ * Gabriel Bouvigne 3 feb 2001
+ *
+ * modifies some values in
+ * gfp->internal_flags->ATH
+ * (gfc->ATH)
+ */
+static void
+adjust_ATH(lame_internal_flags const *const gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ FLOAT gr2_max, max_pow;
+
+ if (gfc->ATH->use_adjust == 0) {
+ gfc->ATH->adjust_factor = 1.0; /* no adjustment */
+ return;
+ }
+
+ /* jd - 2001 mar 12, 27, jun 30 */
+ /* loudness based on equal loudness curve; */
+ /* use granule with maximum combined loudness */
+ max_pow = gfc->ov_psy.loudness_sq[0][0];
+ gr2_max = gfc->ov_psy.loudness_sq[1][0];
+ if (cfg->channels_out == 2) {
+ max_pow += gfc->ov_psy.loudness_sq[0][1];
+ gr2_max += gfc->ov_psy.loudness_sq[1][1];
+ }
+ else {
+ max_pow += max_pow;
+ gr2_max += gr2_max;
+ }
+ if (cfg->mode_gr == 2) {
+ max_pow = Max(max_pow, gr2_max);
+ }
+ max_pow *= 0.5; /* max_pow approaches 1.0 for full band noise */
+
+ /* jd - 2001 mar 31, jun 30 */
+ /* user tuning of ATH adjustment region */
+ max_pow *= gfc->ATH->aa_sensitivity_p;
+
+ /* adjust ATH depending on range of maximum value
+ */
+
+ /* jd - 2001 feb27, mar12,20, jun30, jul22 */
+ /* continuous curves based on approximation */
+ /* to GB's original values. */
+ /* For an increase in approximate loudness, */
+ /* set ATH adjust to adjust_limit immediately */
+ /* after a delay of one frame. */
+ /* For a loudness decrease, reduce ATH adjust */
+ /* towards adjust_limit gradually. */
+ /* max_pow is a loudness squared or a power. */
+ if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */
+ if (gfc->ATH->adjust_factor >= 1.0) {
+ gfc->ATH->adjust_factor = 1.0;
+ }
+ else {
+ /* preceding frame has lower ATH adjust; */
+ /* ascend only to the preceding adjust_limit */
+ /* in case there is leading low volume */
+ if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) {
+ gfc->ATH->adjust_factor = gfc->ATH->adjust_limit;
+ }
+ }
+ gfc->ATH->adjust_limit = 1.0;
+ }
+ else { /* adjustment curve */
+ /* about 32 dB maximum adjust (0.000625) */
+ FLOAT const adj_lim_new = 31.98 * max_pow + 0.000625;
+ if (gfc->ATH->adjust_factor >= adj_lim_new) { /* descend gradually */
+ gfc->ATH->adjust_factor *= adj_lim_new * 0.075 + 0.925;
+ if (gfc->ATH->adjust_factor < adj_lim_new) { /* stop descent */
+ gfc->ATH->adjust_factor = adj_lim_new;
+ }
+ }
+ else { /* ascend */
+ if (gfc->ATH->adjust_limit >= adj_lim_new) {
+ gfc->ATH->adjust_factor = adj_lim_new;
+ }
+ else { /* preceding frame has lower ATH adjust; */
+ /* ascend only to the preceding adjust_limit */
+ if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) {
+ gfc->ATH->adjust_factor = gfc->ATH->adjust_limit;
+ }
+ }
+ }
+ gfc->ATH->adjust_limit = adj_lim_new;
+ }
+}
+
+/***********************************************************************
+ *
+ * some simple statistics
+ *
+ * bitrate index 0: free bitrate -> not allowed in VBR mode
+ * : bitrates, kbps depending on MPEG version
+ * bitrate index 15: forbidden
+ *
+ * mode_ext:
+ * 0: LR
+ * 1: LR-i
+ * 2: MS
+ * 3: MS-i
+ *
+ ***********************************************************************/
+
+static void
+updateStats(lame_internal_flags * const gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *eov = &gfc->ov_enc;
+ int gr, ch;
+ assert(0 <= eov->bitrate_index && eov->bitrate_index < 16);
+ assert(0 <= eov->mode_ext && eov->mode_ext < 4);
+
+ /* count bitrate indices */
+ eov->bitrate_channelmode_hist[eov->bitrate_index][4]++;
+ eov->bitrate_channelmode_hist[15][4]++;
+
+ /* count 'em for every mode extension in case of 2 channel encoding */
+ if (cfg->channels_out == 2) {
+ eov->bitrate_channelmode_hist[eov->bitrate_index][eov->mode_ext]++;
+ eov->bitrate_channelmode_hist[15][eov->mode_ext]++;
+ }
+ for (gr = 0; gr < cfg->mode_gr; ++gr) {
+ for (ch = 0; ch < cfg->channels_out; ++ch) {
+ int bt = gfc->l3_side.tt[gr][ch].block_type;
+ if (gfc->l3_side.tt[gr][ch].mixed_block_flag)
+ bt = 4;
+ eov->bitrate_blocktype_hist[eov->bitrate_index][bt]++;
+ eov->bitrate_blocktype_hist[eov->bitrate_index][5]++;
+ eov->bitrate_blocktype_hist[15][bt]++;
+ eov->bitrate_blocktype_hist[15][5]++;
+ }
+ }
+}
+
+
+
+
+static void
+lame_encode_frame_init(lame_internal_flags * gfc, const sample_t *const inbuf[2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+
+ int ch, gr;
+
+ if (gfc->lame_encode_frame_init == 0) {
+ sample_t primebuff0[286 + 1152 + 576];
+ sample_t primebuff1[286 + 1152 + 576];
+ int const framesize = 576 * cfg->mode_gr;
+ /* prime the MDCT/polyphase filterbank with a short block */
+ int i, j;
+ gfc->lame_encode_frame_init = 1;
+ memset(primebuff0, 0, sizeof(primebuff0));
+ memset(primebuff1, 0, sizeof(primebuff1));
+ for (i = 0, j = 0; i < 286 + 576 * (1 + cfg->mode_gr); ++i) {
+ if (i < framesize) {
+ primebuff0[i] = 0;
+ if (cfg->channels_out == 2)
+ primebuff1[i] = 0;
+ }
+ else {
+ primebuff0[i] = inbuf[0][j];
+ if (cfg->channels_out == 2)
+ primebuff1[i] = inbuf[1][j];
+ ++j;
+ }
+ }
+ /* polyphase filtering / mdct */
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gfc->l3_side.tt[gr][ch].block_type = SHORT_TYPE;
+ }
+ }
+ mdct_sub48(gfc, primebuff0, primebuff1);
+
+ /* check FFT will not use a negative starting offset */
+#if 576 < FFTOFFSET
+# error FFTOFFSET greater than 576: FFT uses a negative offset
+#endif
+ /* check if we have enough data for FFT */
+ assert(gfc->sv_enc.mf_size >= (BLKSIZE + framesize - FFTOFFSET));
+ /* check if we have enough data for polyphase filterbank */
+ assert(gfc->sv_enc.mf_size >= (512 + framesize - 32));
+ }
+
+}
+
+
+
+
+
+
+
+/************************************************************************
+*
+* encodeframe() Layer 3
+*
+* encode a single frame
+*
+************************************************************************
+lame_encode_frame()
+
+
+ gr 0 gr 1
+inbuf: |--------------|--------------|--------------|
+
+
+Polyphase (18 windows, each shifted 32)
+gr 0:
+window1 <----512---->
+window18 <----512---->
+
+gr 1:
+window1 <----512---->
+window18 <----512---->
+
+
+
+MDCT output: |--------------|--------------|--------------|
+
+FFT's <---------1024---------->
+ <---------1024-------->
+
+
+
+ inbuf = buffer of PCM data size=MP3 framesize
+ encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
+ so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
+
+ psy-model FFT has a 1 granule delay, so we feed it data for the
+ next granule.
+ FFT is centered over granule: 224+576+224
+ So FFT starts at: 576-224-MDCTDELAY
+
+ MPEG2: FFT ends at: BLKSIZE+576-224-MDCTDELAY (1328)
+ MPEG1: FFT ends at: BLKSIZE+2*576-224-MDCTDELAY (1904)
+
+ MPEG2: polyphase first window: [0..511]
+ 18th window: [544..1055] (1056)
+ MPEG1: 36th window: [1120..1631] (1632)
+ data needed: 512+framesize-32
+
+ A close look newmdct.c shows that the polyphase filterbank
+ only uses data from [0..510] for each window. Perhaps because the window
+ used by the filterbank is zero for the last point, so Takehiro's
+ code doesn't bother to compute with it.
+
+ FFT starts at 576-224-MDCTDELAY (304) = 576-FFTOFFSET
+
+*/
+
+typedef FLOAT chgrdata[2][2];
+
+
+int
+lame_encode_mp3_frame( /* Output */
+ lame_internal_flags * gfc, /* Context */
+ sample_t const *inbuf_l, /* Input */
+ sample_t const *inbuf_r, /* Input */
+ unsigned char *mp3buf, /* Output */
+ int mp3buf_size)
+{ /* Output */
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int mp3count;
+ III_psy_ratio masking_LR[2][2]; /*LR masking & energy */
+ III_psy_ratio masking_MS[2][2]; /*MS masking & energy */
+ const III_psy_ratio (*masking)[2]; /*pointer to selected maskings */
+ const sample_t *inbuf[2];
+
+ FLOAT tot_ener[2][4];
+ FLOAT ms_ener_ratio[2] = { .5, .5 };
+ FLOAT pe[2][2] = { {0., 0.}, {0., 0.} }, pe_MS[2][2] = { {
+ 0., 0.}, {
+ 0., 0.}};
+ FLOAT (*pe_use)[2];
+
+ int ch, gr;
+
+ inbuf[0] = inbuf_l;
+ inbuf[1] = inbuf_r;
+
+ if (gfc->lame_encode_frame_init == 0) {
+ /*first run? */
+ lame_encode_frame_init(gfc, inbuf);
+
+ }
+
+
+ /********************** padding *****************************/
+ /* padding method as described in
+ * "MPEG-Layer3 / Bitstream Syntax and Decoding"
+ * by Martin Sieler, Ralph Sperschneider
+ *
+ * note: there is no padding for the very first frame
+ *
+ * Robert Hegemann 2000-06-22
+ */
+ gfc->ov_enc.padding = FALSE;
+ if ((gfc->sv_enc.slot_lag -= gfc->sv_enc.frac_SpF) < 0) {
+ gfc->sv_enc.slot_lag += cfg->samplerate_out;
+ gfc->ov_enc.padding = TRUE;
+ }
+
+
+
+ /****************************************
+ * Stage 1: psychoacoustic model *
+ ****************************************/
+
+ {
+ /* psychoacoustic model
+ * psy model has a 1 granule (576) delay that we must compensate for
+ * (mt 6/99).
+ */
+ int ret;
+ const sample_t *bufp[2] = {0, 0}; /* address of beginning of left & right granule */
+ int blocktype[2];
+
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ bufp[ch] = &inbuf[ch][576 + gr * 576 - FFTOFFSET];
+ }
+ ret = L3psycho_anal_vbr(gfc, bufp, gr,
+ masking_LR, masking_MS,
+ pe[gr], pe_MS[gr], tot_ener[gr], blocktype);
+ if (ret != 0)
+ return -4;
+
+ if (cfg->mode == JOINT_STEREO) {
+ ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3];
+ if (ms_ener_ratio[gr] > 0)
+ ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr];
+ }
+
+ /* block type flags */
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
+ cod_info->block_type = blocktype[ch];
+ cod_info->mixed_block_flag = 0;
+ }
+ }
+ }
+
+
+ /* auto-adjust of ATH, useful for low volume */
+ adjust_ATH(gfc);
+
+
+ /****************************************
+ * Stage 2: MDCT *
+ ****************************************/
+
+ /* polyphase filtering / mdct */
+ mdct_sub48(gfc, inbuf[0], inbuf[1]);
+
+
+ /****************************************
+ * Stage 3: MS/LR decision *
+ ****************************************/
+
+ /* Here will be selected MS or LR coding of the 2 stereo channels */
+ gfc->ov_enc.mode_ext = MPG_MD_LR_LR;
+
+ if (cfg->force_ms) {
+ gfc->ov_enc.mode_ext = MPG_MD_MS_LR;
+ }
+ else if (cfg->mode == JOINT_STEREO) {
+ /* ms_ratio = is scaled, for historical reasons, to look like
+ a ratio of side_channel / total.
+ 0 = signal is 100% mono
+ .5 = L & R uncorrelated
+ */
+
+ /* [0] and [1] are the results for the two granules in MPEG-1,
+ * in MPEG-2 it's only a faked averaging of the same value
+ * _prev is the value of the last granule of the previous frame
+ * _next is the value of the first granule of the next frame
+ */
+
+ FLOAT sum_pe_MS = 0;
+ FLOAT sum_pe_LR = 0;
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ sum_pe_MS += pe_MS[gr][ch];
+ sum_pe_LR += pe[gr][ch];
+ }
+ }
+
+ /* based on PE: M/S coding would not use much more bits than L/R */
+ if (sum_pe_MS <= 1.00 * sum_pe_LR) {
+
+ gr_info const *const gi0 = &gfc->l3_side.tt[0][0];
+ gr_info const *const gi1 = &gfc->l3_side.tt[cfg->mode_gr - 1][0];
+
+ if (gi0[0].block_type == gi0[1].block_type && gi1[0].block_type == gi1[1].block_type) {
+
+ gfc->ov_enc.mode_ext = MPG_MD_MS_LR;
+ }
+ }
+ }
+
+ /* bit and noise allocation */
+ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
+ masking = (const III_psy_ratio (*)[2])masking_MS; /* use MS masking */
+ pe_use = pe_MS;
+ }
+ else {
+ masking = (const III_psy_ratio (*)[2])masking_LR; /* use LR masking */
+ pe_use = pe;
+ }
+
+
+ /* copy data for MP3 frame analyzer */
+ if (cfg->analysis && gfc->pinfo != NULL) {
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gfc->pinfo->ms_ratio[gr] = 0;
+ gfc->pinfo->ms_ener_ratio[gr] = ms_ener_ratio[gr];
+ gfc->pinfo->blocktype[gr][ch] = gfc->l3_side.tt[gr][ch].block_type;
+ gfc->pinfo->pe[gr][ch] = pe_use[gr][ch];
+ memcpy(gfc->pinfo->xr[gr][ch], &gfc->l3_side.tt[gr][ch].xr[0], sizeof(FLOAT) * 576);
+ /* in psymodel, LR and MS data was stored in pinfo.
+ switch to MS data: */
+ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
+ gfc->pinfo->ers[gr][ch] = gfc->pinfo->ers[gr][ch + 2];
+ memcpy(gfc->pinfo->energy[gr][ch], gfc->pinfo->energy[gr][ch + 2],
+ sizeof(gfc->pinfo->energy[gr][ch]));
+ }
+ }
+ }
+ }
+
+
+ /****************************************
+ * Stage 4: quantization loop *
+ ****************************************/
+
+ if (cfg->vbr == vbr_off || cfg->vbr == vbr_abr) {
+ static FLOAT const fircoef[9] = {
+ -0.0207887 * 5, -0.0378413 * 5, -0.0432472 * 5, -0.031183 * 5,
+ 7.79609e-18 * 5, 0.0467745 * 5, 0.10091 * 5, 0.151365 * 5,
+ 0.187098 * 5
+ };
+
+ int i;
+ FLOAT f;
+
+ for (i = 0; i < 18; i++)
+ gfc->sv_enc.pefirbuf[i] = gfc->sv_enc.pefirbuf[i + 1];
+
+ f = 0.0;
+ for (gr = 0; gr < cfg->mode_gr; gr++)
+ for (ch = 0; ch < cfg->channels_out; ch++)
+ f += pe_use[gr][ch];
+ gfc->sv_enc.pefirbuf[18] = f;
+
+ f = gfc->sv_enc.pefirbuf[9];
+ for (i = 0; i < 9; i++)
+ f += (gfc->sv_enc.pefirbuf[i] + gfc->sv_enc.pefirbuf[18 - i]) * fircoef[i];
+
+ f = (670 * 5 * cfg->mode_gr * cfg->channels_out) / f;
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ pe_use[gr][ch] *= f;
+ }
+ }
+ }
+ switch (cfg->vbr)
+ {
+ default:
+ case vbr_off:
+ CBR_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
+ break;
+ case vbr_abr:
+ ABR_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
+ break;
+ case vbr_rh:
+ VBR_old_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
+ break;
+ case vbr_mt:
+ case vbr_mtrh:
+ VBR_new_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
+ break;
+ }
+
+
+ /****************************************
+ * Stage 5: bitstream formatting *
+ ****************************************/
+
+
+ /* write the frame to the bitstream */
+ (void) format_bitstream(gfc);
+
+ /* copy mp3 bit buffer into array */
+ mp3count = copy_buffer(gfc, mp3buf, mp3buf_size, 1);
+
+
+ if (cfg->write_lame_tag) {
+ AddVbrFrame(gfc);
+ }
+
+ if (cfg->analysis && gfc->pinfo != NULL) {
+ int framesize = 576 * cfg->mode_gr;
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ int j;
+ for (j = 0; j < FFTOFFSET; j++)
+ gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j + framesize];
+ for (j = FFTOFFSET; j < 1600; j++) {
+ gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET];
+ }
+ }
+ gfc->sv_qnt.masking_lower = 1.0;
+
+ set_frame_pinfo(gfc, masking);
+ }
+
+ ++gfc->ov_enc.frame_number;
+
+ updateStats(gfc);
+
+ return mp3count;
+}
diff --git a/pkg/lame/clame/encoder.h b/pkg/lame/clame/encoder.h
new file mode 100644
index 0000000..b06a7c6
--- /dev/null
+++ b/pkg/lame/clame/encoder.h
@@ -0,0 +1,156 @@
+/*
+ * encoder.h include file
+ *
+ * Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef LAME_ENCODER_H
+#define LAME_ENCODER_H
+
+/***********************************************************************
+*
+* encoder and decoder delays
+*
+***********************************************************************/
+
+/*
+ * layer III enc->dec delay: 1056 (1057?) (observed)
+ * layer II enc->dec delay: 480 (481?) (observed)
+ *
+ * polyphase 256-16 (dec or enc) = 240
+ * mdct 256+32 (9*32) (dec or enc) = 288
+ * total: 512+16
+ *
+ * My guess is that delay of polyphase filterbank is actualy 240.5
+ * (there are technical reasons for this, see postings in mp3encoder).
+ * So total Encode+Decode delay = ENCDELAY + 528 + 1
+ */
+
+/*
+ * ENCDELAY The encoder delay.
+ *
+ * Minimum allowed is MDCTDELAY (see below)
+ *
+ * The first 96 samples will be attenuated, so using a value less than 96
+ * will result in corrupt data for the first 96-ENCDELAY samples.
+ *
+ * suggested: 576
+ * set to 1160 to sync with FhG.
+ */
+
+#define ENCDELAY 576
+
+
+
+/*
+ * make sure there is at least one complete frame after the
+ * last frame containing real data
+ *
+ * Using a value of 288 would be sufficient for a
+ * a very sophisticated decoder that can decode granule-by-granule instead
+ * of frame by frame. But lets not assume this, and assume the decoder
+ * will not decode frame N unless it also has data for frame N+1
+ *
+ */
+/*#define POSTDELAY 288*/
+#define POSTDELAY 1152
+
+
+
+/*
+ * delay of the MDCT used in mdct.c
+ * original ISO routines had a delay of 528!
+ * Takehiro's routines:
+ */
+
+#define MDCTDELAY 48
+#define FFTOFFSET (224+MDCTDELAY)
+
+/*
+ * Most decoders, including the one we use, have a delay of 528 samples.
+ */
+
+#define DECDELAY 528
+
+
+/* number of subbands */
+#define SBLIMIT 32
+
+/* parition bands bands */
+#define CBANDS 64
+
+/* number of critical bands/scale factor bands where masking is computed*/
+#define SBPSY_l 21
+#define SBPSY_s 12
+
+/* total number of scalefactor bands encoded */
+#define SBMAX_l 22
+#define SBMAX_s 13
+#define PSFB21 6
+#define PSFB12 6
+
+
+
+/* FFT sizes */
+#define BLKSIZE 1024
+#define HBLKSIZE (BLKSIZE/2 + 1)
+#define BLKSIZE_s 256
+#define HBLKSIZE_s (BLKSIZE_s/2 + 1)
+
+
+/* #define switch_pe 1800 */
+#define NORM_TYPE 0
+#define START_TYPE 1
+#define SHORT_TYPE 2
+#define STOP_TYPE 3
+
+/*
+ * Mode Extention:
+ * When we are in stereo mode, there are 4 possible methods to store these
+ * two channels. The stereo modes -m? are using a subset of them.
+ *
+ * -ms: MPG_MD_LR_LR
+ * -mj: MPG_MD_LR_LR and MPG_MD_MS_LR
+ * -mf: MPG_MD_MS_LR
+ * -mi: all
+ */
+#if 0
+#define MPG_MD_LR_LR 0
+#define MPG_MD_LR_I 1
+#define MPG_MD_MS_LR 2
+#define MPG_MD_MS_I 3
+#endif
+enum MPEGChannelMode
+{ MPG_MD_LR_LR = 0
+, MPG_MD_LR_I = 1
+, MPG_MD_MS_LR = 2
+, MPG_MD_MS_I = 3
+};
+
+#ifndef lame_internal_flags_defined
+#define lame_internal_flags_defined
+struct lame_internal_flags;
+typedef struct lame_internal_flags lame_internal_flags;
+#endif
+
+int lame_encode_mp3_frame(lame_internal_flags * gfc,
+ sample_t const *inbuf_l,
+ sample_t const *inbuf_r, unsigned char *mp3buf, int mp3buf_size);
+
+#endif /* LAME_ENCODER_H */
diff --git a/pkg/lame/clame/fft.c b/pkg/lame/clame/fft.c
new file mode 100644
index 0000000..163e155
--- /dev/null
+++ b/pkg/lame/clame/fft.c
@@ -0,0 +1,339 @@
+/*
+** FFT and FHT routines
+** Copyright 1988, 1993; Ron Mayer
+** Copyright (c) 1999-2000 Takehiro Tominaga
+**
+** fht(fz,n);
+** Does a hartley transform of "n" points in the array "fz".
+**
+** NOTE: This routine uses at least 2 patented algorithms, and may be
+** under the restrictions of a bunch of different organizations.
+** Although I wrote it completely myself; it is kind of a derivative
+** of a routine I once authored and released under the GPL, so it
+** may fall under the free software foundation's restrictions;
+** it was worked on as a Stanford Univ project, so they claim
+** some rights to it; it was further optimized at work here, so
+** I think this company claims parts of it. The patents are
+** held by R. Bracewell (the FHT algorithm) and O. Buneman (the
+** trig generator), both at Stanford Univ.
+** If it were up to me, I'd say go do whatever you want with it;
+** but it would be polite to give credit to the following people
+** if you use this anywhere:
+** Euler - probable inventor of the fourier transform.
+** Gauss - probable inventor of the FFT.
+** Hartley - probable inventor of the hartley transform.
+** Buneman - for a really cool trig generator
+** Mayer(me) - for authoring this particular version and
+** including all the optimizations in one package.
+** Thanks,
+** Ron Mayer; mayer@acuson.com
+** and added some optimization by
+** Mather - idea of using lookup table
+** Takehiro - some dirty hack for speed up
+*/
+
+/* $Id: fft.c,v 1.39 2017/09/06 15:07:29 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "fft.h"
+
+#include "lame_intrin.h"
+
+
+
+#define TRI_SIZE (5-1) /* 1024 = 4**5 */
+
+/* fft.c */
+
+static const FLOAT costab[TRI_SIZE * 2] = {
+ 9.238795325112867e-01, 3.826834323650898e-01,
+ 9.951847266721969e-01, 9.801714032956060e-02,
+ 9.996988186962042e-01, 2.454122852291229e-02,
+ 9.999811752826011e-01, 6.135884649154475e-03
+};
+
+static void
+fht(FLOAT * fz, int n)
+{
+ const FLOAT *tri = costab;
+ int k4;
+ FLOAT *fi, *gi;
+ FLOAT const *fn;
+
+ n <<= 1; /* to get BLKSIZE, because of 3DNow! ASM routine */
+ fn = fz + n;
+ k4 = 4;
+ do {
+ FLOAT s1, c1;
+ int i, k1, k2, k3, kx;
+ kx = k4 >> 1;
+ k1 = k4;
+ k2 = k4 << 1;
+ k3 = k2 + k1;
+ k4 = k2 << 1;
+ fi = fz;
+ gi = fi + kx;
+ do {
+ FLOAT f0, f1, f2, f3;
+ f1 = fi[0] - fi[k1];
+ f0 = fi[0] + fi[k1];
+ f3 = fi[k2] - fi[k3];
+ f2 = fi[k2] + fi[k3];
+ fi[k2] = f0 - f2;
+ fi[0] = f0 + f2;
+ fi[k3] = f1 - f3;
+ fi[k1] = f1 + f3;
+ f1 = gi[0] - gi[k1];
+ f0 = gi[0] + gi[k1];
+ f3 = SQRT2 * gi[k3];
+ f2 = SQRT2 * gi[k2];
+ gi[k2] = f0 - f2;
+ gi[0] = f0 + f2;
+ gi[k3] = f1 - f3;
+ gi[k1] = f1 + f3;
+ gi += k4;
+ fi += k4;
+ } while (fi < fn);
+ c1 = tri[0];
+ s1 = tri[1];
+ for (i = 1; i < kx; i++) {
+ FLOAT c2, s2;
+ c2 = 1 - (2 * s1) * s1;
+ s2 = (2 * s1) * c1;
+ fi = fz + i;
+ gi = fz + k1 - i;
+ do {
+ FLOAT a, b, g0, f0, f1, g1, f2, g2, f3, g3;
+ b = s2 * fi[k1] - c2 * gi[k1];
+ a = c2 * fi[k1] + s2 * gi[k1];
+ f1 = fi[0] - a;
+ f0 = fi[0] + a;
+ g1 = gi[0] - b;
+ g0 = gi[0] + b;
+ b = s2 * fi[k3] - c2 * gi[k3];
+ a = c2 * fi[k3] + s2 * gi[k3];
+ f3 = fi[k2] - a;
+ f2 = fi[k2] + a;
+ g3 = gi[k2] - b;
+ g2 = gi[k2] + b;
+ b = s1 * f2 - c1 * g3;
+ a = c1 * f2 + s1 * g3;
+ fi[k2] = f0 - a;
+ fi[0] = f0 + a;
+ gi[k3] = g1 - b;
+ gi[k1] = g1 + b;
+ b = c1 * g2 - s1 * f3;
+ a = s1 * g2 + c1 * f3;
+ gi[k2] = g0 - a;
+ gi[0] = g0 + a;
+ fi[k3] = f1 - b;
+ fi[k1] = f1 + b;
+ gi += k4;
+ fi += k4;
+ } while (fi < fn);
+ c2 = c1;
+ c1 = c2 * tri[0] - s1 * tri[1];
+ s1 = c2 * tri[1] + s1 * tri[0];
+ }
+ tri += 2;
+ } while (k4 < n);
+}
+
+
+static const unsigned char rv_tbl[] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe
+};
+
+#define ch01(index) (buffer[chn][index])
+
+#define ml00(f) (window[i ] * f(i))
+#define ml10(f) (window[i + 0x200] * f(i + 0x200))
+#define ml20(f) (window[i + 0x100] * f(i + 0x100))
+#define ml30(f) (window[i + 0x300] * f(i + 0x300))
+
+#define ml01(f) (window[i + 0x001] * f(i + 0x001))
+#define ml11(f) (window[i + 0x201] * f(i + 0x201))
+#define ml21(f) (window[i + 0x101] * f(i + 0x101))
+#define ml31(f) (window[i + 0x301] * f(i + 0x301))
+
+#define ms00(f) (window_s[i ] * f(i + k))
+#define ms10(f) (window_s[0x7f - i] * f(i + k + 0x80))
+#define ms20(f) (window_s[i + 0x40] * f(i + k + 0x40))
+#define ms30(f) (window_s[0x3f - i] * f(i + k + 0xc0))
+
+#define ms01(f) (window_s[i + 0x01] * f(i + k + 0x01))
+#define ms11(f) (window_s[0x7e - i] * f(i + k + 0x81))
+#define ms21(f) (window_s[i + 0x41] * f(i + k + 0x41))
+#define ms31(f) (window_s[0x3e - i] * f(i + k + 0xc1))
+
+void
+fft_short(lame_internal_flags const *const gfc,
+ FLOAT x_real[3][BLKSIZE_s], int chn, const sample_t *const buffer[2])
+{
+ int i;
+ int j;
+ int b;
+
+#define window_s gfc->cd_psy->window_s
+#define window gfc->cd_psy->window
+
+ for (b = 0; b < 3; b++) {
+ FLOAT *x = &x_real[b][BLKSIZE_s / 2];
+ short const k = (576 / 3) * (b + 1);
+ j = BLKSIZE_s / 8 - 1;
+ do {
+ FLOAT f0, f1, f2, f3, w;
+
+ i = rv_tbl[j << 2];
+
+ f0 = ms00(ch01);
+ w = ms10(ch01);
+ f1 = f0 - w;
+ f0 = f0 + w;
+ f2 = ms20(ch01);
+ w = ms30(ch01);
+ f3 = f2 - w;
+ f2 = f2 + w;
+
+ x -= 4;
+ x[0] = f0 + f2;
+ x[2] = f0 - f2;
+ x[1] = f1 + f3;
+ x[3] = f1 - f3;
+
+ f0 = ms01(ch01);
+ w = ms11(ch01);
+ f1 = f0 - w;
+ f0 = f0 + w;
+ f2 = ms21(ch01);
+ w = ms31(ch01);
+ f3 = f2 - w;
+ f2 = f2 + w;
+
+ x[BLKSIZE_s / 2 + 0] = f0 + f2;
+ x[BLKSIZE_s / 2 + 2] = f0 - f2;
+ x[BLKSIZE_s / 2 + 1] = f1 + f3;
+ x[BLKSIZE_s / 2 + 3] = f1 - f3;
+ } while (--j >= 0);
+
+#undef window
+#undef window_s
+
+ gfc->fft_fht(x, BLKSIZE_s / 2);
+ /* BLKSIZE_s/2 because of 3DNow! ASM routine */
+ }
+}
+
+void
+fft_long(lame_internal_flags const *const gfc,
+ FLOAT x[BLKSIZE], int chn, const sample_t *const buffer[2])
+{
+ int i;
+ int jj = BLKSIZE / 8 - 1;
+ x += BLKSIZE / 2;
+
+#define window_s gfc->cd_psy->window_s
+#define window gfc->cd_psy->window
+
+ do {
+ FLOAT f0, f1, f2, f3, w;
+
+ i = rv_tbl[jj];
+ f0 = ml00(ch01);
+ w = ml10(ch01);
+ f1 = f0 - w;
+ f0 = f0 + w;
+ f2 = ml20(ch01);
+ w = ml30(ch01);
+ f3 = f2 - w;
+ f2 = f2 + w;
+
+ x -= 4;
+ x[0] = f0 + f2;
+ x[2] = f0 - f2;
+ x[1] = f1 + f3;
+ x[3] = f1 - f3;
+
+ f0 = ml01(ch01);
+ w = ml11(ch01);
+ f1 = f0 - w;
+ f0 = f0 + w;
+ f2 = ml21(ch01);
+ w = ml31(ch01);
+ f3 = f2 - w;
+ f2 = f2 + w;
+
+ x[BLKSIZE / 2 + 0] = f0 + f2;
+ x[BLKSIZE / 2 + 2] = f0 - f2;
+ x[BLKSIZE / 2 + 1] = f1 + f3;
+ x[BLKSIZE / 2 + 3] = f1 - f3;
+ } while (--jj >= 0);
+
+#undef window
+#undef window_s
+
+ gfc->fft_fht(x, BLKSIZE / 2);
+ /* BLKSIZE/2 because of 3DNow! ASM routine */
+}
+
+#ifdef HAVE_NASM
+extern void fht_3DN(FLOAT * fz, int n);
+extern void fht_SSE(FLOAT * fz, int n);
+#endif
+
+void
+init_fft(lame_internal_flags * const gfc)
+{
+ int i;
+
+ /* The type of window used here will make no real difference, but */
+ /* in the interest of merging nspsytune stuff - switch to blackman window */
+ for (i = 0; i < BLKSIZE; i++)
+ /* blackman window */
+ gfc->cd_psy->window[i] = 0.42 - 0.5 * cos(2 * PI * (i + .5) / BLKSIZE) +
+ 0.08 * cos(4 * PI * (i + .5) / BLKSIZE);
+
+ for (i = 0; i < BLKSIZE_s / 2; i++)
+ gfc->cd_psy->window_s[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE_s));
+
+ gfc->fft_fht = fht;
+#ifdef HAVE_NASM
+ if (gfc->CPU_features.AMD_3DNow) {
+ gfc->fft_fht = fht_3DN;
+ }
+ else if (gfc->CPU_features.SSE) {
+ gfc->fft_fht = fht_SSE;
+ }
+ else {
+ gfc->fft_fht = fht;
+ }
+#else
+#ifdef HAVE_XMMINTRIN_H
+#ifdef MIN_ARCH_SSE
+ gfc->fft_fht = fht_SSE2;
+#endif
+#endif
+#endif
+}
diff --git a/pkg/lame/clame/fft.h b/pkg/lame/clame/fft.h
new file mode 100644
index 0000000..258df88
--- /dev/null
+++ b/pkg/lame/clame/fft.h
@@ -0,0 +1,35 @@
+/*
+ * Fast Fourier Transform include file
+ *
+ * Copyright (c) 2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_FFT_H
+#define LAME_FFT_H
+
+void fft_long(lame_internal_flags const *const gfc, FLOAT x_real[BLKSIZE],
+ int chn, const sample_t *const data[2]);
+
+void fft_short(lame_internal_flags const *const gfc, FLOAT x_real[3][BLKSIZE_s],
+ int chn, const sample_t *const data[2]);
+
+void init_fft(lame_internal_flags * const gfc);
+
+#endif
+
+/* End of fft.h */
diff --git a/pkg/lame/clame/gain_analysis.c b/pkg/lame/clame/gain_analysis.c
new file mode 100644
index 0000000..c94db78
--- /dev/null
+++ b/pkg/lame/clame/gain_analysis.c
@@ -0,0 +1,476 @@
+/*
+ * ReplayGainAnalysis - analyzes input samples and give the recommended dB change
+ * Copyright (C) 2001 David Robinson and Glen Sawyer
+ * Improvements and optimizations added by Frank Klemm, and by Marcel Muller
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * concept and filter values by David Robinson (David@Robinson.org)
+ * -- blame him if you think the idea is flawed
+ * original coding by Glen Sawyer (mp3gain@hotmail.com)
+ * -- blame him if you think this runs too slowly, or the coding is otherwise flawed
+ *
+ * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ )
+ * -- credit him for all the _good_ programming ;)
+ *
+ *
+ * For an explanation of the concepts and the basic algorithms involved, go to:
+ * http://www.replaygain.org/
+ */
+
+/*
+ * Here's the deal. Call
+ *
+ * InitGainAnalysis ( long samplefreq );
+ *
+ * to initialize everything. Call
+ *
+ * AnalyzeSamples ( const Float_t* left_samples,
+ * const Float_t* right_samples,
+ * size_t num_samples,
+ * int num_channels );
+ *
+ * as many times as you want, with as many or as few samples as you want.
+ * If mono, pass the sample buffer in through left_samples, leave
+ * right_samples NULL, and make sure num_channels = 1.
+ *
+ * GetTitleGain()
+ *
+ * will return the recommended dB level change for all samples analyzed
+ * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis().
+ *
+ * GetAlbumGain()
+ *
+ * will return the recommended dB level change for all samples analyzed
+ * since InitGainAnalysis() was called and finalized with GetTitleGain().
+ *
+ * Pseudo-code to process an album:
+ *
+ * Float_t l_samples [4096];
+ * Float_t r_samples [4096];
+ * size_t num_samples;
+ * unsigned int num_songs;
+ * unsigned int i;
+ *
+ * InitGainAnalysis ( 44100 );
+ * for ( i = 1; i <= num_songs; i++ ) {
+ * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 )
+ * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 );
+ * fprintf ("Recommended dB change for song %2d: %+6.2f dB\n", i, GetTitleGain() );
+ * }
+ * fprintf ("Recommended dB change for whole album: %+6.2f dB\n", GetAlbumGain() );
+ */
+
+/*
+ * So here's the main source of potential code confusion:
+ *
+ * The filters applied to the incoming samples are IIR filters,
+ * meaning they rely on up to number of previous samples
+ * AND up to number of previous filtered samples.
+ *
+ * I set up the AnalyzeSamples routine to minimize memory usage and interface
+ * complexity. The speed isn't compromised too much (I don't think), but the
+ * internal complexity is higher than it should be for such a relatively
+ * simple routine.
+ *
+ * Optimization/clarity suggestions are welcome.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#include
+#include
+#include
+
+#include "lame.h"
+#include "machine.h"
+#include "gain_analysis.h"
+
+/* for each filter: */
+/* [0] 48 kHz, [1] 44.1 kHz, [2] 32 kHz, [3] 24 kHz, [4] 22050 Hz, [5] 16 kHz, [6] 12 kHz, [7] is 11025 Hz, [8] 8 kHz */
+
+#ifdef WIN32
+#pragma warning ( disable : 4305 )
+#endif
+
+
+/*lint -save -e736 loss of precision */
+static const Float_t ABYule[9][multiple_of(4, 2 * YULE_ORDER + 1)] = {
+ /* 20 18 16 14 12 10 8 6 4 2 0 19 17 15 13 11 9 7 5 3 1 */
+ { 0.00288463683916, 0.00012025322027, 0.00306428023191, 0.00594298065125, -0.02074045215285, 0.02161526843274, -0.01655260341619, -0.00009291677959, -0.00123395316851, -0.02160367184185, 0.03857599435200, 0.13919314567432, -0.86984376593551, 2.75465861874613, -5.87257861775999, 9.48293806319790,-12.28759895145294, 13.05504219327545,-11.34170355132042, 7.81501653005538, -3.84664617118067},
+ {-0.00187763777362, 0.00674613682247, -0.00240879051584, 0.01624864962975, -0.02596338512915, 0.02245293253339, -0.00834990904936, -0.00851165645469, -0.00848709379851, -0.02911007808948, 0.05418656406430, 0.13149317958808, -0.75104302451432, 2.19611684890774, -4.39470996079559, 6.85401540936998, -8.81498681370155, 9.47693607801280, -8.54751527471874, 6.36317777566148, -3.47845948550071},
+ {-0.00881362733839, 0.00651420667831, -0.01390589421898, 0.03174092540049, 0.00222312597743, 0.04781476674921, -0.05588393329856, 0.02163541888798, -0.06247880153653, -0.09331049056315, 0.15457299681924, 0.02347897407020, -0.05032077717131, 0.16378164858596, -0.45953458054983, 1.00595954808547, -1.67148153367602, 2.23697657451713, -2.64577170229825, 2.84868151156327, -2.37898834973084},
+ {-0.02950134983287, 0.00205861885564, -0.00000828086748, 0.06276101321749, -0.00584456039913, -0.02364141202522, -0.00915702933434, 0.03282930172664, -0.08587323730772, -0.22613988682123, 0.30296907319327, 0.00302439095741, 0.02005851806501, 0.04500235387352, -0.22138138954925, 0.39120800788284, -0.22638893773906, -0.16276719120440, -0.25656257754070, 1.07977492259970, -1.61273165137247},
+ {-0.01760176568150, -0.01635381384540, 0.00832043980773, 0.05724228140351, -0.00589500224440, -0.00469977914380, -0.07834489609479, 0.11921148675203, -0.11828570177555, -0.25572241425570, 0.33642304856132, 0.02977207319925, -0.04237348025746, 0.08333755284107, -0.04067510197014, -0.12453458140019, 0.47854794562326, -0.80774944671438, 0.12205022308084, 0.87350271418188, -1.49858979367799},
+ { 0.00541907748707, -0.03193428438915, -0.01863887810927, 0.10478503600251, 0.04097565135648, -0.12398163381748, 0.04078262797139, -0.01419140100551, -0.22784394429749, -0.14351757464547, 0.44915256608450, 0.03222754072173, 0.05784820375801, 0.06747620744683, 0.00613424350682, 0.22199650564824, -0.42029820170918, 0.00213767857124, -0.37256372942400, 0.29661783706366, -0.62820619233671},
+ {-0.00588215443421, -0.03788984554840, 0.08647503780351, 0.00647310677246, -0.27562961986224, 0.30931782841830, -0.18901604199609, 0.16744243493672, 0.16242137742230, -0.75464456939302, 0.56619470757641, 0.01807364323573, 0.01639907836189, -0.04784254229033, 0.06739368333110, -0.33032403314006, 0.45054734505008, 0.00819999645858, -0.26806001042947, 0.29156311971249, -1.04800335126349},
+ {-0.00749618797172, -0.03721611395801, 0.06920467763959, 0.01628462406333, -0.25344790059353, 0.15558449135573, 0.02377945217615, 0.17520704835522, -0.14289799034253, -0.53174909058578, 0.58100494960553, 0.01818801111503, 0.02442357316099, -0.02505961724053, -0.05246019024463, -0.23313271880868, 0.38952639978999, 0.14728154134330, -0.20256413484477, -0.31863563325245, -0.51035327095184},
+ {-0.02217936801134, 0.04788665548180, -0.04060034127000, -0.11202315195388, -0.02459864859345, 0.14590772289388, -0.10214864179676, 0.04267842219415, -0.00275953611929, -0.42163034350696, 0.53648789255105, 0.04704409688120, 0.05477720428674, -0.18823009262115, -0.17556493366449, 0.15113130533216, 0.26408300200955, -0.04678328784242, -0.03424681017675, -0.43193942311114, -0.25049871956020}
+};
+
+static const Float_t ABButter[9][multiple_of(4, 2 * BUTTER_ORDER + 1)] = {
+ /* 5 4 3 2 1 */
+ {0.98621192462708, 0.97261396931306, -1.97242384925416, -1.97223372919527, 0.98621192462708},
+ {0.98500175787242, 0.97022847566350, -1.97000351574484, -1.96977855582618, 0.98500175787242},
+ {0.97938932735214, 0.95920349965459, -1.95877865470428, -1.95835380975398, 0.97938932735214},
+ {0.97531843204928, 0.95124613669835, -1.95063686409857, -1.95002759149878, 0.97531843204928},
+ {0.97316523498161, 0.94705070426118, -1.94633046996323, -1.94561023566527, 0.97316523498161},
+ {0.96454515552826, 0.93034775234268, -1.92909031105652, -1.92783286977036, 0.96454515552826},
+ {0.96009142950541, 0.92177618768381, -1.92018285901082, -1.91858953033784, 0.96009142950541},
+ {0.95856916599601, 0.91885558323625, -1.91713833199203, -1.91542108074780, 0.95856916599601},
+ {0.94597685600279, 0.89487434461664, -1.89195371200558, -1.88903307939452, 0.94597685600279}
+};
+
+/*lint -restore */
+
+#ifdef WIN32
+#pragma warning ( default : 4305 )
+#endif
+
+/* When calling this procedure, make sure that ip[-order] and op[-order] point to real data! */
+
+static void
+filterYule(const Float_t * input, Float_t * output, size_t nSamples, const Float_t * const kernel)
+{
+ while (nSamples--) {
+ Float_t y0 = input[-10] * kernel[ 0];
+ Float_t y2 = input[ -9] * kernel[ 1];
+ Float_t y4 = input[ -8] * kernel[ 2];
+ Float_t y6 = input[ -7] * kernel[ 3];
+ Float_t s00 = y0 + y2 + y4 + y6;
+ Float_t y8 = input[ -6] * kernel[ 4];
+ Float_t yA = input[ -5] * kernel[ 5];
+ Float_t yC = input[ -4] * kernel[ 6];
+ Float_t yE = input[ -3] * kernel[ 7];
+ Float_t s01 = y8 + yA + yC + yE;
+ Float_t yG = input[ -2] * kernel[ 8] + input[ -1] * kernel[ 9];
+ Float_t yK = input[ 0] * kernel[10];
+
+ Float_t s1 = s00 + s01 + yG + yK;
+
+ Float_t x1 = output[-10] * kernel[11] + output[ -9] * kernel[12];
+ Float_t x5 = output[ -8] * kernel[13] + output[ -7] * kernel[14];
+ Float_t x9 = output[ -6] * kernel[15] + output[ -5] * kernel[16];
+ Float_t xD = output[ -4] * kernel[17] + output[ -3] * kernel[18];
+ Float_t xH = output[ -2] * kernel[19] + output[ -1] * kernel[20];
+
+ Float_t s2 = x1 + x5 + x9 + xD + xH;
+
+ output[0] = (Float_t)(s1 - s2);
+
+ ++output;
+ ++input;
+ }
+}
+
+static void
+filterButter(const Float_t * input, Float_t * output, size_t nSamples, const Float_t * const kernel)
+{
+ while (nSamples--) {
+ Float_t s1 = input[-2] * kernel[0] + input[-1] * kernel[2] + input[ 0] * kernel[4];
+ Float_t s2 = output[-2] * kernel[1] + output[-1] * kernel[3];
+ output[0] = (Float_t)(s1 - s2);
+ ++output;
+ ++input;
+ }
+}
+
+
+
+static int ResetSampleFrequency(replaygain_t * rgData, long samplefreq);
+
+/* returns a INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if not */
+
+int
+ResetSampleFrequency(replaygain_t * rgData, long samplefreq)
+{
+ /* zero out initial values, only first MAX_ORDER values */
+ memset(rgData->linprebuf, 0, MAX_ORDER * sizeof(*rgData->linprebuf));
+ memset(rgData->rinprebuf, 0, MAX_ORDER * sizeof(*rgData->rinprebuf));
+ memset(rgData->lstepbuf, 0, MAX_ORDER * sizeof(*rgData->lstepbuf));
+ memset(rgData->rstepbuf, 0, MAX_ORDER * sizeof(*rgData->rstepbuf));
+ memset(rgData->loutbuf, 0, MAX_ORDER * sizeof(*rgData->loutbuf));
+ memset(rgData->routbuf, 0, MAX_ORDER * sizeof(*rgData->routbuf));
+
+ switch ((int) (samplefreq)) {
+ case 48000:
+ rgData->freqindex = 0;
+ break;
+ case 44100:
+ rgData->freqindex = 1;
+ break;
+ case 32000:
+ rgData->freqindex = 2;
+ break;
+ case 24000:
+ rgData->freqindex = 3;
+ break;
+ case 22050:
+ rgData->freqindex = 4;
+ break;
+ case 16000:
+ rgData->freqindex = 5;
+ break;
+ case 12000:
+ rgData->freqindex = 6;
+ break;
+ case 11025:
+ rgData->freqindex = 7;
+ break;
+ case 8000:
+ rgData->freqindex = 8;
+ break;
+ default:
+ return INIT_GAIN_ANALYSIS_ERROR;
+ }
+
+ rgData->sampleWindow =
+ (samplefreq * RMS_WINDOW_TIME_NUMERATOR + RMS_WINDOW_TIME_DENOMINATOR -
+ 1) / RMS_WINDOW_TIME_DENOMINATOR;
+
+ rgData->lsum = 0.;
+ rgData->rsum = 0.;
+ rgData->totsamp = 0;
+
+ memset(rgData->A, 0, sizeof(rgData->A));
+
+ return INIT_GAIN_ANALYSIS_OK;
+}
+
+int
+InitGainAnalysis(replaygain_t * rgData, long samplefreq)
+{
+ if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) {
+ return INIT_GAIN_ANALYSIS_ERROR;
+ }
+
+ rgData->linpre = rgData->linprebuf + MAX_ORDER;
+ rgData->rinpre = rgData->rinprebuf + MAX_ORDER;
+ rgData->lstep = rgData->lstepbuf + MAX_ORDER;
+ rgData->rstep = rgData->rstepbuf + MAX_ORDER;
+ rgData->lout = rgData->loutbuf + MAX_ORDER;
+ rgData->rout = rgData->routbuf + MAX_ORDER;
+
+ memset(rgData->B, 0, sizeof(rgData->B));
+
+ return INIT_GAIN_ANALYSIS_OK;
+}
+
+/* returns GAIN_ANALYSIS_OK if successful, GAIN_ANALYSIS_ERROR if not */
+
+int
+AnalyzeSamples(replaygain_t * rgData, const Float_t * left_samples, const Float_t * right_samples,
+ size_t num_samples, int num_channels)
+{
+ const Float_t *curleft;
+ const Float_t *curright;
+ long batchsamples;
+ long cursamples;
+ long cursamplepos;
+ int i;
+ Float_t sum_l, sum_r;
+
+ if (num_samples == 0)
+ return GAIN_ANALYSIS_OK;
+
+ cursamplepos = 0;
+ batchsamples = (long) num_samples;
+
+ switch (num_channels) {
+ case 1:
+ right_samples = left_samples;
+ break;
+ case 2:
+ break;
+ default:
+ return GAIN_ANALYSIS_ERROR;
+ }
+
+ if (num_samples < MAX_ORDER) {
+ memcpy(rgData->linprebuf + MAX_ORDER, left_samples, num_samples * sizeof(Float_t));
+ memcpy(rgData->rinprebuf + MAX_ORDER, right_samples, num_samples * sizeof(Float_t));
+ }
+ else {
+ memcpy(rgData->linprebuf + MAX_ORDER, left_samples, MAX_ORDER * sizeof(Float_t));
+ memcpy(rgData->rinprebuf + MAX_ORDER, right_samples, MAX_ORDER * sizeof(Float_t));
+ }
+
+ while (batchsamples > 0) {
+ cursamples = batchsamples > rgData->sampleWindow - rgData->totsamp ?
+ rgData->sampleWindow - rgData->totsamp : batchsamples;
+ if (cursamplepos < MAX_ORDER) {
+ curleft = rgData->linpre + cursamplepos;
+ curright = rgData->rinpre + cursamplepos;
+ if (cursamples > MAX_ORDER - cursamplepos)
+ cursamples = MAX_ORDER - cursamplepos;
+ }
+ else {
+ curleft = left_samples + cursamplepos;
+ curright = right_samples + cursamplepos;
+ }
+
+ YULE_FILTER(curleft, rgData->lstep + rgData->totsamp, cursamples,
+ ABYule[rgData->freqindex]);
+ YULE_FILTER(curright, rgData->rstep + rgData->totsamp, cursamples,
+ ABYule[rgData->freqindex]);
+
+ BUTTER_FILTER(rgData->lstep + rgData->totsamp, rgData->lout + rgData->totsamp, cursamples,
+ ABButter[rgData->freqindex]);
+ BUTTER_FILTER(rgData->rstep + rgData->totsamp, rgData->rout + rgData->totsamp, cursamples,
+ ABButter[rgData->freqindex]);
+
+ curleft = rgData->lout + rgData->totsamp; /* Get the squared values */
+ curright = rgData->rout + rgData->totsamp;
+
+ sum_l = 0;
+ sum_r = 0;
+ i = cursamples & 0x03;
+ while (i--) {
+ Float_t const l = *curleft++;
+ Float_t const r = *curright++;
+ sum_l += l * l;
+ sum_r += r * r;
+ }
+ i = cursamples / 4;
+ while (i--) {
+ Float_t l0 = curleft[0] * curleft[0];
+ Float_t l1 = curleft[1] * curleft[1];
+ Float_t l2 = curleft[2] * curleft[2];
+ Float_t l3 = curleft[3] * curleft[3];
+ Float_t sl = l0 + l1 + l2 + l3;
+ Float_t r0 = curright[0] * curright[0];
+ Float_t r1 = curright[1] * curright[1];
+ Float_t r2 = curright[2] * curright[2];
+ Float_t r3 = curright[3] * curright[3];
+ Float_t sr = r0 + r1 + r2 + r3;
+ sum_l += sl;
+ curleft += 4;
+ sum_r += sr;
+ curright += 4;
+ }
+ rgData->lsum += sum_l;
+ rgData->rsum += sum_r;
+
+ batchsamples -= cursamples;
+ cursamplepos += cursamples;
+ rgData->totsamp += cursamples;
+ if (rgData->totsamp == rgData->sampleWindow) { /* Get the Root Mean Square (RMS) for this set of samples */
+ double const val =
+ STEPS_per_dB * 10. * log10((rgData->lsum + rgData->rsum) / rgData->totsamp * 0.5 +
+ 1.e-37);
+ size_t ival = (val <= 0) ? 0 : (size_t) val;
+ if (ival >= sizeof(rgData->A) / sizeof(*(rgData->A)))
+ ival = sizeof(rgData->A) / sizeof(*(rgData->A)) - 1;
+ rgData->A[ival]++;
+ rgData->lsum = rgData->rsum = 0.;
+ memmove(rgData->loutbuf, rgData->loutbuf + rgData->totsamp,
+ MAX_ORDER * sizeof(Float_t));
+ memmove(rgData->routbuf, rgData->routbuf + rgData->totsamp,
+ MAX_ORDER * sizeof(Float_t));
+ memmove(rgData->lstepbuf, rgData->lstepbuf + rgData->totsamp,
+ MAX_ORDER * sizeof(Float_t));
+ memmove(rgData->rstepbuf, rgData->rstepbuf + rgData->totsamp,
+ MAX_ORDER * sizeof(Float_t));
+ rgData->totsamp = 0;
+ }
+ if (rgData->totsamp > rgData->sampleWindow) /* somehow I really screwed up: Error in programming! Contact author about totsamp > sampleWindow */
+ return GAIN_ANALYSIS_ERROR;
+ }
+ if (num_samples < MAX_ORDER) {
+ memmove(rgData->linprebuf, rgData->linprebuf + num_samples,
+ (MAX_ORDER - num_samples) * sizeof(Float_t));
+ memmove(rgData->rinprebuf, rgData->rinprebuf + num_samples,
+ (MAX_ORDER - num_samples) * sizeof(Float_t));
+ memcpy(rgData->linprebuf + MAX_ORDER - num_samples, left_samples,
+ num_samples * sizeof(Float_t));
+ memcpy(rgData->rinprebuf + MAX_ORDER - num_samples, right_samples,
+ num_samples * sizeof(Float_t));
+ }
+ else {
+ memcpy(rgData->linprebuf, left_samples + num_samples - MAX_ORDER,
+ MAX_ORDER * sizeof(Float_t));
+ memcpy(rgData->rinprebuf, right_samples + num_samples - MAX_ORDER,
+ MAX_ORDER * sizeof(Float_t));
+ }
+
+ return GAIN_ANALYSIS_OK;
+}
+
+
+static Float_t
+analyzeResult(uint32_t const *Array, size_t len)
+{
+ uint32_t elems;
+ uint32_t upper;
+ uint32_t sum;
+ size_t i;
+
+ elems = 0;
+ for (i = 0; i < len; i++)
+ elems += Array[i];
+ if (elems == 0)
+ return GAIN_NOT_ENOUGH_SAMPLES;
+
+ upper = (uint32_t) ceil(elems * (1. - RMS_PERCENTILE));
+ sum = 0;
+ for (i = len; i-- > 0;) {
+ sum += Array[i];
+ if (sum >= upper) {
+ break;
+ }
+ }
+
+ return (Float_t) ((Float_t) PINK_REF - (Float_t) i / (Float_t) STEPS_per_dB);
+}
+
+
+Float_t
+GetTitleGain(replaygain_t * rgData)
+{
+ Float_t retval;
+ unsigned int i;
+
+ retval = analyzeResult(rgData->A, sizeof(rgData->A) / sizeof(*(rgData->A)));
+
+ for (i = 0; i < sizeof(rgData->A) / sizeof(*(rgData->A)); i++) {
+ rgData->B[i] += rgData->A[i];
+ rgData->A[i] = 0;
+ }
+
+ for (i = 0; i < MAX_ORDER; i++)
+ rgData->linprebuf[i] = rgData->lstepbuf[i]
+ = rgData->loutbuf[i]
+ = rgData->rinprebuf[i]
+ = rgData->rstepbuf[i]
+ = rgData->routbuf[i] = 0.f;
+
+ rgData->totsamp = 0;
+ rgData->lsum = rgData->rsum = 0.;
+ return retval;
+}
+
+#if 0
+static Float_t GetAlbumGain(replaygain_t const* rgData);
+
+Float_t
+GetAlbumGain(replaygain_t const* rgData)
+{
+ return analyzeResult(rgData->B, sizeof(rgData->B) / sizeof(*(rgData->B)));
+}
+#endif
+
+/* end of gain_analysis.c */
diff --git a/pkg/lame/clame/gain_analysis.h b/pkg/lame/clame/gain_analysis.h
new file mode 100644
index 0000000..a6b56ab
--- /dev/null
+++ b/pkg/lame/clame/gain_analysis.h
@@ -0,0 +1,109 @@
+/*
+ * ReplayGainAnalysis - analyzes input samples and give the recommended dB change
+ * Copyright (C) 2001 David Robinson and Glen Sawyer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * concept and filter values by David Robinson (David@Robinson.org)
+ * -- blame him if you think the idea is flawed
+ * coding by Glen Sawyer (mp3gain@hotmail.com) 735 W 255 N, Orem, UT 84057-4505 USA
+ * -- blame him if you think this runs too slowly, or the coding is otherwise flawed
+ *
+ * For an explanation of the concepts and the basic algorithms involved, go to:
+ * http://www.replaygain.org/
+ */
+
+#ifndef GAIN_ANALYSIS_H
+#define GAIN_ANALYSIS_H
+
+#ifdef HAVE_INTTYPES_H
+# include
+#else
+# ifdef HAVE_STDINT_H
+# include
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ typedef sample_t Float_t; /* Type used for filtering */
+
+
+#define PINK_REF 64.82 /* 298640883795 */ /* calibration value for 89dB */
+
+
+#define YULE_ORDER 10
+#define BUTTER_ORDER 2
+#define YULE_FILTER filterYule
+#define BUTTER_FILTER filterButter
+#define RMS_PERCENTILE 0.95 /* percentile which is louder than the proposed level */
+#define MAX_SAMP_FREQ 48000L /* maximum allowed sample frequency [Hz] */
+#define RMS_WINDOW_TIME_NUMERATOR 1L
+#define RMS_WINDOW_TIME_DENOMINATOR 20L /* numerator / denominator = time slice size [s] */
+#define STEPS_per_dB 100 /* Table entries per dB */
+#define MAX_dB 120 /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */
+
+ enum { GAIN_NOT_ENOUGH_SAMPLES = -24601, GAIN_ANALYSIS_ERROR = 0, GAIN_ANALYSIS_OK =
+ 1, INIT_GAIN_ANALYSIS_ERROR = 0, INIT_GAIN_ANALYSIS_OK = 1
+ };
+
+ enum { MAX_ORDER = (BUTTER_ORDER > YULE_ORDER ? BUTTER_ORDER : YULE_ORDER)
+ , MAX_SAMPLES_PER_WINDOW = ((MAX_SAMP_FREQ * RMS_WINDOW_TIME_NUMERATOR) / RMS_WINDOW_TIME_DENOMINATOR + 1) /* max. Samples per Time slice */
+ };
+
+ struct replaygain_data {
+ Float_t linprebuf[MAX_ORDER * 2];
+ Float_t *linpre; /* left input samples, with pre-buffer */
+ Float_t lstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
+ Float_t *lstep; /* left "first step" (i.e. post first filter) samples */
+ Float_t loutbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
+ Float_t *lout; /* left "out" (i.e. post second filter) samples */
+ Float_t rinprebuf[MAX_ORDER * 2];
+ Float_t *rinpre; /* right input samples ... */
+ Float_t rstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
+ Float_t *rstep;
+ Float_t routbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];
+ Float_t *rout;
+ long sampleWindow; /* number of samples required to reach number of milliseconds required for RMS window */
+ long totsamp;
+ double lsum;
+ double rsum;
+ int freqindex;
+ int first;
+ uint32_t A[STEPS_per_dB * MAX_dB];
+ uint32_t B[STEPS_per_dB * MAX_dB];
+
+ };
+#ifndef replaygain_data_defined
+#define replaygain_data_defined
+ typedef struct replaygain_data replaygain_t;
+#endif
+
+
+
+
+ int InitGainAnalysis(replaygain_t * rgData, long samplefreq);
+ int AnalyzeSamples(replaygain_t * rgData, const Float_t * left_samples,
+ const Float_t * right_samples, size_t num_samples, int num_channels);
+ Float_t GetTitleGain(replaygain_t * rgData);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* GAIN_ANALYSIS_H */
diff --git a/pkg/lame/clame/id3tag.c b/pkg/lame/clame/id3tag.c
new file mode 100644
index 0000000..ac48510
--- /dev/null
+++ b/pkg/lame/clame/id3tag.c
@@ -0,0 +1,1926 @@
+/*
+ * id3tag.c -- Write ID3 version 1 and 2 tags.
+ *
+ * Copyright (C) 2000 Don Melton
+ * Copyright (C) 2011-2017 Robert Hegemann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * HISTORY: This source file is part of LAME (see http://www.mp3dev.org)
+ * and was originally adapted by Conrad Sanderson
+ * from mp3info by Ricardo Cerqueira to write only ID3 version 1
+ * tags. Don Melton COMPLETELY rewrote it to support version
+ * 2 tags and be more conformant to other standards while remaining flexible.
+ *
+ * NOTE: See http://id3.org/ for more information about ID3 tag formats.
+ */
+
+/* $Id: id3tag.c,v 1.80 2017/08/28 15:39:51 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include
+#endif
+
+#ifdef STDC_HEADERS
+# include
+# include
+# include
+# include
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "id3tag.h"
+#include "lame_global_flags.h"
+#include "util.h"
+#include "bitstream.h"
+
+
+static const char *const genre_names[] = {
+ /*
+ * NOTE: The spelling of these genre names is identical to those found in
+ * Winamp and mp3info.
+ */
+ "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge",
+ "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B",
+ "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska",
+ "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop",
+ "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental",
+ "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "Alternative Rock",
+ "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop",
+ "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial",
+ "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy",
+ "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle",
+ "Native US", "Cabaret", "New Wave", "Psychedelic", "Rave",
+ "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz",
+ "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk",
+ "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin",
+ "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock",
+ "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock",
+ "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech",
+ "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass",
+ "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba",
+ "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet",
+ "Punk Rock", "Drum Solo", "A Cappella", "Euro-House", "Dance Hall",
+ "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie",
+ "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta",
+ "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian",
+ "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
+ "SynthPop"
+};
+
+#define GENRE_NAME_COUNT \
+ ((int)(sizeof genre_names / sizeof (const char *const)))
+
+static const int genre_alpha_map[] = {
+ 123, 34, 74, 73, 99, 20, 40, 26, 145, 90, 116, 41, 135, 85, 96, 138, 89, 0,
+ 107, 132, 65, 88, 104, 102, 97, 136, 61, 141, 32, 1, 112, 128, 57, 140, 2,
+ 139, 58, 3, 125, 50, 22, 4, 55, 127, 122, 120, 98, 52, 48, 54, 124, 25, 84,
+ 80, 115, 81, 119, 5, 30, 36, 59, 126, 38, 49, 91, 6, 129, 79, 137, 7, 35,
+ 100, 131, 19, 33, 46, 47, 8, 29, 146, 63, 86, 71, 45, 142, 9, 77, 82, 64,
+ 133, 10, 66, 39, 11, 103, 12, 75, 134, 13, 53, 62, 109, 117, 23, 108, 92,
+ 67, 93, 43, 121, 15, 68, 14, 16, 76, 87, 118, 17, 78, 143, 114, 110, 69, 21,
+ 111, 95, 105, 42, 37, 24, 56, 44, 101, 83, 94, 106, 147, 113, 18, 51, 130,
+ 144, 60, 70, 31, 72, 27, 28
+};
+
+#define GENRE_ALPHA_COUNT ((int)(sizeof genre_alpha_map / sizeof (int)))
+
+#define GENRE_INDEX_OTHER 12
+
+
+#define FRAME_ID(a, b, c, d) \
+ ( ((unsigned long)(a) << 24) \
+ | ((unsigned long)(b) << 16) \
+ | ((unsigned long)(c) << 8) \
+ | ((unsigned long)(d) << 0) )
+
+typedef enum UsualStringIDs { ID_TITLE = FRAME_ID('T', 'I', 'T', '2')
+ , ID_ARTIST = FRAME_ID('T', 'P', 'E', '1')
+ , ID_ALBUM = FRAME_ID('T', 'A', 'L', 'B')
+ , ID_GENRE = FRAME_ID('T', 'C', 'O', 'N')
+ , ID_ENCODER = FRAME_ID('T', 'S', 'S', 'E')
+ , ID_PLAYLENGTH = FRAME_ID('T', 'L', 'E', 'N')
+ , ID_COMMENT = FRAME_ID('C', 'O', 'M', 'M') /* full text string */
+} UsualStringIDs;
+
+typedef enum NumericStringIDs { ID_DATE = FRAME_ID('T', 'D', 'A', 'T') /* "ddMM" */
+ , ID_TIME = FRAME_ID('T', 'I', 'M', 'E') /* "hhmm" */
+ , ID_TPOS = FRAME_ID('T', 'P', 'O', 'S') /* '0'-'9' and '/' allowed */
+ , ID_TRACK = FRAME_ID('T', 'R', 'C', 'K') /* '0'-'9' and '/' allowed */
+ , ID_YEAR = FRAME_ID('T', 'Y', 'E', 'R') /* "yyyy" */
+} NumericStringIDs;
+
+typedef enum MiscIDs { ID_TXXX = FRAME_ID('T', 'X', 'X', 'X')
+ , ID_WXXX = FRAME_ID('W', 'X', 'X', 'X')
+ , ID_SYLT = FRAME_ID('S', 'Y', 'L', 'T')
+ , ID_APIC = FRAME_ID('A', 'P', 'I', 'C')
+ , ID_GEOB = FRAME_ID('G', 'E', 'O', 'B')
+ , ID_PCNT = FRAME_ID('P', 'C', 'N', 'T')
+ , ID_AENC = FRAME_ID('A', 'E', 'N', 'C')
+ , ID_LINK = FRAME_ID('L', 'I', 'N', 'K')
+ , ID_ENCR = FRAME_ID('E', 'N', 'C', 'R')
+ , ID_GRID = FRAME_ID('G', 'R', 'I', 'D')
+ , ID_PRIV = FRAME_ID('P', 'R', 'I', 'V')
+ , ID_USLT = FRAME_ID('U', 'S', 'L', 'T') /* full text string */
+ , ID_USER = FRAME_ID('U', 'S', 'E', 'R') /* full text string */
+ , ID_PCST = FRAME_ID('P', 'C', 'S', 'T') /* iTunes Podcast indicator, only presence important */
+ , ID_WFED = FRAME_ID('W', 'F', 'E', 'D') /* iTunes Podcast URL as TEXT FRAME !!! violates standard */
+} MiscIDs;
+
+
+static int
+frame_id_matches(int id, int mask)
+{
+ int result = 0, i, window = 0xff;
+ for (i = 0; i < 4; ++i, window <<= 8) {
+ int const mw = (mask & window);
+ int const iw = (id & window);
+ if (mw != 0 && mw != iw) {
+ result |= iw;
+ }
+ }
+ return result;
+}
+
+static int
+isFrameIdMatching(int id, int mask)
+{
+ return frame_id_matches(id, mask) == 0 ? 1 : 0;
+}
+
+static int
+test_tag_spec_flags(lame_internal_flags const *gfc, unsigned int tst)
+{
+ return (gfc->tag_spec.flags & tst) != 0u ? 1 : 0;
+}
+
+#if 0
+static void
+debug_tag_spec_flags(lame_internal_flags * gfc, const char* info)
+{
+ MSGF(gfc, "%s\n", info);
+ MSGF(gfc, "CHANGED_FLAG : %d\n", test_tag_spec_flags(gfc, CHANGED_FLAG ));
+ MSGF(gfc, "ADD_V2_FLAG : %d\n", test_tag_spec_flags(gfc, ADD_V2_FLAG ));
+ MSGF(gfc, "V1_ONLY_FLAG : %d\n", test_tag_spec_flags(gfc, V1_ONLY_FLAG ));
+ MSGF(gfc, "V2_ONLY_FLAG : %d\n", test_tag_spec_flags(gfc, V2_ONLY_FLAG ));
+ MSGF(gfc, "SPACE_V1_FLAG : %d\n", test_tag_spec_flags(gfc, SPACE_V1_FLAG));
+ MSGF(gfc, "PAD_V2_FLAG : %d\n", test_tag_spec_flags(gfc, PAD_V2_FLAG ));
+}
+#endif
+
+static int
+is_lame_internal_flags_null(lame_t gfp)
+{
+ return (gfp && gfp->internal_flags) ? 0 : 1;
+}
+
+static int
+id3v2_add_ucs2_lng(lame_t gfp, uint32_t frame_id, unsigned short const *desc, unsigned short const *text);
+static int
+id3v2_add_latin1_lng(lame_t gfp, uint32_t frame_id, char const *desc, char const *text);
+
+
+static void
+copyV1ToV2(lame_t gfp, int frame_id, char const *s)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc != 0) {
+ unsigned int flags = gfc->tag_spec.flags;
+ id3v2_add_latin1_lng(gfp, frame_id, 0, s);
+ gfc->tag_spec.flags = flags;
+#if 0
+ debug_tag_spec_flags(gfc, "copyV1ToV2");
+#endif
+ }
+}
+
+
+static void
+id3v2AddLameVersion(lame_t gfp)
+{
+ char buffer[1024];
+ const char *b = get_lame_os_bitness();
+ const char *v = get_lame_version();
+ const char *u = get_lame_url();
+ const size_t lenb = strlen(b);
+
+ if (lenb > 0) {
+ sprintf(buffer, "LAME %s version %s (%s)", b, v, u);
+ }
+ else {
+ sprintf(buffer, "LAME version %s (%s)", v, u);
+ }
+ copyV1ToV2(gfp, ID_ENCODER, buffer);
+}
+
+static void
+id3v2AddAudioDuration(lame_t gfp, double ms)
+{
+ SessionConfig_t const *const cfg = &gfp->internal_flags->cfg; /* caller checked pointers */
+ char buffer[1024];
+ double const max_ulong = MAX_U_32_NUM;
+ unsigned long playlength_ms;
+
+ ms *= 1000;
+ ms /= cfg->samplerate_in;
+ if (ms > max_ulong) {
+ playlength_ms = max_ulong;
+ }
+ else if (ms < 0) {
+ playlength_ms = 0;
+ }
+ else {
+ playlength_ms = ms;
+ }
+ sprintf(buffer, "%lu", playlength_ms);
+ copyV1ToV2(gfp, ID_PLAYLENGTH, buffer);
+}
+
+void
+id3tag_genre_list(void (*handler) (int, const char *, void *), void *cookie)
+{
+ if (handler) {
+ int i;
+ for (i = 0; i < GENRE_NAME_COUNT; ++i) {
+ if (i < GENRE_ALPHA_COUNT) {
+ int j = genre_alpha_map[i];
+ handler(j, genre_names[j], cookie);
+ }
+ }
+ }
+}
+
+#define GENRE_NUM_UNKNOWN 255
+
+
+
+void
+id3tag_init(lame_t gfp)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return;
+ }
+ gfc = gfp->internal_flags;
+ free_id3tag(gfc);
+ memset(&gfc->tag_spec, 0, sizeof gfc->tag_spec);
+ gfc->tag_spec.genre_id3v1 = GENRE_NUM_UNKNOWN;
+ gfc->tag_spec.padding_size = 128;
+ id3v2AddLameVersion(gfp);
+}
+
+
+
+void
+id3tag_add_v2(lame_t gfp)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return;
+ }
+ gfc = gfp->internal_flags;
+ gfc->tag_spec.flags &= ~V1_ONLY_FLAG;
+ gfc->tag_spec.flags |= ADD_V2_FLAG;
+}
+
+void
+id3tag_v1_only(lame_t gfp)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return;
+ }
+ gfc = gfp->internal_flags;
+ gfc->tag_spec.flags &= ~(ADD_V2_FLAG | V2_ONLY_FLAG);
+ gfc->tag_spec.flags |= V1_ONLY_FLAG;
+}
+
+void
+id3tag_v2_only(lame_t gfp)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return;
+ }
+ gfc = gfp->internal_flags;
+ gfc->tag_spec.flags &= ~V1_ONLY_FLAG;
+ gfc->tag_spec.flags |= V2_ONLY_FLAG;
+}
+
+void
+id3tag_space_v1(lame_t gfp)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return;
+ }
+ gfc = gfp->internal_flags;
+ gfc->tag_spec.flags &= ~V2_ONLY_FLAG;
+ gfc->tag_spec.flags |= SPACE_V1_FLAG;
+}
+
+void
+id3tag_pad_v2(lame_t gfp)
+{
+ id3tag_set_pad(gfp, 128);
+}
+
+void
+id3tag_set_pad(lame_t gfp, size_t n)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return;
+ }
+ gfc = gfp->internal_flags;
+ gfc->tag_spec.flags &= ~V1_ONLY_FLAG;
+ gfc->tag_spec.flags |= PAD_V2_FLAG;
+ gfc->tag_spec.flags |= ADD_V2_FLAG;
+ gfc->tag_spec.padding_size = (unsigned int)n;
+}
+
+static int
+hasUcs2ByteOrderMarker(unsigned short bom)
+{
+ if (bom == 0xFFFEu || bom == 0xFEFFu) {
+ return 1;
+ }
+ return 0;
+}
+
+
+static unsigned short
+swap_bytes(unsigned short w)
+{
+ return (0xff00u & (w << 8)) | (0x00ffu & (w >> 8));
+}
+
+
+static unsigned short
+toLittleEndian(unsigned short bom, unsigned short c)
+{
+ if (bom == 0xFFFEu) {
+ return swap_bytes(c);
+ }
+ return c;
+}
+
+static unsigned short
+fromLatin1Char(const unsigned short* s, unsigned short c)
+{
+ if (s[0] == 0xFFFEu) {
+ return swap_bytes(c);
+ }
+ return c;
+}
+
+
+static size_t
+local_strdup(char **dst, const char *src)
+{
+ if (dst == 0) {
+ return 0;
+ }
+ free(*dst);
+ *dst = 0;
+ if (src != 0) {
+ size_t n;
+ for (n = 0; src[n] != 0; ++n) { /* calc src string length */
+ }
+ if (n > 0) { /* string length without zero termination */
+ assert(sizeof(*src) == sizeof(**dst));
+ *dst = lame_calloc(char, n + 1);
+ if (*dst != 0) {
+ memcpy(*dst, src, n * sizeof(**dst));
+ (*dst)[n] = 0;
+ return n;
+ }
+ }
+ }
+ return 0;
+}
+
+static size_t
+local_ucs2_strdup(unsigned short **dst, unsigned short const *src)
+{
+ if (dst == 0) {
+ return 0;
+ }
+ free(*dst); /* free old string pointer */
+ *dst = 0;
+ if (src != 0) {
+ size_t n;
+ for (n = 0; src[n] != 0; ++n) { /* calc src string length */
+ }
+ if (n > 0) { /* string length without zero termination */
+ assert(sizeof(*src) >= 2);
+ assert(sizeof(*src) == sizeof(**dst));
+ *dst = lame_calloc(unsigned short, n + 1);
+ if (*dst != 0) {
+ memcpy(*dst, src, n * sizeof(**dst));
+ (*dst)[n] = 0;
+ return n;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static size_t
+local_ucs2_strlen(unsigned short const *s)
+{
+ size_t n = 0;
+ if (s != 0) {
+ while (*s++) {
+ ++n;
+ }
+ }
+ return n;
+}
+
+
+static size_t
+local_ucs2_substr(unsigned short** dst, unsigned short const* src, size_t start, size_t end)
+{
+ size_t const len = 1 + 1 + ((start < end) ? (end - start) : 0);
+ size_t n = 0;
+ unsigned short *ptr = lame_calloc(unsigned short, len);
+ *dst = ptr;
+ if (ptr == 0 || src == 0) {
+ return 0;
+ }
+ if (hasUcs2ByteOrderMarker(src[0])) {
+ ptr[n++] = src[0];
+ if (start == 0) {
+ ++start;
+ }
+ }
+ while (start < end) {
+ ptr[n++] = src[start++];
+ }
+ ptr[n] = 0;
+ return n;
+}
+
+static int
+local_ucs2_pos(unsigned short const* str, unsigned short c)
+{
+ int i;
+ for (i = 0; str != 0 && str[i] != 0; ++i) {
+ if (str[i] == c) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int
+local_char_pos(char const* str, char c)
+{
+ int i;
+ for (i = 0; str != 0 && str[i] != 0; ++i) {
+ if (str[i] == c) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int
+maybeLatin1(unsigned short const* text)
+{
+ if (text) {
+ unsigned short bom = *text++;
+ while (*text) {
+ unsigned short c = toLittleEndian(bom, *text++);
+ if (c > 0x00fe) return 0;
+ }
+ }
+ return 1;
+}
+
+static int searchGenre(char const* genre);
+static int sloppySearchGenre(char const* genre);
+
+static int
+lookupGenre(char const* genre)
+{
+ char *str;
+ int num = strtol(genre, &str, 10);
+ /* is the input a string or a valid number? */
+ if (*str) {
+ num = searchGenre(genre);
+ if (num == GENRE_NAME_COUNT) {
+ num = sloppySearchGenre(genre);
+ }
+ if (num == GENRE_NAME_COUNT) {
+ return -2; /* no common genre text found */
+ }
+ }
+ else {
+ if ((num < 0) || (num >= GENRE_NAME_COUNT)) {
+ return -1; /* number unknown */
+ }
+ }
+ return num;
+}
+
+static unsigned char *
+writeLoBytes(unsigned char *frame, unsigned short const *str, size_t n);
+
+static char*
+local_strdup_utf16_to_latin1(unsigned short const* utf16)
+{
+ size_t len = local_ucs2_strlen(utf16);
+ unsigned char* latin1 = lame_calloc(unsigned char, len+1);
+ writeLoBytes(latin1, utf16, len);
+ return (char*)latin1;
+}
+
+
+static int
+id3tag_set_genre_utf16(lame_t gfp, unsigned short const* text)
+{
+ lame_internal_flags* gfc = gfp->internal_flags;
+ int ret;
+ if (text == 0) {
+ return -3;
+ }
+ if (!hasUcs2ByteOrderMarker(text[0])) {
+ return -3;
+ }
+ if (maybeLatin1(text)) {
+ char* latin1 = local_strdup_utf16_to_latin1(text);
+ int num = lookupGenre(latin1);
+ free(latin1);
+ if (num == -1) return -1; /* number out of range */
+ if (num >= 0) { /* common genre found */
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ gfc->tag_spec.genre_id3v1 = num;
+ copyV1ToV2(gfp, ID_GENRE, genre_names[num]);
+ return 0;
+ }
+ }
+ ret = id3v2_add_ucs2_lng(gfp, ID_GENRE, 0, text);
+ if (ret == 0) {
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ gfc->tag_spec.genre_id3v1 = GENRE_INDEX_OTHER;
+ }
+ return ret;
+}
+
+/*
+Some existing options for ID3 tag can be specified by --tv option
+as follows.
+--tt , --tv TIT2=value
+--ta , --tv TPE1=value
+--tl , --tv TALB=value
+--ty , --tv TYER=value
+--tn , --tv TRCK=value
+--tg , --tv TCON=value
+(although some are not exactly same)*/
+
+int
+id3tag_set_albumart(lame_t gfp, const char *image, size_t size)
+{
+ int mimetype = MIMETYPE_NONE;
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ gfc = gfp->internal_flags;
+
+ if (image != 0) {
+ unsigned char const *data = (unsigned char const *) image;
+ /* determine MIME type from the actual image data */
+ if (2 < size && data[0] == 0xFF && data[1] == 0xD8) {
+ mimetype = MIMETYPE_JPEG;
+ }
+ else if (4 < size && data[0] == 0x89 && strncmp((const char *) &data[1], "PNG", 3) == 0) {
+ mimetype = MIMETYPE_PNG;
+ }
+ else if (4 < size && strncmp((const char *) data, "GIF8", 4) == 0) {
+ mimetype = MIMETYPE_GIF;
+ }
+ else {
+ return -1;
+ }
+ }
+ if (gfc->tag_spec.albumart != 0) {
+ free(gfc->tag_spec.albumart);
+ gfc->tag_spec.albumart = 0;
+ gfc->tag_spec.albumart_size = 0;
+ gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE;
+ }
+ if (size < 1 || mimetype == MIMETYPE_NONE) {
+ return 0;
+ }
+ gfc->tag_spec.albumart = lame_calloc(unsigned char, size);
+ if (gfc->tag_spec.albumart != 0) {
+ memcpy(gfc->tag_spec.albumart, image, size);
+ gfc->tag_spec.albumart_size = (unsigned int)size;
+ gfc->tag_spec.albumart_mimetype = mimetype;
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ id3tag_add_v2(gfp);
+ }
+ return 0;
+}
+
+static unsigned char *
+set_4_byte_value(unsigned char *bytes, uint32_t value)
+{
+ int i;
+ for (i = 3; i >= 0; --i) {
+ bytes[i] = value & 0xffUL;
+ value >>= 8;
+ }
+ return bytes + 4;
+}
+
+static uint32_t
+toID3v2TagId(char const *s)
+{
+ unsigned int i, x = 0;
+ if (s == 0) {
+ return 0;
+ }
+ for (i = 0; i < 4 && s[i] != 0; ++i) {
+ char const c = s[i];
+ unsigned int const u = 0x0ff & c;
+ x <<= 8;
+ x |= u;
+ if (c < 'A' || 'Z' < c) {
+ if (c < '0' || '9' < c) {
+ return 0;
+ }
+ }
+ }
+ return x;
+}
+
+static uint32_t
+toID3v2TagId_ucs2(unsigned short const *s)
+{
+ unsigned int i, x = 0;
+ unsigned short bom = 0;
+ if (s == 0) {
+ return 0;
+ }
+ bom = s[0];
+ if (hasUcs2ByteOrderMarker(bom)) {
+ ++s;
+ }
+ for (i = 0; i < 4 && s[i] != 0; ++i) {
+ unsigned short const c = toLittleEndian(bom, s[i]);
+ if (c < 'A' || 'Z' < c) {
+ if (c < '0' || '9' < c) {
+ return 0;
+ }
+ }
+ x <<= 8;
+ x |= c;
+ }
+ return x;
+}
+
+#if 0
+static int
+isNumericString(uint32_t frame_id)
+{
+ switch (frame_id) {
+ case ID_DATE:
+ case ID_TIME:
+ case ID_TPOS:
+ case ID_TRACK:
+ case ID_YEAR:
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+static int
+isMultiFrame(uint32_t frame_id)
+{
+ switch (frame_id) {
+ case ID_TXXX:
+ case ID_WXXX:
+ case ID_COMMENT:
+ case ID_SYLT:
+ case ID_APIC:
+ case ID_GEOB:
+ case ID_PCNT:
+ case ID_AENC:
+ case ID_LINK:
+ case ID_ENCR:
+ case ID_GRID:
+ case ID_PRIV:
+ return 1;
+ }
+ return 0;
+}
+
+#if 0
+static int
+isFullTextString(int frame_id)
+{
+ switch (frame_id) {
+ case ID_VSLT:
+ case ID_COMMENT:
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+static FrameDataNode *
+findNode(id3tag_spec const *tag, uint32_t frame_id, FrameDataNode const *last)
+{
+ FrameDataNode *node = last ? last->nxt : tag->v2_head;
+ while (node != 0) {
+ if (node->fid == frame_id) {
+ return node;
+ }
+ node = node->nxt;
+ }
+ return 0;
+}
+
+static void
+appendNode(id3tag_spec * tag, FrameDataNode * node)
+{
+ if (tag->v2_tail == 0 || tag->v2_head == 0) {
+ tag->v2_head = node;
+ tag->v2_tail = node;
+ }
+ else {
+ tag->v2_tail->nxt = node;
+ tag->v2_tail = node;
+ }
+}
+
+static void
+setLang(char *dst, char const *src)
+{
+ int i;
+ if (src == 0 || src[0] == 0) {
+ dst[0] = 'e';
+ dst[1] = 'n';
+ dst[2] = 'g';
+ }
+ else {
+ for (i = 0; i < 3 && src && *src; ++i) {
+ dst[i] = src[i];
+ }
+ for (; i < 3; ++i) {
+ dst[i] = ' ';
+ }
+ }
+}
+
+static int
+isSameLang(char const *l1, char const *l2)
+{
+ char d[3];
+ int i;
+ setLang(d, l2);
+ for (i = 0; i < 3; ++i) {
+ char a = tolower(l1[i]);
+ char b = tolower(d[i]);
+ if (a < ' ')
+ a = ' ';
+ if (b < ' ')
+ b = ' ';
+ if (a != b) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+isSameDescriptor(FrameDataNode const *node, char const *dsc)
+{
+ size_t i;
+ if (node->dsc.enc == 1 && node->dsc.dim > 0) {
+ return 0;
+ }
+ for (i = 0; i < node->dsc.dim; ++i) {
+ if (!dsc || node->dsc.ptr.l[i] != dsc[i]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+isSameDescriptorUcs2(FrameDataNode const *node, unsigned short const *dsc)
+{
+ size_t i;
+ if (node->dsc.enc != 1 && node->dsc.dim > 0) {
+ return 0;
+ }
+ for (i = 0; i < node->dsc.dim; ++i) {
+ if (!dsc || node->dsc.ptr.u[i] != dsc[i]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+id3v2_add_ucs2(lame_t gfp, uint32_t frame_id, char const *lng, unsigned short const *desc, unsigned short const *text)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc != 0) {
+ FrameDataNode *node = findNode(&gfc->tag_spec, frame_id, 0);
+ char lang[4];
+ setLang(lang, lng);
+ if (isMultiFrame(frame_id)) {
+ while (node) {
+ if (isSameLang(node->lng, lang)) {
+ if (isSameDescriptorUcs2(node, desc)) {
+ break;
+ }
+ }
+ node = findNode(&gfc->tag_spec, frame_id, node);
+ }
+ }
+ if (node == 0) {
+ node = lame_calloc(FrameDataNode, 1);
+ if (node == 0) {
+ return -254; /* memory problem */
+ }
+ appendNode(&gfc->tag_spec, node);
+ }
+ node->fid = frame_id;
+ setLang(node->lng, lang);
+ node->dsc.dim = local_ucs2_strdup(&node->dsc.ptr.u, desc);
+ node->dsc.enc = 1;
+ node->txt.dim = local_ucs2_strdup(&node->txt.ptr.u, text);
+ node->txt.enc = 1;
+ gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);
+ return 0;
+ }
+ return -255;
+}
+
+static int
+id3v2_add_latin1(lame_t gfp, uint32_t frame_id, char const *lng, char const *desc, char const *text)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc != 0) {
+ FrameDataNode *node = findNode(&gfc->tag_spec, frame_id, 0);
+ char lang[4];
+ setLang(lang, lng);
+ if (isMultiFrame(frame_id)) {
+ while (node) {
+ if (isSameLang(node->lng, lang)) {
+ if (isSameDescriptor(node, desc)) {
+ break;
+ }
+ }
+ node = findNode(&gfc->tag_spec, frame_id, node);
+ }
+ }
+ if (node == 0) {
+ node = lame_calloc(FrameDataNode, 1);
+ if (node == 0) {
+ return -254; /* memory problem */
+ }
+ appendNode(&gfc->tag_spec, node);
+ }
+ node->fid = frame_id;
+ setLang(node->lng, lang);
+ node->dsc.dim = local_strdup(&node->dsc.ptr.l, desc);
+ node->dsc.enc = 0;
+ node->txt.dim = local_strdup(&node->txt.ptr.l, text);
+ node->txt.enc = 0;
+ gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);
+ return 0;
+ }
+ return -255;
+}
+
+static char const*
+id3v2_get_language(lame_t gfp)
+{
+ lame_internal_flags const* gfc = gfp ? gfp->internal_flags : 0;
+ if (gfc) return gfc->tag_spec.language;
+ return 0;
+}
+
+static int
+id3v2_add_ucs2_lng(lame_t gfp, uint32_t frame_id, unsigned short const *desc, unsigned short const *text)
+{
+ char const* lang = id3v2_get_language(gfp);
+ return id3v2_add_ucs2(gfp, frame_id, lang, desc, text);
+}
+
+static int
+id3v2_add_latin1_lng(lame_t gfp, uint32_t frame_id, char const *desc, char const *text)
+{
+ char const* lang = id3v2_get_language(gfp);
+ return id3v2_add_latin1(gfp, frame_id, lang, desc, text);
+}
+
+static int
+id3tag_set_userinfo_latin1(lame_t gfp, uint32_t id, char const *fieldvalue)
+{
+ char const separator = '=';
+ int rc = -7;
+ int a = local_char_pos(fieldvalue, separator);
+ if (a >= 0) {
+ char* dup = 0;
+ local_strdup(&dup, fieldvalue);
+ dup[a] = 0;
+ rc = id3v2_add_latin1_lng(gfp, id, dup, dup+a+1);
+ free(dup);
+ }
+ return rc;
+}
+
+static int
+id3tag_set_userinfo_ucs2(lame_t gfp, uint32_t id, unsigned short const *fieldvalue)
+{
+ unsigned short const separator = fromLatin1Char(fieldvalue,'=');
+ int rc = -7;
+ size_t b = local_ucs2_strlen(fieldvalue);
+ int a = local_ucs2_pos(fieldvalue, separator);
+ if (a >= 0) {
+ unsigned short* dsc = 0, *val = 0;
+ local_ucs2_substr(&dsc, fieldvalue, 0, a);
+ local_ucs2_substr(&val, fieldvalue, a+1, b);
+ rc = id3v2_add_ucs2_lng(gfp, id, dsc, val);
+ free(dsc);
+ free(val);
+ }
+ return rc;
+}
+
+int
+id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text)
+{
+ uint32_t const frame_id = toID3v2TagId(id);
+ if (frame_id == 0) {
+ return -1;
+ }
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ if (text == 0) {
+ return 0;
+ }
+ if (!hasUcs2ByteOrderMarker(text[0])) {
+ return -3; /* BOM missing */
+ }
+ if (frame_id == ID_TXXX || frame_id == ID_WXXX || frame_id == ID_COMMENT) {
+ return id3tag_set_userinfo_ucs2(gfp, frame_id, text);
+ }
+ if (frame_id == ID_GENRE) {
+ return id3tag_set_genre_utf16(gfp, text);
+ }
+ if (frame_id == ID_PCST) {
+ return id3v2_add_ucs2_lng(gfp, frame_id, 0, text);
+ }
+ if (frame_id == ID_USER) {
+ return id3v2_add_ucs2_lng(gfp, frame_id, text, 0);
+ }
+ if (frame_id == ID_WFED) {
+ return id3v2_add_ucs2_lng(gfp, frame_id, text, 0); /* iTunes expects WFED to be a text frame */
+ }
+ if (isFrameIdMatching(frame_id, FRAME_ID('T', 0, 0, 0))
+ ||isFrameIdMatching(frame_id, FRAME_ID('W', 0, 0, 0))) {
+#if 0
+ if (isNumericString(frame_id)) {
+ return -2; /* must be Latin-1 encoded */
+ }
+#endif
+ return id3v2_add_ucs2_lng(gfp, frame_id, 0, text);
+ }
+ return -255; /* not supported by now */
+}
+
+extern int
+id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text);
+
+int
+id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text)
+{
+ return id3tag_set_textinfo_utf16(gfp, id, text);
+}
+
+int
+id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text)
+{
+ uint32_t const frame_id = toID3v2TagId(id);
+ if (frame_id == 0) {
+ return -1;
+ }
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ if (text == 0) {
+ return 0;
+ }
+ if (frame_id == ID_TXXX || frame_id == ID_WXXX || frame_id == ID_COMMENT) {
+ return id3tag_set_userinfo_latin1(gfp, frame_id, text);
+ }
+ if (frame_id == ID_GENRE) {
+ return id3tag_set_genre(gfp, text);
+ }
+ if (frame_id == ID_PCST) {
+ return id3v2_add_latin1_lng(gfp, frame_id, 0, text);
+ }
+ if (frame_id == ID_USER) {
+ return id3v2_add_latin1_lng(gfp, frame_id, text, 0);
+ }
+ if (frame_id == ID_WFED) {
+ return id3v2_add_latin1_lng(gfp, frame_id, text, 0); /* iTunes expects WFED to be a text frame */
+ }
+ if (isFrameIdMatching(frame_id, FRAME_ID('T', 0, 0, 0))
+ ||isFrameIdMatching(frame_id, FRAME_ID('W', 0, 0, 0))) {
+ return id3v2_add_latin1_lng(gfp, frame_id, 0, text);
+ }
+ return -255; /* not supported by now */
+}
+
+
+int
+id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text)
+{
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ return id3v2_add_latin1(gfp, ID_COMMENT, lang, desc, text);
+}
+
+
+int
+id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text)
+{
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ return id3v2_add_ucs2(gfp, ID_COMMENT, lang, desc, text);
+}
+
+extern int
+id3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text);
+
+
+int
+id3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text)
+{
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ return id3tag_set_comment_utf16(gfp, lang, desc, text);
+}
+
+
+void
+id3tag_set_title(lame_t gfp, const char *title)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc && title && *title) {
+ local_strdup(&gfc->tag_spec.title, title);
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ copyV1ToV2(gfp, ID_TITLE, title);
+ }
+}
+
+void
+id3tag_set_artist(lame_t gfp, const char *artist)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc && artist && *artist) {
+ local_strdup(&gfc->tag_spec.artist, artist);
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ copyV1ToV2(gfp, ID_ARTIST, artist);
+ }
+}
+
+void
+id3tag_set_album(lame_t gfp, const char *album)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc && album && *album) {
+ local_strdup(&gfc->tag_spec.album, album);
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ copyV1ToV2(gfp, ID_ALBUM, album);
+ }
+}
+
+void
+id3tag_set_year(lame_t gfp, const char *year)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc && year && *year) {
+ int num = atoi(year);
+ if (num < 0) {
+ num = 0;
+ }
+ /* limit a year to 4 digits so it fits in a version 1 tag */
+ if (num > 9999) {
+ num = 9999;
+ }
+ if (num) {
+ gfc->tag_spec.year = num;
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ }
+ copyV1ToV2(gfp, ID_YEAR, year);
+ }
+}
+
+void
+id3tag_set_comment(lame_t gfp, const char *comment)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ if (gfc && comment && *comment) {
+ local_strdup(&gfc->tag_spec.comment, comment);
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ {
+ uint32_t const flags = gfc->tag_spec.flags;
+ id3v2_add_latin1_lng(gfp, ID_COMMENT, "", comment);
+ gfc->tag_spec.flags = flags;
+ }
+ }
+}
+
+int
+id3tag_set_track(lame_t gfp, const char *track)
+{
+ char const *trackcount;
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ int ret = 0;
+
+ if (gfc && track && *track) {
+ int num = atoi(track);
+ /* check for valid ID3v1 track number range */
+ if (num < 1 || num > 255) {
+ num = 0;
+ ret = -1; /* track number out of ID3v1 range, ignored for ID3v1 */
+ gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);
+ }
+ if (num) {
+ gfc->tag_spec.track_id3v1 = num;
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ }
+ /* Look for the total track count after a "/", same restrictions */
+ trackcount = strchr(track, '/');
+ if (trackcount && *trackcount) {
+ gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);
+ }
+ copyV1ToV2(gfp, ID_TRACK, track);
+ }
+ return ret;
+}
+
+/* would use real "strcasecmp" but it isn't portable */
+static int
+local_strcasecmp(const char *s1, const char *s2)
+{
+ unsigned char c1;
+ unsigned char c2;
+ do {
+ c1 = tolower(*s1);
+ c2 = tolower(*s2);
+ if (!c1) {
+ break;
+ }
+ ++s1;
+ ++s2;
+ } while (c1 == c2);
+ return c1 - c2;
+}
+
+
+static
+const char* nextUpperAlpha(const char* p, char x)
+{
+ char c;
+ for(c = toupper(*p); *p != 0; c = toupper(*++p)) {
+ if ('A' <= c && c <= 'Z') {
+ if (c != x) {
+ return p;
+ }
+ }
+ }
+ return p;
+}
+
+
+static int
+sloppyCompared(const char* p, const char* q)
+{
+ char cp, cq;
+ p = nextUpperAlpha(p, 0);
+ q = nextUpperAlpha(q, 0);
+ cp = toupper(*p);
+ cq = toupper(*q);
+ while (cp == cq) {
+ if (cp == 0) {
+ return 1;
+ }
+ if (p[1] == '.') { /* some abbrevation */
+ while (*q && *q++ != ' ') {
+ }
+ }
+ p = nextUpperAlpha(p, cp);
+ q = nextUpperAlpha(q, cq);
+ cp = toupper(*p);
+ cq = toupper(*q);
+ }
+ return 0;
+}
+
+
+static int
+sloppySearchGenre(const char *genre)
+{
+ int i;
+ for (i = 0; i < GENRE_NAME_COUNT; ++i) {
+ if (sloppyCompared(genre, genre_names[i])) {
+ return i;
+ }
+ }
+ return GENRE_NAME_COUNT;
+}
+
+
+static int
+searchGenre(const char* genre)
+{
+ int i;
+ for (i = 0; i < GENRE_NAME_COUNT; ++i) {
+ if (!local_strcasecmp(genre, genre_names[i])) {
+ return i;
+ }
+ }
+ return GENRE_NAME_COUNT;
+}
+
+
+int
+id3tag_set_genre(lame_t gfp, const char *genre)
+{
+ lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;
+ int ret = 0;
+ if (gfc && genre && *genre) {
+ int const num = lookupGenre(genre);
+ if (num == -1) return num;
+ gfc->tag_spec.flags |= CHANGED_FLAG;
+ if (num >= 0) {
+ gfc->tag_spec.genre_id3v1 = num;
+ genre = genre_names[num];
+ }
+ else {
+ gfc->tag_spec.genre_id3v1 = GENRE_INDEX_OTHER;
+ gfc->tag_spec.flags |= ADD_V2_FLAG;
+ }
+ copyV1ToV2(gfp, ID_GENRE, genre);
+ }
+ return ret;
+}
+
+
+static size_t
+sizeOfNode(FrameDataNode const *node)
+{
+ size_t n = 0;
+ if (node) {
+ n = 10; /* header size */
+ n += 1; /* text encoding flag */
+ switch (node->txt.enc) {
+ default:
+ case 0:
+ if (node->dsc.dim > 0) {
+ n += node->dsc.dim + 1;
+ }
+ n += node->txt.dim;
+ break;
+ case 1:
+ if (node->dsc.dim > 0) {
+ n += (node->dsc.dim+1) * 2;
+ }
+ n += node->txt.dim * 2;
+ break;
+ }
+ }
+ return n;
+}
+
+static size_t
+sizeOfCommentNode(FrameDataNode const *node)
+{
+ size_t n = 0;
+ if (node) {
+ n = 10; /* header size */
+ n += 1; /* text encoding flag */
+ n += 3; /* language */
+ switch (node->dsc.enc) {
+ default:
+ case 0:
+ n += 1 + node->dsc.dim;
+ break;
+ case 1:
+ n += 2 + node->dsc.dim * 2;
+ break;
+ }
+ switch (node->txt.enc) {
+ default:
+ case 0:
+ n += node->txt.dim;
+ break;
+ case 1:
+ n += node->txt.dim * 2;
+ break;
+ }
+ }
+ return n;
+}
+
+static size_t
+sizeOfWxxxNode(FrameDataNode const *node)
+{
+ size_t n = 0;
+ if (node) {
+ n = 10; /* header size */
+ if (node->dsc.dim > 0) {
+ n += 1; /* text encoding flag */
+ switch (node->dsc.enc) {
+ default:
+ case 0:
+ n += 1 + node->dsc.dim;
+ break;
+ case 1:
+ n += 2 + node->dsc.dim * 2;
+ break;
+ }
+ }
+ if (node->txt.dim > 0) {
+ switch (node->txt.enc) {
+ default:
+ case 0:
+ n += node->txt.dim;
+ break;
+ case 1:
+ n += node->txt.dim - 1; /* UCS2 -> Latin1, skip BOM */
+ break;
+ }
+ }
+ }
+ return n;
+}
+
+static unsigned char *
+writeChars(unsigned char *frame, char const *str, size_t n)
+{
+ while (n--) {
+ *frame++ = *str++;
+ }
+ return frame;
+}
+
+static unsigned char *
+writeUcs2s(unsigned char *frame, unsigned short const *str, size_t n)
+{
+ if (n > 0) {
+ unsigned short const bom = *str;
+ while (n--) {
+ unsigned short const c = toLittleEndian(bom, *str++);
+ *frame++ = 0x00ffu & c;
+ *frame++ = 0x00ffu & (c >> 8);
+ }
+ }
+ return frame;
+}
+
+static unsigned char *
+writeLoBytes(unsigned char *frame, unsigned short const *str, size_t n)
+{
+ if (n > 0) {
+ unsigned short const bom = *str;
+ if (hasUcs2ByteOrderMarker(bom)) {
+ str++; n--; /* skip BOM */
+ }
+ while (n--) {
+ unsigned short const c = toLittleEndian(bom, *str++);
+ if (c < 0x0020u || 0x00ffu < c) {
+ *frame++ = 0x0020; /* blank */
+ }
+ else {
+ *frame++ = c;
+ }
+ }
+ }
+ return frame;
+}
+
+static unsigned char *
+set_frame_comment(unsigned char *frame, FrameDataNode const *node)
+{
+ size_t const n = sizeOfCommentNode(node);
+ if (n > 10) {
+ frame = set_4_byte_value(frame, node->fid);
+ frame = set_4_byte_value(frame, (uint32_t) (n - 10));
+ /* clear 2-byte header flags */
+ *frame++ = 0;
+ *frame++ = 0;
+ /* encoding descriptor byte */
+ *frame++ = node->txt.enc == 1 ? 1 : 0;
+ /* 3 bytes language */
+ *frame++ = node->lng[0];
+ *frame++ = node->lng[1];
+ *frame++ = node->lng[2];
+ /* descriptor with zero byte(s) separator */
+ if (node->dsc.enc != 1) {
+ frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim);
+ *frame++ = 0;
+ }
+ else {
+ frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim);
+ *frame++ = 0;
+ *frame++ = 0;
+ }
+ /* comment full text */
+ if (node->txt.enc != 1) {
+ frame = writeChars(frame, node->txt.ptr.l, node->txt.dim);
+ }
+ else {
+ frame = writeUcs2s(frame, node->txt.ptr.u, node->txt.dim);
+ }
+ }
+ return frame;
+}
+
+static unsigned char *
+set_frame_custom2(unsigned char *frame, FrameDataNode const *node)
+{
+ size_t const n = sizeOfNode(node);
+ if (n > 10) {
+ frame = set_4_byte_value(frame, node->fid);
+ frame = set_4_byte_value(frame, (unsigned long) (n - 10));
+ /* clear 2-byte header flags */
+ *frame++ = 0;
+ *frame++ = 0;
+ /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */
+ *frame++ = node->txt.enc == 1 ? 1 : 0;
+ if (node->dsc.dim > 0) {
+ if (node->dsc.enc != 1) {
+ frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim);
+ *frame++ = 0;
+ }
+ else {
+ frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim);
+ *frame++ = 0;
+ *frame++ = 0;
+ }
+ }
+ if (node->txt.enc != 1) {
+ frame = writeChars(frame, node->txt.ptr.l, node->txt.dim);
+ }
+ else {
+ frame = writeUcs2s(frame, node->txt.ptr.u, node->txt.dim);
+ }
+ }
+ return frame;
+}
+
+static unsigned char *
+set_frame_wxxx(unsigned char *frame, FrameDataNode const *node)
+{
+ size_t const n = sizeOfWxxxNode(node);
+ if (n > 10) {
+ frame = set_4_byte_value(frame, node->fid);
+ frame = set_4_byte_value(frame, (unsigned long) (n - 10));
+ /* clear 2-byte header flags */
+ *frame++ = 0;
+ *frame++ = 0;
+ if (node->dsc.dim > 0) {
+ /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */
+ *frame++ = node->dsc.enc == 1 ? 1 : 0;
+ if (node->dsc.enc != 1) {
+ frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim);
+ *frame++ = 0;
+ }
+ else {
+ frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim);
+ *frame++ = 0;
+ *frame++ = 0;
+ }
+ }
+ if (node->txt.enc != 1) {
+ frame = writeChars(frame, node->txt.ptr.l, node->txt.dim);
+ }
+ else {
+ frame = writeLoBytes(frame, node->txt.ptr.u, node->txt.dim);
+ }
+ }
+ return frame;
+}
+
+static unsigned char *
+set_frame_apic(unsigned char *frame, const char *mimetype, const unsigned char *data, size_t size)
+{
+ /* ID3v2.3 standard APIC frame:
+ *
+ * Text encoding $xx
+ * MIME type $00
+ * Picture type $xx
+ * Description $00 (00)
+ * Picture data
+ */
+ if (mimetype && data && size) {
+ frame = set_4_byte_value(frame, FRAME_ID('A', 'P', 'I', 'C'));
+ frame = set_4_byte_value(frame, (unsigned long) (4 + strlen(mimetype) + size));
+ /* clear 2-byte header flags */
+ *frame++ = 0;
+ *frame++ = 0;
+ /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */
+ *frame++ = 0;
+ /* copy mime_type */
+ while (*mimetype) {
+ *frame++ = *mimetype++;
+ }
+ *frame++ = 0;
+ /* set picture type to 0 */
+ *frame++ = 0;
+ /* empty description field */
+ *frame++ = 0;
+ /* copy the image data */
+ while (size--) {
+ *frame++ = *data++;
+ }
+ }
+ return frame;
+}
+
+int
+id3tag_set_fieldvalue(lame_t gfp, const char *fieldvalue)
+{
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ if (fieldvalue && *fieldvalue) {
+ if (strlen(fieldvalue) < 5 || fieldvalue[4] != '=') {
+ return -1;
+ }
+ return id3tag_set_textinfo_latin1(gfp, fieldvalue, &fieldvalue[5]);
+ }
+ return 0;
+}
+
+int
+id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue)
+{
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ if (fieldvalue && *fieldvalue) {
+ size_t dx = hasUcs2ByteOrderMarker(fieldvalue[0]);
+ unsigned short const separator = fromLatin1Char(fieldvalue, '=');
+ char fid[5] = {0,0,0,0,0};
+ uint32_t const frame_id = toID3v2TagId_ucs2(fieldvalue);
+ if (local_ucs2_strlen(fieldvalue) < (5+dx) || fieldvalue[4+dx] != separator) {
+ return -1;
+ }
+ fid[0] = (frame_id >> 24) & 0x0ff;
+ fid[1] = (frame_id >> 16) & 0x0ff;
+ fid[2] = (frame_id >> 8) & 0x0ff;
+ fid[3] = frame_id & 0x0ff;
+ if (frame_id != 0) {
+ unsigned short* txt = 0;
+ int rc;
+ local_ucs2_substr(&txt, fieldvalue, dx+5, local_ucs2_strlen(fieldvalue));
+ rc = id3tag_set_textinfo_utf16(gfp, fid, txt);
+ free(txt);
+ return rc;
+ }
+ }
+ return -1;
+}
+
+extern int
+id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue);
+
+int
+id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue)
+{
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ return id3tag_set_fieldvalue_utf16(gfp, fieldvalue);
+}
+
+size_t
+lame_get_id3v2_tag(lame_t gfp, unsigned char *buffer, size_t size)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ gfc = gfp->internal_flags;
+ if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) {
+ return 0;
+ }
+#if 0
+ debug_tag_spec_flags(gfc, "lame_get_id3v2_tag");
+#endif
+ {
+ int usev2 = test_tag_spec_flags(gfc, ADD_V2_FLAG | V2_ONLY_FLAG);
+ /* calculate length of four fields which may not fit in verion 1 tag */
+ size_t title_length = gfc->tag_spec.title ? strlen(gfc->tag_spec.title) : 0;
+ size_t artist_length = gfc->tag_spec.artist ? strlen(gfc->tag_spec.artist) : 0;
+ size_t album_length = gfc->tag_spec.album ? strlen(gfc->tag_spec.album) : 0;
+ size_t comment_length = gfc->tag_spec.comment ? strlen(gfc->tag_spec.comment) : 0;
+ /* write tag if explicitly requested or if fields overflow */
+ if ((title_length > 30)
+ || (artist_length > 30)
+ || (album_length > 30)
+ || (comment_length > 30)
+ || (gfc->tag_spec.track_id3v1 && (comment_length > 28))) {
+ usev2 = 1;
+ }
+ if (usev2) {
+ size_t tag_size;
+ unsigned char *p;
+ size_t adjusted_tag_size;
+ const char *albumart_mime = NULL;
+ static const char *mime_jpeg = "image/jpeg";
+ static const char *mime_png = "image/png";
+ static const char *mime_gif = "image/gif";
+
+ if (gfp->num_samples != MAX_U_32_NUM) {
+ id3v2AddAudioDuration(gfp, gfp->num_samples);
+ }
+
+ /* calulate size of tag starting with 10-byte tag header */
+ tag_size = 10;
+ if (gfc->tag_spec.albumart && gfc->tag_spec.albumart_size) {
+ switch (gfc->tag_spec.albumart_mimetype) {
+ case MIMETYPE_JPEG:
+ albumart_mime = mime_jpeg;
+ break;
+ case MIMETYPE_PNG:
+ albumart_mime = mime_png;
+ break;
+ case MIMETYPE_GIF:
+ albumart_mime = mime_gif;
+ break;
+ }
+ if (albumart_mime) {
+ tag_size += 10 + 4 + strlen(albumart_mime) + gfc->tag_spec.albumart_size;
+ }
+ }
+ {
+ id3tag_spec *tag = &gfc->tag_spec;
+ if (tag->v2_head != 0) {
+ FrameDataNode *node;
+ for (node = tag->v2_head; node != 0; node = node->nxt) {
+ if (node->fid == ID_COMMENT || node->fid == ID_USER) {
+ tag_size += sizeOfCommentNode(node);
+ }
+ else if (isFrameIdMatching(node->fid, FRAME_ID('W',0,0,0))) {
+ tag_size += sizeOfWxxxNode(node);
+ }
+ else {
+ tag_size += sizeOfNode(node);
+ }
+ }
+ }
+ }
+ if (test_tag_spec_flags(gfc, PAD_V2_FLAG)) {
+ /* add some bytes of padding */
+ tag_size += gfc->tag_spec.padding_size;
+ }
+ if (size < tag_size) {
+ return tag_size;
+ }
+ if (buffer == 0) {
+ return 0;
+ }
+ p = buffer;
+ /* set tag header starting with file identifier */
+ *p++ = 'I';
+ *p++ = 'D';
+ *p++ = '3';
+ /* set version number word */
+ *p++ = 3;
+ *p++ = 0;
+ /* clear flags byte */
+ *p++ = 0;
+ /* calculate and set tag size = total size - header size */
+ adjusted_tag_size = tag_size - 10;
+ /* encode adjusted size into four bytes where most significant
+ * bit is clear in each byte, for 28-bit total */
+ *p++ = (unsigned char) ((adjusted_tag_size >> 21) & 0x7fu);
+ *p++ = (unsigned char) ((adjusted_tag_size >> 14) & 0x7fu);
+ *p++ = (unsigned char) ((adjusted_tag_size >> 7) & 0x7fu);
+ *p++ = (unsigned char) (adjusted_tag_size & 0x7fu);
+
+ /*
+ * NOTE: The remainder of the tag (frames and padding, if any)
+ * are not "unsynchronized" to prevent false MPEG audio headers
+ * from appearing in the bitstream. Why? Well, most players
+ * and utilities know how to skip the ID3 version 2 tag by now
+ * even if they don't read its contents, and it's actually
+ * very unlikely that such a false "sync" pattern would occur
+ * in just the simple text frames added here.
+ */
+
+ /* set each frame in tag */
+ {
+ id3tag_spec *tag = &gfc->tag_spec;
+ if (tag->v2_head != 0) {
+ FrameDataNode *node;
+ for (node = tag->v2_head; node != 0; node = node->nxt) {
+ if (node->fid == ID_COMMENT || node->fid == ID_USER) {
+ p = set_frame_comment(p, node);
+ }
+ else if (isFrameIdMatching(node->fid,FRAME_ID('W',0,0,0))) {
+ p = set_frame_wxxx(p, node);
+ }
+ else {
+ p = set_frame_custom2(p, node);
+ }
+ }
+ }
+ }
+ if (albumart_mime) {
+ p = set_frame_apic(p, albumart_mime, gfc->tag_spec.albumart,
+ gfc->tag_spec.albumart_size);
+ }
+ /* clear any padding bytes */
+ memset(p, 0, tag_size - (p - buffer));
+ return tag_size;
+ }
+ }
+ return 0;
+}
+
+int
+id3tag_write_v2(lame_t gfp)
+{
+ lame_internal_flags *gfc = 0;
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ gfc = gfp->internal_flags;
+#if 0
+ debug_tag_spec_flags(gfc, "write v2");
+#endif
+ if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) {
+ return 0;
+ }
+ if (test_tag_spec_flags(gfc, CHANGED_FLAG)) {
+ unsigned char *tag = 0;
+ size_t tag_size, n;
+
+ n = lame_get_id3v2_tag(gfp, 0, 0);
+ tag = lame_calloc(unsigned char, n);
+ if (tag == 0) {
+ return -1;
+ }
+ tag_size = lame_get_id3v2_tag(gfp, tag, n);
+ if (tag_size > n) {
+ free(tag);
+ return -1;
+ }
+ else {
+ size_t i;
+ /* write tag directly into bitstream at current position */
+ for (i = 0; i < tag_size; ++i) {
+ add_dummy_byte(gfc, tag[i], 1);
+ }
+ }
+ free(tag);
+ return (int) tag_size; /* ok, tag should not exceed 2GB */
+ }
+ return 0;
+}
+
+static unsigned char *
+set_text_field(unsigned char *field, const char *text, size_t size, int pad)
+{
+ while (size--) {
+ if (text && *text) {
+ *field++ = *text++;
+ }
+ else {
+ *field++ = pad;
+ }
+ }
+ return field;
+}
+
+size_t
+lame_get_id3v1_tag(lame_t gfp, unsigned char *buffer, size_t size)
+{
+ size_t const tag_size = 128;
+ lame_internal_flags *gfc;
+
+ if (gfp == 0) {
+ return 0;
+ }
+ if (size < tag_size) {
+ return tag_size;
+ }
+ gfc = gfp->internal_flags;
+ if (gfc == 0) {
+ return 0;
+ }
+ if (buffer == 0) {
+ return 0;
+ }
+ if (test_tag_spec_flags(gfc, V2_ONLY_FLAG)) {
+ return 0;
+ }
+ if (test_tag_spec_flags(gfc, CHANGED_FLAG)) {
+ unsigned char *p = buffer;
+ int pad = test_tag_spec_flags(gfc, SPACE_V1_FLAG) ? ' ' : 0;
+ char year[5];
+
+ /* set tag identifier */
+ *p++ = 'T';
+ *p++ = 'A';
+ *p++ = 'G';
+ /* set each field in tag */
+ p = set_text_field(p, gfc->tag_spec.title, 30, pad);
+ p = set_text_field(p, gfc->tag_spec.artist, 30, pad);
+ p = set_text_field(p, gfc->tag_spec.album, 30, pad);
+ sprintf(year, "%d", gfc->tag_spec.year);
+ p = set_text_field(p, gfc->tag_spec.year ? year : NULL, 4, pad);
+ /* limit comment field to 28 bytes if a track is specified */
+ p = set_text_field(p, gfc->tag_spec.comment, gfc->tag_spec.track_id3v1 ? 28 : 30, pad);
+ if (gfc->tag_spec.track_id3v1) {
+ /* clear the next byte to indicate a version 1.1 tag */
+ *p++ = 0;
+ *p++ = gfc->tag_spec.track_id3v1;
+ }
+ *p++ = gfc->tag_spec.genre_id3v1;
+ return tag_size;
+ }
+ return 0;
+}
+
+int
+id3tag_write_v1(lame_t gfp)
+{
+ lame_internal_flags* gfc = 0;
+ size_t i, n, m;
+ unsigned char tag[128];
+
+ if (is_lame_internal_flags_null(gfp)) {
+ return 0;
+ }
+ gfc = gfp->internal_flags;
+
+ m = sizeof(tag);
+ n = lame_get_id3v1_tag(gfp, tag, m);
+ if (n > m) {
+ return 0;
+ }
+ /* write tag directly into bitstream at current position */
+ for (i = 0; i < n; ++i) {
+ add_dummy_byte(gfc, tag[i], 1);
+ }
+ return (int) n; /* ok, tag has fixed size of 128 bytes, well below 2GB */
+}
diff --git a/pkg/lame/clame/id3tag.h b/pkg/lame/clame/id3tag.h
new file mode 100644
index 0000000..9cd9ad9
--- /dev/null
+++ b/pkg/lame/clame/id3tag.h
@@ -0,0 +1,64 @@
+
+#ifndef LAME_ID3_H
+#define LAME_ID3_H
+
+
+#define CHANGED_FLAG (1U << 0)
+#define ADD_V2_FLAG (1U << 1)
+#define V1_ONLY_FLAG (1U << 2)
+#define V2_ONLY_FLAG (1U << 3)
+#define SPACE_V1_FLAG (1U << 4)
+#define PAD_V2_FLAG (1U << 5)
+
+enum {
+ MIMETYPE_NONE = 0,
+ MIMETYPE_JPEG,
+ MIMETYPE_PNG,
+ MIMETYPE_GIF
+};
+
+typedef struct FrameDataNode {
+ struct FrameDataNode *nxt;
+ uint32_t fid; /* Frame Identifier */
+ char lng[4]; /* 3-character language descriptor */
+ struct {
+ union {
+ char *l; /* ptr to Latin-1 chars */
+ unsigned short *u; /* ptr to UCS-2 text */
+ unsigned char *b; /* ptr to raw bytes */
+ } ptr;
+ size_t dim;
+ int enc; /* 0:Latin-1, 1:UCS-2, 2:RAW */
+ } dsc , txt;
+} FrameDataNode;
+
+
+typedef struct id3tag_spec {
+ /* private data members */
+ unsigned int flags;
+ int year;
+ char *title;
+ char *artist;
+ char *album;
+ char *comment;
+ int track_id3v1;
+ int genre_id3v1;
+ unsigned char *albumart;
+ unsigned int albumart_size;
+ unsigned int padding_size;
+ int albumart_mimetype;
+ char language[4]; /* the language of the frame's content, according to ISO-639-2 */
+ FrameDataNode *v2_head, *v2_tail;
+} id3tag_spec;
+
+
+/* write tag into stream at current position */
+extern int id3tag_write_v2(lame_global_flags * gfp);
+extern int id3tag_write_v1(lame_global_flags * gfp);
+/*
+ * NOTE: A version 2 tag will NOT be added unless one of the text fields won't
+ * fit in a version 1 tag (e.g. the title string is longer than 30 characters),
+ * or the "id3tag_add_v2" or "id3tag_v2_only" functions are used.
+ */
+
+#endif
diff --git a/pkg/lame/clame/l3side.h b/pkg/lame/clame/l3side.h
new file mode 100644
index 0000000..f65bbed
--- /dev/null
+++ b/pkg/lame/clame/l3side.h
@@ -0,0 +1,95 @@
+/*
+ * Layer 3 side include file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_L3SIDE_H
+#define LAME_L3SIDE_H
+
+/* max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8) */
+#define SFBMAX (SBMAX_s*3)
+
+/* Layer III side information. */
+typedef struct {
+ int l[1 + SBMAX_l];
+ int s[1 + SBMAX_s];
+ int psfb21[1 + PSFB21];
+ int psfb12[1 + PSFB12];
+} scalefac_struct;
+
+
+typedef struct {
+ FLOAT l[SBMAX_l];
+ FLOAT s[SBMAX_s][3];
+} III_psy_xmin;
+
+typedef struct {
+ III_psy_xmin thm;
+ III_psy_xmin en;
+} III_psy_ratio;
+
+typedef struct {
+ FLOAT xr[576];
+ int l3_enc[576];
+ int scalefac[SFBMAX];
+ FLOAT xrpow_max;
+
+ int part2_3_length;
+ int big_values;
+ int count1;
+ int global_gain;
+ int scalefac_compress;
+ int block_type;
+ int mixed_block_flag;
+ int table_select[3];
+ int subblock_gain[3 + 1];
+ int region0_count;
+ int region1_count;
+ int preflag;
+ int scalefac_scale;
+ int count1table_select;
+
+ int part2_length;
+ int sfb_lmax;
+ int sfb_smin;
+ int psy_lmax;
+ int sfbmax;
+ int psymax;
+ int sfbdivide;
+ int width[SFBMAX];
+ int window[SFBMAX];
+ int count1bits;
+ /* added for LSF */
+ const int *sfb_partition_table;
+ int slen[4];
+
+ int max_nonzero_coeff;
+ char energy_above_cutoff[SFBMAX];
+} gr_info;
+
+typedef struct {
+ gr_info tt[2][2];
+ int main_data_begin;
+ int private_bits;
+ int resvDrain_pre;
+ int resvDrain_post;
+ int scfsi[2][4];
+} III_side_info_t;
+
+#endif
diff --git a/pkg/lame/clame/lame-analysis.h b/pkg/lame/clame/lame-analysis.h
new file mode 100644
index 0000000..5055a60
--- /dev/null
+++ b/pkg/lame/clame/lame-analysis.h
@@ -0,0 +1,96 @@
+/*
+ * GTK plotting routines source file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_GTKANAL_H
+#define LAME_GTKANAL_H
+
+
+#define READ_AHEAD 40 /* number of frames to read ahead */
+#define MAXMPGLAG READ_AHEAD /* if the mpg123 lag becomes bigger than this
+ we have to stop */
+#define NUMBACK 6 /* number of frames we can back up */
+#define NUMPINFO (NUMBACK+READ_AHEAD+1)
+
+
+
+struct plotting_data {
+ int frameNum; /* current frame number */
+ int frameNum123;
+ int num_samples; /* number of pcm samples read for this frame */
+ double frametime; /* starting time of frame, in seconds */
+ double pcmdata[2][1600];
+ double pcmdata2[2][1152 + 1152 - DECDELAY];
+ double xr[2][2][576];
+ double mpg123xr[2][2][576];
+ double ms_ratio[2];
+ double ms_ener_ratio[2];
+
+ /* L,R, M and S values */
+ double energy_save[4][BLKSIZE]; /* psymodel is one ahead */
+ double energy[2][4][BLKSIZE];
+ double pe[2][4];
+ double thr[2][4][SBMAX_l];
+ double en[2][4][SBMAX_l];
+ double thr_s[2][4][3 * SBMAX_s];
+ double en_s[2][4][3 * SBMAX_s];
+ double ers_save[4]; /* psymodel is one ahead */
+ double ers[2][4];
+
+ double sfb[2][2][SBMAX_l];
+ double sfb_s[2][2][3 * SBMAX_s];
+ double LAMEsfb[2][2][SBMAX_l];
+ double LAMEsfb_s[2][2][3 * SBMAX_s];
+
+ int LAMEqss[2][2];
+ int qss[2][2];
+ int big_values[2][2];
+ int sub_gain[2][2][3];
+
+ double xfsf[2][2][SBMAX_l];
+ double xfsf_s[2][2][3 * SBMAX_s];
+
+ int over[2][2];
+ double tot_noise[2][2];
+ double max_noise[2][2];
+ double over_noise[2][2];
+ int over_SSD[2][2];
+ int blocktype[2][2];
+ int scalefac_scale[2][2];
+ int preflag[2][2];
+ int mpg123blocktype[2][2];
+ int mixed[2][2];
+ int mainbits[2][2];
+ int sfbits[2][2];
+ int LAMEmainbits[2][2];
+ int LAMEsfbits[2][2];
+ int framesize, stereo, js, ms_stereo, i_stereo, emph, bitrate, sampfreq, maindata;
+ int crc, padding;
+ int scfsi[2], mean_bits, resvsize;
+ int totbits;
+};
+#ifndef plotting_data_defined
+#define plotting_data_defined
+typedef struct plotting_data plotting_data;
+#endif
+#if 0
+extern plotting_data *pinfo;
+#endif
+#endif
diff --git a/pkg/lame/clame/lame.c b/pkg/lame/clame/lame.c
new file mode 100644
index 0000000..cb82225
--- /dev/null
+++ b/pkg/lame/clame/lame.c
@@ -0,0 +1,2665 @@
+/* -*- mode: C; mode: fold -*- */
+/*
+ * LAME MP3 encoding engine
+ *
+ * Copyright (c) 1999-2000 Mark Taylor
+ * Copyright (c) 2000-2005 Takehiro Tominaga
+ * Copyright (c) 2000-2017 Robert Hegemann
+ * Copyright (c) 2000-2005 Gabriel Bouvigne
+ * Copyright (c) 2000-2004 Alexander Leidinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: lame.c,v 1.377 2017/09/26 12:14:02 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+
+#include "encoder.h"
+#include "util.h"
+#include "lame_global_flags.h"
+#include "gain_analysis.h"
+#include "bitstream.h"
+#include "quantize_pvt.h"
+#include "set_get.h"
+#include "quantize.h"
+#include "psymodel.h"
+#include "version.h"
+#include "VbrTag.h"
+#include "tables.h"
+
+
+#if defined(__FreeBSD__) && !defined(__alpha__)
+#include
+#endif
+#ifdef __riscos__
+#include "asmstuff.h"
+#endif
+
+#ifdef __sun__
+/* woraround for SunOS 4.x, it has SEEK_* defined here */
+#include
+#endif
+
+
+#define LAME_DEFAULT_QUALITY 3
+
+
+
+int
+is_lame_global_flags_valid(const lame_global_flags * gfp)
+{
+ if (gfp == NULL)
+ return 0;
+ if (gfp->class_id != LAME_ID)
+ return 0;
+ return 1;
+}
+
+
+int
+is_lame_internal_flags_valid(const lame_internal_flags * gfc)
+{
+ if (gfc == NULL)
+ return 0;
+ if (gfc->class_id != LAME_ID)
+ return 0;
+ if (gfc->lame_init_params_successful <=0)
+ return 0;
+ return 1;
+}
+
+
+
+static FLOAT
+filter_coef(FLOAT x)
+{
+ if (x > 1.0)
+ return 0.0;
+ if (x <= 0.0)
+ return 1.0;
+
+ return cos(PI / 2 * x);
+}
+
+static void
+lame_init_params_ppflt(lame_internal_flags * gfc)
+{
+ SessionConfig_t *const cfg = &gfc->cfg;
+
+ /***************************************************************/
+ /* compute info needed for polyphase filter (filter type==0, default) */
+ /***************************************************************/
+
+ int band, maxband, minband;
+ FLOAT freq;
+ int lowpass_band = 32;
+ int highpass_band = -1;
+
+ if (cfg->lowpass1 > 0) {
+ minband = 999;
+ for (band = 0; band <= 31; band++) {
+ freq = band / 31.0;
+ /* this band and above will be zeroed: */
+ if (freq >= cfg->lowpass2) {
+ lowpass_band = Min(lowpass_band, band);
+ }
+ if (cfg->lowpass1 < freq && freq < cfg->lowpass2) {
+ minband = Min(minband, band);
+ }
+ }
+
+ /* compute the *actual* transition band implemented by
+ * the polyphase filter */
+ if (minband == 999) {
+ cfg->lowpass1 = (lowpass_band - .75) / 31.0;
+ }
+ else {
+ cfg->lowpass1 = (minband - .75) / 31.0;
+ }
+ cfg->lowpass2 = lowpass_band / 31.0;
+ }
+
+ /* make sure highpass filter is within 90% of what the effective
+ * highpass frequency will be */
+ if (cfg->highpass2 > 0) {
+ if (cfg->highpass2 < .9 * (.75 / 31.0)) {
+ cfg->highpass1 = 0;
+ cfg->highpass2 = 0;
+ MSGF(gfc, "Warning: highpass filter disabled. " "highpass frequency too small\n");
+ }
+ }
+
+ if (cfg->highpass2 > 0) {
+ maxband = -1;
+ for (band = 0; band <= 31; band++) {
+ freq = band / 31.0;
+ /* this band and below will be zereod */
+ if (freq <= cfg->highpass1) {
+ highpass_band = Max(highpass_band, band);
+ }
+ if (cfg->highpass1 < freq && freq < cfg->highpass2) {
+ maxband = Max(maxband, band);
+ }
+ }
+ /* compute the *actual* transition band implemented by
+ * the polyphase filter */
+ cfg->highpass1 = highpass_band / 31.0;
+ if (maxband == -1) {
+ cfg->highpass2 = (highpass_band + .75) / 31.0;
+ }
+ else {
+ cfg->highpass2 = (maxband + .75) / 31.0;
+ }
+ }
+
+ for (band = 0; band < 32; band++) {
+ FLOAT fc1, fc2;
+ freq = band / 31.0f;
+ if (cfg->highpass2 > cfg->highpass1) {
+ fc1 = filter_coef((cfg->highpass2 - freq) / (cfg->highpass2 - cfg->highpass1 + 1e-20));
+ }
+ else {
+ fc1 = 1.0f;
+ }
+ if (cfg->lowpass2 > cfg->lowpass1) {
+ fc2 = filter_coef((freq - cfg->lowpass1) / (cfg->lowpass2 - cfg->lowpass1 + 1e-20));
+ }
+ else {
+ fc2 = 1.0f;
+ }
+ gfc->sv_enc.amp_filter[band] = fc1 * fc2;
+ }
+}
+
+
+static void
+optimum_bandwidth(double *const lowerlimit, double *const upperlimit, const unsigned bitrate)
+{
+/*
+ * Input:
+ * bitrate total bitrate in kbps
+ *
+ * Output:
+ * lowerlimit: best lowpass frequency limit for input filter in Hz
+ * upperlimit: best highpass frequency limit for input filter in Hz
+ */
+ int table_index;
+
+ typedef struct {
+ int bitrate; /* only indicative value */
+ int lowpass;
+ } band_pass_t;
+
+ const band_pass_t freq_map[] = {
+ {8, 2000},
+ {16, 3700},
+ {24, 3900},
+ {32, 5500},
+ {40, 7000},
+ {48, 7500},
+ {56, 10000},
+ {64, 11000},
+ {80, 13500},
+ {96, 15100},
+ {112, 15600},
+ {128, 17000},
+ {160, 17500},
+ {192, 18600},
+ {224, 19400},
+ {256, 19700},
+ {320, 20500}
+ };
+
+
+ table_index = nearestBitrateFullIndex(bitrate);
+
+ (void) freq_map[table_index].bitrate;
+ *lowerlimit = freq_map[table_index].lowpass;
+
+
+/*
+ * Now we try to choose a good high pass filtering frequency.
+ * This value is currently not used.
+ * For fu < 16 kHz: sqrt(fu*fl) = 560 Hz
+ * For fu = 18 kHz: no high pass filtering
+ * This gives:
+ *
+ * 2 kHz => 160 Hz
+ * 3 kHz => 107 Hz
+ * 4 kHz => 80 Hz
+ * 8 kHz => 40 Hz
+ * 16 kHz => 20 Hz
+ * 17 kHz => 10 Hz
+ * 18 kHz => 0 Hz
+ *
+ * These are ad hoc values and these can be optimized if a high pass is available.
+ */
+/* if (f_low <= 16000)
+ f_high = 16000. * 20. / f_low;
+ else if (f_low <= 18000)
+ f_high = 180. - 0.01 * f_low;
+ else
+ f_high = 0.;*/
+
+ /*
+ * When we sometimes have a good highpass filter, we can add the highpass
+ * frequency to the lowpass frequency
+ */
+
+ /*if (upperlimit != NULL)
+ *upperlimit = f_high;*/
+ (void) upperlimit;
+}
+
+
+static int
+optimum_samplefreq(int lowpassfreq, int input_samplefreq)
+{
+/*
+ * Rules:
+ * - if possible, sfb21 should NOT be used
+ *
+ */
+ int suggested_samplefreq = 44100;
+
+ if (input_samplefreq >= 48000)
+ suggested_samplefreq = 48000;
+ else if (input_samplefreq >= 44100)
+ suggested_samplefreq = 44100;
+ else if (input_samplefreq >= 32000)
+ suggested_samplefreq = 32000;
+ else if (input_samplefreq >= 24000)
+ suggested_samplefreq = 24000;
+ else if (input_samplefreq >= 22050)
+ suggested_samplefreq = 22050;
+ else if (input_samplefreq >= 16000)
+ suggested_samplefreq = 16000;
+ else if (input_samplefreq >= 12000)
+ suggested_samplefreq = 12000;
+ else if (input_samplefreq >= 11025)
+ suggested_samplefreq = 11025;
+ else if (input_samplefreq >= 8000)
+ suggested_samplefreq = 8000;
+
+ if (lowpassfreq == -1)
+ return suggested_samplefreq;
+
+ if (lowpassfreq <= 15960)
+ suggested_samplefreq = 44100;
+ if (lowpassfreq <= 15250)
+ suggested_samplefreq = 32000;
+ if (lowpassfreq <= 11220)
+ suggested_samplefreq = 24000;
+ if (lowpassfreq <= 9970)
+ suggested_samplefreq = 22050;
+ if (lowpassfreq <= 7230)
+ suggested_samplefreq = 16000;
+ if (lowpassfreq <= 5420)
+ suggested_samplefreq = 12000;
+ if (lowpassfreq <= 4510)
+ suggested_samplefreq = 11025;
+ if (lowpassfreq <= 3970)
+ suggested_samplefreq = 8000;
+
+ if (input_samplefreq < suggested_samplefreq) {
+ /* choose a valid MPEG sample frequency above the input sample frequency
+ to avoid SFB21/12 bitrate bloat
+ rh 061115
+ */
+ if (input_samplefreq > 44100) {
+ return 48000;
+ }
+ if (input_samplefreq > 32000) {
+ return 44100;
+ }
+ if (input_samplefreq > 24000) {
+ return 32000;
+ }
+ if (input_samplefreq > 22050) {
+ return 24000;
+ }
+ if (input_samplefreq > 16000) {
+ return 22050;
+ }
+ if (input_samplefreq > 12000) {
+ return 16000;
+ }
+ if (input_samplefreq > 11025) {
+ return 12000;
+ }
+ if (input_samplefreq > 8000) {
+ return 11025;
+ }
+ return 8000;
+ }
+ return suggested_samplefreq;
+}
+
+
+
+
+
+/* set internal feature flags. USER should not access these since
+ * some combinations will produce strange results */
+static void
+lame_init_qval(lame_global_flags * gfp)
+{
+ lame_internal_flags *const gfc = gfp->internal_flags;
+ SessionConfig_t *const cfg = &gfc->cfg;
+
+ switch (gfp->quality) {
+ default:
+ case 9: /* no psymodel, no noise shaping */
+ cfg->noise_shaping = 0;
+ cfg->noise_shaping_amp = 0;
+ cfg->noise_shaping_stop = 0;
+ cfg->use_best_huffman = 0;
+ cfg->full_outer_loop = 0;
+ break;
+
+ case 8:
+ gfp->quality = 7;
+ /*lint --fallthrough */
+ case 7: /* use psymodel (for short block and m/s switching), but no noise shapping */
+ cfg->noise_shaping = 0;
+ cfg->noise_shaping_amp = 0;
+ cfg->noise_shaping_stop = 0;
+ cfg->use_best_huffman = 0;
+ cfg->full_outer_loop = 0;
+ if (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) {
+ cfg->full_outer_loop = -1;
+ }
+ break;
+
+ case 6:
+ if (cfg->noise_shaping == 0)
+ cfg->noise_shaping = 1;
+ cfg->noise_shaping_amp = 0;
+ cfg->noise_shaping_stop = 0;
+ if (cfg->subblock_gain == -1)
+ cfg->subblock_gain = 1;
+ cfg->use_best_huffman = 0;
+ cfg->full_outer_loop = 0;
+ break;
+
+ case 5:
+ if (cfg->noise_shaping == 0)
+ cfg->noise_shaping = 1;
+ cfg->noise_shaping_amp = 0;
+ cfg->noise_shaping_stop = 0;
+ if (cfg->subblock_gain == -1)
+ cfg->subblock_gain = 1;
+ cfg->use_best_huffman = 0;
+ cfg->full_outer_loop = 0;
+ break;
+
+ case 4:
+ if (cfg->noise_shaping == 0)
+ cfg->noise_shaping = 1;
+ cfg->noise_shaping_amp = 0;
+ cfg->noise_shaping_stop = 0;
+ if (cfg->subblock_gain == -1)
+ cfg->subblock_gain = 1;
+ cfg->use_best_huffman = 1;
+ cfg->full_outer_loop = 0;
+ break;
+
+ case 3:
+ if (cfg->noise_shaping == 0)
+ cfg->noise_shaping = 1;
+ cfg->noise_shaping_amp = 1;
+ cfg->noise_shaping_stop = 1;
+ if (cfg->subblock_gain == -1)
+ cfg->subblock_gain = 1;
+ cfg->use_best_huffman = 1;
+ cfg->full_outer_loop = 0;
+ break;
+
+ case 2:
+ if (cfg->noise_shaping == 0)
+ cfg->noise_shaping = 1;
+ if (gfc->sv_qnt.substep_shaping == 0)
+ gfc->sv_qnt.substep_shaping = 2;
+ cfg->noise_shaping_amp = 1;
+ cfg->noise_shaping_stop = 1;
+ if (cfg->subblock_gain == -1)
+ cfg->subblock_gain = 1;
+ cfg->use_best_huffman = 1; /* inner loop */
+ cfg->full_outer_loop = 0;
+ break;
+
+ case 1:
+ if (cfg->noise_shaping == 0)
+ cfg->noise_shaping = 1;
+ if (gfc->sv_qnt.substep_shaping == 0)
+ gfc->sv_qnt.substep_shaping = 2;
+ cfg->noise_shaping_amp = 2;
+ cfg->noise_shaping_stop = 1;
+ if (cfg->subblock_gain == -1)
+ cfg->subblock_gain = 1;
+ cfg->use_best_huffman = 1;
+ cfg->full_outer_loop = 0;
+ break;
+
+ case 0:
+ if (cfg->noise_shaping == 0)
+ cfg->noise_shaping = 1;
+ if (gfc->sv_qnt.substep_shaping == 0)
+ gfc->sv_qnt.substep_shaping = 2;
+ cfg->noise_shaping_amp = 2;
+ cfg->noise_shaping_stop = 1;
+ if (cfg->subblock_gain == -1)
+ cfg->subblock_gain = 1;
+ cfg->use_best_huffman = 1; /*type 2 disabled because of it slowness,
+ in favor of full outer loop search */
+ cfg->full_outer_loop = 1;
+ break;
+ }
+
+}
+
+
+
+static double
+linear_int(double a, double b, double m)
+{
+ return a + m * (b - a);
+}
+
+
+
+/********************************************************************
+ * initialize internal params based on data in gf
+ * (globalflags struct filled in by calling program)
+ *
+ * OUTLINE:
+ *
+ * We first have some complex code to determine bitrate,
+ * output samplerate and mode. It is complicated by the fact
+ * that we allow the user to set some or all of these parameters,
+ * and need to determine best possible values for the rest of them:
+ *
+ * 1. set some CPU related flags
+ * 2. check if we are mono->mono, stereo->mono or stereo->stereo
+ * 3. compute bitrate and output samplerate:
+ * user may have set compression ratio
+ * user may have set a bitrate
+ * user may have set a output samplerate
+ * 4. set some options which depend on output samplerate
+ * 5. compute the actual compression ratio
+ * 6. set mode based on compression ratio
+ *
+ * The remaining code is much simpler - it just sets options
+ * based on the mode & compression ratio:
+ *
+ * set allow_diff_short based on mode
+ * select lowpass filter based on compression ratio & mode
+ * set the bitrate index, and min/max bitrates for VBR modes
+ * disable VBR tag if it is not appropriate
+ * initialize the bitstream
+ * initialize scalefac_band data
+ * set sideinfo_len (based on channels, CRC, out_samplerate)
+ * write an id3v2 tag into the bitstream
+ * write VBR tag into the bitstream
+ * set mpeg1/2 flag
+ * estimate the number of frames (based on a lot of data)
+ *
+ * now we set more flags:
+ * nspsytune:
+ * see code
+ * VBR modes
+ * see code
+ * CBR/ABR
+ * see code
+ *
+ * Finally, we set the algorithm flags based on the gfp->quality value
+ * lame_init_qval(gfp);
+ *
+ ********************************************************************/
+int
+lame_init_params(lame_global_flags * gfp)
+{
+
+ int i;
+ int j;
+ lame_internal_flags *gfc;
+ SessionConfig_t *cfg;
+
+ if (!is_lame_global_flags_valid(gfp))
+ return -1;
+
+ gfc = gfp->internal_flags;
+ if (gfc == 0)
+ return -1;
+
+ if (is_lame_internal_flags_valid(gfc))
+ return -1; /* already initialized */
+
+ /* start updating lame internal flags */
+ gfc->class_id = LAME_ID;
+ gfc->lame_init_params_successful = 0; /* will be set to one, when we get through until the end */
+
+ if (gfp->samplerate_in < 1)
+ return -1; /* input sample rate makes no sense */
+ if (gfp->num_channels < 1 || 2 < gfp->num_channels)
+ return -1; /* number of input channels makes no sense */
+ if (gfp->samplerate_out != 0) {
+ int v=0;
+ if (SmpFrqIndex(gfp->samplerate_out, &v) < 0)
+ return -1; /* output sample rate makes no sense */
+ }
+
+ cfg = &gfc->cfg;
+
+ cfg->enforce_min_bitrate = gfp->VBR_hard_min;
+ cfg->analysis = gfp->analysis;
+ if (cfg->analysis)
+ gfp->write_lame_tag = 0;
+
+ /* some file options not allowed if output is: not specified or stdout */
+ if (gfc->pinfo != NULL)
+ gfp->write_lame_tag = 0; /* disable Xing VBR tag */
+
+ /* report functions */
+ gfc->report_msg = gfp->report.msgf;
+ gfc->report_dbg = gfp->report.debugf;
+ gfc->report_err = gfp->report.errorf;
+
+ if (gfp->asm_optimizations.amd3dnow)
+ gfc->CPU_features.AMD_3DNow = has_3DNow();
+ else
+ gfc->CPU_features.AMD_3DNow = 0;
+
+ if (gfp->asm_optimizations.mmx)
+ gfc->CPU_features.MMX = has_MMX();
+ else
+ gfc->CPU_features.MMX = 0;
+
+ if (gfp->asm_optimizations.sse) {
+ gfc->CPU_features.SSE = has_SSE();
+ gfc->CPU_features.SSE2 = has_SSE2();
+ }
+ else {
+ gfc->CPU_features.SSE = 0;
+ gfc->CPU_features.SSE2 = 0;
+ }
+
+
+ cfg->vbr = gfp->VBR;
+ cfg->error_protection = gfp->error_protection;
+ cfg->copyright = gfp->copyright;
+ cfg->original = gfp->original;
+ cfg->extension = gfp->extension;
+ cfg->emphasis = gfp->emphasis;
+
+ cfg->channels_in = gfp->num_channels;
+ if (cfg->channels_in == 1)
+ gfp->mode = MONO;
+ cfg->channels_out = (gfp->mode == MONO) ? 1 : 2;
+ if (gfp->mode != JOINT_STEREO)
+ gfp->force_ms = 0; /* forced mid/side stereo for j-stereo only */
+ cfg->force_ms = gfp->force_ms;
+
+ if (cfg->vbr == vbr_off && gfp->VBR_mean_bitrate_kbps != 128 && gfp->brate == 0)
+ gfp->brate = gfp->VBR_mean_bitrate_kbps;
+
+ switch (cfg->vbr) {
+ case vbr_off:
+ case vbr_mtrh:
+ case vbr_mt:
+ /* these modes can handle free format condition */
+ break;
+ default:
+ gfp->free_format = 0; /* mode can't be mixed with free format */
+ break;
+ }
+
+ cfg->free_format = gfp->free_format;
+
+ if (cfg->vbr == vbr_off && gfp->brate == 0) {
+ /* no bitrate or compression ratio specified, use 11.025 */
+ if (EQ(gfp->compression_ratio, 0))
+ gfp->compression_ratio = 11.025; /* rate to compress a CD down to exactly 128000 bps */
+ }
+
+ /* find bitrate if user specify a compression ratio */
+ if (cfg->vbr == vbr_off && gfp->compression_ratio > 0) {
+
+ if (gfp->samplerate_out == 0)
+ gfp->samplerate_out = map2MP3Frequency((int) (0.97 * gfp->samplerate_in)); /* round up with a margin of 3% */
+
+ /* choose a bitrate for the output samplerate which achieves
+ * specified compression ratio
+ */
+ gfp->brate = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->compression_ratio);
+
+ /* we need the version for the bitrate table look up */
+ cfg->samplerate_index = SmpFrqIndex(gfp->samplerate_out, &cfg->version);
+ assert(cfg->samplerate_index >=0);
+
+ if (!cfg->free_format) /* for non Free Format find the nearest allowed bitrate */
+ gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, gfp->samplerate_out);
+ }
+ if (gfp->samplerate_out) {
+ if (gfp->samplerate_out < 16000) {
+ gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8);
+ gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 64);
+ }
+ else if (gfp->samplerate_out < 32000) {
+ gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8);
+ gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 160);
+ }
+ else {
+ gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 32);
+ gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 320);
+ }
+ }
+ /* WORK IN PROGRESS */
+ /* mapping VBR scale to internal VBR quality settings */
+ if (gfp->samplerate_out == 0 && (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh)) {
+ float const qval = gfp->VBR_q + gfp->VBR_q_frac;
+ struct q_map { int sr_a; float qa, qb, ta, tb; int lp; };
+ struct q_map const m[9]
+ = { {48000, 0.0,6.5, 0.0,6.5, 23700}
+ , {44100, 0.0,6.5, 0.0,6.5, 21780}
+ , {32000, 6.5,8.0, 5.2,6.5, 15800}
+ , {24000, 8.0,8.5, 5.2,6.0, 11850}
+ , {22050, 8.5,9.01, 5.2,6.5, 10892}
+ , {16000, 9.01,9.4, 4.9,6.5, 7903}
+ , {12000, 9.4,9.6, 4.5,6.0, 5928}
+ , {11025, 9.6,9.9, 5.1,6.5, 5446}
+ , { 8000, 9.9,10., 4.9,6.5, 3952}
+ };
+ for (i = 2; i < 9; ++i) {
+ if (gfp->samplerate_in == m[i].sr_a) {
+ if (qval < m[i].qa) {
+ double d = qval / m[i].qa;
+ d = d * m[i].ta;
+ gfp->VBR_q = (int)d;
+ gfp->VBR_q_frac = d - gfp->VBR_q;
+ }
+ }
+ if (gfp->samplerate_in >= m[i].sr_a) {
+ if (m[i].qa <= qval && qval < m[i].qb) {
+ float const q_ = m[i].qb-m[i].qa;
+ float const t_ = m[i].tb-m[i].ta;
+ double d = m[i].ta + t_ * (qval-m[i].qa) / q_;
+ gfp->VBR_q = (int)d;
+ gfp->VBR_q_frac = d - gfp->VBR_q;
+ gfp->samplerate_out = m[i].sr_a;
+ if (gfp->lowpassfreq == 0) {
+ gfp->lowpassfreq = -1;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /****************************************************************/
+ /* if a filter has not been enabled, see if we should add one: */
+ /****************************************************************/
+ if (gfp->lowpassfreq == 0) {
+ double lowpass = 16000;
+ double highpass;
+
+ switch (cfg->vbr) {
+ case vbr_off:{
+ optimum_bandwidth(&lowpass, &highpass, gfp->brate);
+ break;
+ }
+ case vbr_abr:{
+ optimum_bandwidth(&lowpass, &highpass, gfp->VBR_mean_bitrate_kbps);
+ break;
+ }
+ case vbr_rh:{
+ int const x[11] = {
+ 19500, 19000, 18600, 18000, 17500, 16000, 15600, 14900, 12500, 10000, 3950
+ };
+ if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {
+ double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;
+ lowpass = linear_int(a, b, m);
+ }
+ else {
+ lowpass = 19500;
+ }
+ break;
+ }
+ case vbr_mtrh:
+ case vbr_mt:{
+ int const x[11] = {
+ 24000, 19500, 18500, 18000, 17500, 17000, 16500, 15600, 15200, 7230, 3950
+ };
+ if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {
+ double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;
+ lowpass = linear_int(a, b, m);
+ }
+ else {
+ lowpass = 21500;
+ }
+ break;
+ }
+ default:{
+ int const x[11] = {
+ 19500, 19000, 18500, 18000, 17500, 16500, 15500, 14500, 12500, 9500, 3950
+ };
+ if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {
+ double a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;
+ lowpass = linear_int(a, b, m);
+ }
+ else {
+ lowpass = 19500;
+ }
+ }
+ }
+
+ if (gfp->mode == MONO && (cfg->vbr == vbr_off || cfg->vbr == vbr_abr))
+ lowpass *= 1.5;
+
+ gfp->lowpassfreq = lowpass;
+ }
+
+ if (gfp->samplerate_out == 0) {
+ if (2 * gfp->lowpassfreq > gfp->samplerate_in) {
+ gfp->lowpassfreq = gfp->samplerate_in / 2;
+ }
+ gfp->samplerate_out = optimum_samplefreq((int) gfp->lowpassfreq, gfp->samplerate_in);
+ }
+ if (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) {
+ gfp->lowpassfreq = Min(24000, gfp->lowpassfreq);
+ }
+ else {
+ gfp->lowpassfreq = Min(20500, gfp->lowpassfreq);
+ }
+ gfp->lowpassfreq = Min(gfp->samplerate_out / 2, gfp->lowpassfreq);
+
+ if (cfg->vbr == vbr_off) {
+ gfp->compression_ratio = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate);
+ }
+ if (cfg->vbr == vbr_abr) {
+ gfp->compression_ratio =
+ gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps);
+ }
+
+ cfg->disable_reservoir = gfp->disable_reservoir;
+ cfg->lowpassfreq = gfp->lowpassfreq;
+ cfg->highpassfreq = gfp->highpassfreq;
+ cfg->samplerate_in = gfp->samplerate_in;
+ cfg->samplerate_out = gfp->samplerate_out;
+ cfg->mode_gr = cfg->samplerate_out <= 24000 ? 1 : 2; /* Number of granules per frame */
+
+
+ /*
+ * sample freq bitrate compression ratio
+ * [kHz] [kbps/channel] for 16 bit input
+ * 44.1 56 12.6
+ * 44.1 64 11.025
+ * 44.1 80 8.82
+ * 22.05 24 14.7
+ * 22.05 32 11.025
+ * 22.05 40 8.82
+ * 16 16 16.0
+ * 16 24 10.667
+ *
+ */
+ /*
+ * For VBR, take a guess at the compression_ratio.
+ * For example:
+ *
+ * VBR_q compression like
+ * - 4.4 320 kbps/44 kHz
+ * 0...1 5.5 256 kbps/44 kHz
+ * 2 7.3 192 kbps/44 kHz
+ * 4 8.8 160 kbps/44 kHz
+ * 6 11 128 kbps/44 kHz
+ * 9 14.7 96 kbps
+ *
+ * for lower bitrates, downsample with --resample
+ */
+
+ switch (cfg->vbr) {
+ case vbr_mt:
+ case vbr_rh:
+ case vbr_mtrh:
+ {
+ /*numbers are a bit strange, but they determine the lowpass value */
+ FLOAT const cmp[] = { 5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14, 15, 16.5 };
+ gfp->compression_ratio = cmp[gfp->VBR_q];
+ }
+ break;
+ case vbr_abr:
+ gfp->compression_ratio =
+ cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps);
+ break;
+ default:
+ gfp->compression_ratio = cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate);
+ break;
+ }
+
+
+ /* mode = -1 (not set by user) or
+ * mode = MONO (because of only 1 input channel).
+ * If mode has not been set, then select J-STEREO
+ */
+ if (gfp->mode == NOT_SET) {
+ gfp->mode = JOINT_STEREO;
+ }
+
+ cfg->mode = gfp->mode;
+
+
+ /* apply user driven high pass filter */
+ if (cfg->highpassfreq > 0) {
+ cfg->highpass1 = 2. * cfg->highpassfreq;
+
+ if (gfp->highpasswidth >= 0)
+ cfg->highpass2 = 2. * (cfg->highpassfreq + gfp->highpasswidth);
+ else /* 0% above on default */
+ cfg->highpass2 = (1 + 0.00) * 2. * cfg->highpassfreq;
+
+ cfg->highpass1 /= cfg->samplerate_out;
+ cfg->highpass2 /= cfg->samplerate_out;
+ }
+ else {
+ cfg->highpass1 = 0;
+ cfg->highpass2 = 0;
+ }
+ /* apply user driven low pass filter */
+ cfg->lowpass1 = 0;
+ cfg->lowpass2 = 0;
+ if (cfg->lowpassfreq > 0 && cfg->lowpassfreq < (cfg->samplerate_out / 2) ) {
+ cfg->lowpass2 = 2. * cfg->lowpassfreq;
+ if (gfp->lowpasswidth >= 0) {
+ cfg->lowpass1 = 2. * (cfg->lowpassfreq - gfp->lowpasswidth);
+ if (cfg->lowpass1 < 0) /* has to be >= 0 */
+ cfg->lowpass1 = 0;
+ }
+ else { /* 0% below on default */
+ cfg->lowpass1 = (1 - 0.00) * 2. * cfg->lowpassfreq;
+ }
+ cfg->lowpass1 /= cfg->samplerate_out;
+ cfg->lowpass2 /= cfg->samplerate_out;
+ }
+
+
+
+
+ /**********************************************************************/
+ /* compute info needed for polyphase filter (filter type==0, default) */
+ /**********************************************************************/
+ lame_init_params_ppflt(gfc);
+
+
+ /*******************************************************
+ * samplerate and bitrate index
+ *******************************************************/
+ cfg->samplerate_index = SmpFrqIndex(cfg->samplerate_out, &cfg->version);
+ assert(cfg->samplerate_index >= 0);
+
+ if (cfg->vbr == vbr_off) {
+ if (cfg->free_format) {
+ gfc->ov_enc.bitrate_index = 0;
+ }
+ else {
+ gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, cfg->samplerate_out);
+ gfc->ov_enc.bitrate_index = BitrateIndex(gfp->brate, cfg->version, cfg->samplerate_out);
+ if (gfc->ov_enc.bitrate_index <= 0) {
+ /* This never happens, because of preceding FindNearestBitrate!
+ * But, set a sane value, just in case
+ */
+ assert(0);
+ gfc->ov_enc.bitrate_index = 8;
+ }
+ }
+ }
+ else {
+ gfc->ov_enc.bitrate_index = 1;
+ }
+
+ init_bit_stream_w(gfc);
+
+ j = cfg->samplerate_index + (3 * cfg->version) + 6 * (cfg->samplerate_out < 16000);
+ for (i = 0; i < SBMAX_l + 1; i++)
+ gfc->scalefac_band.l[i] = sfBandIndex[j].l[i];
+
+ for (i = 0; i < PSFB21 + 1; i++) {
+ int const size = (gfc->scalefac_band.l[22] - gfc->scalefac_band.l[21]) / PSFB21;
+ int const start = gfc->scalefac_band.l[21] + i * size;
+ gfc->scalefac_band.psfb21[i] = start;
+ }
+ gfc->scalefac_band.psfb21[PSFB21] = 576;
+
+ for (i = 0; i < SBMAX_s + 1; i++)
+ gfc->scalefac_band.s[i] = sfBandIndex[j].s[i];
+
+ for (i = 0; i < PSFB12 + 1; i++) {
+ int const size = (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]) / PSFB12;
+ int const start = gfc->scalefac_band.s[12] + i * size;
+ gfc->scalefac_band.psfb12[i] = start;
+ }
+ gfc->scalefac_band.psfb12[PSFB12] = 192;
+
+ /* determine the mean bitrate for main data */
+ if (cfg->mode_gr == 2) /* MPEG 1 */
+ cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 17 : 4 + 32;
+ else /* MPEG 2 */
+ cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 9 : 4 + 17;
+
+ if (cfg->error_protection)
+ cfg->sideinfo_len += 2;
+
+ {
+ int k;
+
+ for (k = 0; k < 19; k++)
+ gfc->sv_enc.pefirbuf[k] = 700 * cfg->mode_gr * cfg->channels_out;
+
+ if (gfp->ATHtype == -1)
+ gfp->ATHtype = 4;
+ }
+
+ assert(gfp->VBR_q <= 9);
+ assert(gfp->VBR_q >= 0);
+
+ switch (cfg->vbr) {
+
+ case vbr_mt:
+ case vbr_mtrh:{
+ if (gfp->strict_ISO < 0) {
+ gfp->strict_ISO = MDB_MAXIMUM;
+ }
+ if (gfp->useTemporal < 0) {
+ gfp->useTemporal = 0; /* off by default for this VBR mode */
+ }
+
+ (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0);
+ /* The newer VBR code supports only a limited
+ subset of quality levels:
+ 9-5=5 are the same, uses x^3/4 quantization
+ 4-0=0 are the same 5 plus best huffman divide code
+ */
+ if (gfp->quality < 0)
+ gfp->quality = LAME_DEFAULT_QUALITY;
+ if (gfp->quality < 5)
+ gfp->quality = 0;
+ if (gfp->quality > 7)
+ gfp->quality = 7;
+
+ /* sfb21 extra only with MPEG-1 at higher sampling rates
+ */
+ if (gfp->experimentalY)
+ gfc->sv_qnt.sfb21_extra = 0;
+ else
+ gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000);
+
+ break;
+
+ }
+ case vbr_rh:{
+
+ (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0);
+
+ /* sfb21 extra only with MPEG-1 at higher sampling rates
+ */
+ if (gfp->experimentalY)
+ gfc->sv_qnt.sfb21_extra = 0;
+ else
+ gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000);
+
+ /* VBR needs at least the output of GPSYCHO,
+ * so we have to garantee that by setting a minimum
+ * quality level, actually level 6 does it.
+ * down to level 6
+ */
+ if (gfp->quality > 6)
+ gfp->quality = 6;
+
+
+ if (gfp->quality < 0)
+ gfp->quality = LAME_DEFAULT_QUALITY;
+
+ break;
+ }
+
+ default: /* cbr/abr */ {
+
+ /* no sfb21 extra with CBR code
+ */
+ gfc->sv_qnt.sfb21_extra = 0;
+
+ if (gfp->quality < 0)
+ gfp->quality = LAME_DEFAULT_QUALITY;
+
+
+ if (cfg->vbr == vbr_off)
+ (void) lame_set_VBR_mean_bitrate_kbps(gfp, gfp->brate);
+ /* second, set parameters depending on bitrate */
+ (void) apply_preset(gfp, gfp->VBR_mean_bitrate_kbps, 0);
+ gfp->VBR = cfg->vbr;
+
+ break;
+ }
+ }
+
+ /*initialize default values common for all modes */
+
+ gfc->sv_qnt.mask_adjust = gfp->maskingadjust;
+ gfc->sv_qnt.mask_adjust_short = gfp->maskingadjust_short;
+
+ /* just another daily changing developer switch */
+ if (gfp->tune) {
+ gfc->sv_qnt.mask_adjust += gfp->tune_value_a;
+ gfc->sv_qnt.mask_adjust_short += gfp->tune_value_a;
+ }
+
+
+ if (cfg->vbr != vbr_off) { /* choose a min/max bitrate for VBR */
+ /* if the user didn't specify VBR_max_bitrate: */
+ cfg->vbr_min_bitrate_index = 1; /* default: allow 8 kbps (MPEG-2) or 32 kbps (MPEG-1) */
+ cfg->vbr_max_bitrate_index = 14; /* default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) */
+ if (cfg->samplerate_out < 16000)
+ cfg->vbr_max_bitrate_index = 8; /* default: allow 64 kbps (MPEG-2.5) */
+ if (gfp->VBR_min_bitrate_kbps) {
+ gfp->VBR_min_bitrate_kbps =
+ FindNearestBitrate(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out);
+ cfg->vbr_min_bitrate_index =
+ BitrateIndex(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out);
+ if (cfg->vbr_min_bitrate_index < 0) {
+ /* This never happens, because of preceding FindNearestBitrate!
+ * But, set a sane value, just in case
+ */
+ assert(0);
+ cfg->vbr_min_bitrate_index = 1;
+ }
+ }
+ if (gfp->VBR_max_bitrate_kbps) {
+ gfp->VBR_max_bitrate_kbps =
+ FindNearestBitrate(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out);
+ cfg->vbr_max_bitrate_index =
+ BitrateIndex(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out);
+ if (cfg->vbr_max_bitrate_index < 0) {
+ /* This never happens, because of preceding FindNearestBitrate!
+ * But, set a sane value, just in case
+ */
+ assert(0);
+ cfg->vbr_max_bitrate_index = cfg->samplerate_out < 16000 ? 8 : 14;
+ }
+ }
+ gfp->VBR_min_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_min_bitrate_index];
+ gfp->VBR_max_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_max_bitrate_index];
+ gfp->VBR_mean_bitrate_kbps =
+ Min(bitrate_table[cfg->version][cfg->vbr_max_bitrate_index],
+ gfp->VBR_mean_bitrate_kbps);
+ gfp->VBR_mean_bitrate_kbps =
+ Max(bitrate_table[cfg->version][cfg->vbr_min_bitrate_index],
+ gfp->VBR_mean_bitrate_kbps);
+ }
+
+ cfg->preset = gfp->preset;
+ cfg->write_lame_tag = gfp->write_lame_tag;
+ gfc->sv_qnt.substep_shaping = gfp->substep_shaping;
+ cfg->noise_shaping = gfp->noise_shaping;
+ cfg->subblock_gain = gfp->subblock_gain;
+ cfg->use_best_huffman = gfp->use_best_huffman;
+ cfg->avg_bitrate = gfp->brate;
+ cfg->vbr_avg_bitrate_kbps = gfp->VBR_mean_bitrate_kbps;
+ cfg->compression_ratio = gfp->compression_ratio;
+
+ /* initialize internal qval settings */
+ lame_init_qval(gfp);
+
+
+ /* automatic ATH adjustment on
+ */
+ if (gfp->athaa_type < 0)
+ gfc->ATH->use_adjust = 3;
+ else
+ gfc->ATH->use_adjust = gfp->athaa_type;
+
+
+ /* initialize internal adaptive ATH settings -jd */
+ gfc->ATH->aa_sensitivity_p = pow(10.0, gfp->athaa_sensitivity / -10.0);
+
+
+ if (gfp->short_blocks == short_block_not_set) {
+ gfp->short_blocks = short_block_allowed;
+ }
+
+ /*Note Jan/2003: Many hardware decoders cannot handle short blocks in regular
+ stereo mode unless they are coupled (same type in both channels)
+ it is a rare event (1 frame per min. or so) that LAME would use
+ uncoupled short blocks, so lets turn them off until we decide
+ how to handle this. No other encoders allow uncoupled short blocks,
+ even though it is in the standard. */
+ /* rh 20040217: coupling makes no sense for mono and dual-mono streams
+ */
+ if (gfp->short_blocks == short_block_allowed
+ && (cfg->mode == JOINT_STEREO || cfg->mode == STEREO)) {
+ gfp->short_blocks = short_block_coupled;
+ }
+
+ cfg->short_blocks = gfp->short_blocks;
+
+
+ if (lame_get_quant_comp(gfp) < 0)
+ (void) lame_set_quant_comp(gfp, 1);
+ if (lame_get_quant_comp_short(gfp) < 0)
+ (void) lame_set_quant_comp_short(gfp, 0);
+
+ if (lame_get_msfix(gfp) < 0)
+ lame_set_msfix(gfp, 0);
+
+ /* select psychoacoustic model */
+ (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 1);
+
+ if (gfp->ATHtype < 0)
+ gfp->ATHtype = 4;
+
+ if (gfp->ATHcurve < 0)
+ gfp->ATHcurve = 4;
+
+ if (gfp->interChRatio < 0)
+ gfp->interChRatio = 0;
+
+ if (gfp->useTemporal < 0)
+ gfp->useTemporal = 1; /* on by default */
+
+
+ cfg->interChRatio = gfp->interChRatio;
+ cfg->msfix = gfp->msfix;
+ cfg->ATH_offset_db = 0-gfp->ATH_lower_db;
+ cfg->ATH_offset_factor = powf(10.f, cfg->ATH_offset_db * 0.1f);
+ cfg->ATHcurve = gfp->ATHcurve;
+ cfg->ATHtype = gfp->ATHtype;
+ cfg->ATHonly = gfp->ATHonly;
+ cfg->ATHshort = gfp->ATHshort;
+ cfg->noATH = gfp->noATH;
+
+ cfg->quant_comp = gfp->quant_comp;
+ cfg->quant_comp_short = gfp->quant_comp_short;
+
+ cfg->use_temporal_masking_effect = gfp->useTemporal;
+ if (cfg->mode == JOINT_STEREO) {
+ cfg->use_safe_joint_stereo = gfp->exp_nspsytune & 2;
+ }
+ else {
+ cfg->use_safe_joint_stereo = 0;
+ }
+ {
+ cfg->adjust_bass_db = (gfp->exp_nspsytune >> 2) & 63;
+ if (cfg->adjust_bass_db >= 32.f)
+ cfg->adjust_bass_db -= 64.f;
+ cfg->adjust_bass_db *= 0.25f;
+
+ cfg->adjust_alto_db = (gfp->exp_nspsytune >> 8) & 63;
+ if (cfg->adjust_alto_db >= 32.f)
+ cfg->adjust_alto_db -= 64.f;
+ cfg->adjust_alto_db *= 0.25f;
+
+ cfg->adjust_treble_db = (gfp->exp_nspsytune >> 14) & 63;
+ if (cfg->adjust_treble_db >= 32.f)
+ cfg->adjust_treble_db -= 64.f;
+ cfg->adjust_treble_db *= 0.25f;
+
+ /* to be compatible with Naoki's original code, the next 6 bits
+ * define only the amount of changing treble for sfb21 */
+ cfg->adjust_sfb21_db = (gfp->exp_nspsytune >> 20) & 63;
+ if (cfg->adjust_sfb21_db >= 32.f)
+ cfg->adjust_sfb21_db -= 64.f;
+ cfg->adjust_sfb21_db *= 0.25f;
+ cfg->adjust_sfb21_db += cfg->adjust_treble_db;
+ }
+
+ /* Setting up the PCM input data transform matrix, to apply
+ * user defined re-scaling, and or two-to-one channel downmix.
+ */
+ {
+ FLOAT m[2][2] = { {1.0f, 0.0f}, {0.0f, 1.0f} };
+
+ /* user selected scaling of the samples */
+ m[0][0] *= gfp->scale;
+ m[0][1] *= gfp->scale;
+ m[1][0] *= gfp->scale;
+ m[1][1] *= gfp->scale;
+ /* user selected scaling of the channel 0 (left) samples */
+ m[0][0] *= gfp->scale_left;
+ m[0][1] *= gfp->scale_left;
+ /* user selected scaling of the channel 1 (right) samples */
+ m[1][0] *= gfp->scale_right;
+ m[1][1] *= gfp->scale_right;
+ /* Downsample to Mono if 2 channels in and 1 channel out */
+ if (cfg->channels_in == 2 && cfg->channels_out == 1) {
+ m[0][0] = 0.5f * (m[0][0] + m[1][0]);
+ m[0][1] = 0.5f * (m[0][1] + m[1][1]);
+ m[1][0] = 0;
+ m[1][1] = 0;
+ }
+ cfg->pcm_transform[0][0] = m[0][0];
+ cfg->pcm_transform[0][1] = m[0][1];
+ cfg->pcm_transform[1][0] = m[1][0];
+ cfg->pcm_transform[1][1] = m[1][1];
+ }
+
+ /* padding method as described in
+ * "MPEG-Layer3 / Bitstream Syntax and Decoding"
+ * by Martin Sieler, Ralph Sperschneider
+ *
+ * note: there is no padding for the very first frame
+ *
+ * Robert Hegemann 2000-06-22
+ */
+ gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF = 0;
+ if (cfg->vbr == vbr_off)
+ gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF
+ = ((cfg->version + 1) * 72000L * cfg->avg_bitrate) % cfg->samplerate_out;
+
+ (void) lame_init_bitstream(gfp);
+
+ iteration_init(gfc);
+ (void) psymodel_init(gfp);
+
+ cfg->buffer_constraint = get_max_frame_buffer_size_by_constraint(cfg, gfp->strict_ISO);
+
+
+ cfg->findReplayGain = gfp->findReplayGain;
+ cfg->decode_on_the_fly = gfp->decode_on_the_fly;
+
+ if (cfg->decode_on_the_fly)
+ cfg->findPeakSample = 1;
+
+ if (cfg->findReplayGain) {
+ if (InitGainAnalysis(gfc->sv_rpg.rgdata, cfg->samplerate_out) == INIT_GAIN_ANALYSIS_ERROR) {
+ /* Actually this never happens, our samplerates are the ones RG accepts!
+ * But just in case, turn RG off
+ */
+ assert(0);
+ cfg->findReplayGain = 0;
+ }
+ }
+
+#ifdef DECODE_ON_THE_FLY
+ if (cfg->decode_on_the_fly && !gfp->decode_only) {
+ if (gfc->hip) {
+ hip_decode_exit(gfc->hip);
+ }
+ gfc->hip = hip_decode_init();
+ /* report functions */
+ hip_set_errorf(gfc->hip, gfp->report.errorf);
+ hip_set_debugf(gfc->hip, gfp->report.debugf);
+ hip_set_msgf(gfc->hip, gfp->report.msgf);
+ }
+#endif
+ /* updating lame internal flags finished successful */
+ gfc->lame_init_params_successful = 1;
+ return 0;
+}
+
+static void
+concatSep(char* dest, char const* sep, char const* str)
+{
+ if (*dest != 0) strcat(dest, sep);
+ strcat(dest, str);
+}
+
+/*
+ * print_config
+ *
+ * Prints some selected information about the coding parameters via
+ * the macro command MSGF(), which is currently mapped to lame_errorf
+ * (reports via a error function?), which is a printf-like function
+ * for .
+ */
+
+void
+lame_print_config(const lame_global_flags * gfp)
+{
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ double const out_samplerate = cfg->samplerate_out;
+ double const in_samplerate = cfg->samplerate_in;
+
+ MSGF(gfc, "LAME %s %s (%s)\n", get_lame_version(), get_lame_os_bitness(), get_lame_url());
+
+#if (LAME_ALPHA_VERSION)
+ MSGF(gfc, "warning: alpha versions should be used for testing only\n");
+#endif
+ if (gfc->CPU_features.MMX
+ || gfc->CPU_features.AMD_3DNow || gfc->CPU_features.SSE || gfc->CPU_features.SSE2) {
+ char text[256] = { 0 };
+ int fft_asm_used = 0;
+#ifdef HAVE_NASM
+ if (gfc->CPU_features.AMD_3DNow) {
+ fft_asm_used = 1;
+ }
+ else if (gfc->CPU_features.SSE) {
+ fft_asm_used = 2;
+ }
+#else
+# if defined( HAVE_XMMINTRIN_H ) && defined( MIN_ARCH_SSE )
+ {
+ fft_asm_used = 3;
+ }
+# endif
+#endif
+ if (gfc->CPU_features.MMX) {
+#ifdef MMX_choose_table
+ concatSep(text, ", ", "MMX (ASM used)");
+#else
+ concatSep(text, ", ", "MMX");
+#endif
+ }
+ if (gfc->CPU_features.AMD_3DNow) {
+ concatSep(text, ", ", (fft_asm_used == 1) ? "3DNow! (ASM used)" : "3DNow!");
+ }
+ if (gfc->CPU_features.SSE) {
+#if defined(HAVE_XMMINTRIN_H)
+ concatSep(text, ", ", "SSE (ASM used)");
+#else
+ concatSep(text, ", ", (fft_asm_used == 2) ? "SSE (ASM used)" : "SSE");
+#endif
+ }
+ if (gfc->CPU_features.SSE2) {
+ concatSep(text, ", ", (fft_asm_used == 3) ? "SSE2 (ASM used)" : "SSE2");
+ }
+ MSGF(gfc, "CPU features: %s\n", text);
+ }
+
+ if (cfg->channels_in == 2 && cfg->channels_out == 1 /* mono */ ) {
+ MSGF(gfc, "Autoconverting from stereo to mono. Setting encoding to mono mode.\n");
+ }
+
+ if (isResamplingNecessary(cfg)) {
+ MSGF(gfc, "Resampling: input %g kHz output %g kHz\n",
+ 1.e-3 * in_samplerate, 1.e-3 * out_samplerate);
+ }
+
+ if (cfg->highpass2 > 0.)
+ MSGF(gfc,
+ "Using polyphase highpass filter, transition band: %5.0f Hz - %5.0f Hz\n",
+ 0.5 * cfg->highpass1 * out_samplerate, 0.5 * cfg->highpass2 * out_samplerate);
+ if (0. < cfg->lowpass1 || 0. < cfg->lowpass2) {
+ MSGF(gfc,
+ "Using polyphase lowpass filter, transition band: %5.0f Hz - %5.0f Hz\n",
+ 0.5 * cfg->lowpass1 * out_samplerate, 0.5 * cfg->lowpass2 * out_samplerate);
+ }
+ else {
+ MSGF(gfc, "polyphase lowpass filter disabled\n");
+ }
+
+ if (cfg->free_format) {
+ MSGF(gfc, "Warning: many decoders cannot handle free format bitstreams\n");
+ if (cfg->avg_bitrate > 320) {
+ MSGF(gfc,
+ "Warning: many decoders cannot handle free format bitrates >320 kbps (see documentation)\n");
+ }
+ }
+}
+
+
+/** rh:
+ * some pretty printing is very welcome at this point!
+ * so, if someone is willing to do so, please do it!
+ * add more, if you see more...
+ */
+void
+lame_print_internals(const lame_global_flags * gfp)
+{
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ const char *pc = "";
+
+ /* compiler/processor optimizations, operational, etc.
+ */
+ MSGF(gfc, "\nmisc:\n\n");
+
+ MSGF(gfc, "\tscaling: %g\n", gfp->scale);
+ MSGF(gfc, "\tch0 (left) scaling: %g\n", gfp->scale_left);
+ MSGF(gfc, "\tch1 (right) scaling: %g\n", gfp->scale_right);
+ switch (cfg->use_best_huffman) {
+ default:
+ pc = "normal";
+ break;
+ case 1:
+ pc = "best (outside loop)";
+ break;
+ case 2:
+ pc = "best (inside loop, slow)";
+ break;
+ }
+ MSGF(gfc, "\thuffman search: %s\n", pc);
+ MSGF(gfc, "\texperimental Y=%d\n", gfp->experimentalY);
+ MSGF(gfc, "\t...\n");
+
+ /* everything controlling the stream format
+ */
+ MSGF(gfc, "\nstream format:\n\n");
+ switch (cfg->version) {
+ case 0:
+ pc = "2.5";
+ break;
+ case 1:
+ pc = "1";
+ break;
+ case 2:
+ pc = "2";
+ break;
+ default:
+ pc = "?";
+ break;
+ }
+ MSGF(gfc, "\tMPEG-%s Layer 3\n", pc);
+ switch (cfg->mode) {
+ case JOINT_STEREO:
+ pc = "joint stereo";
+ break;
+ case STEREO:
+ pc = "stereo";
+ break;
+ case DUAL_CHANNEL:
+ pc = "dual channel";
+ break;
+ case MONO:
+ pc = "mono";
+ break;
+ case NOT_SET:
+ pc = "not set (error)";
+ break;
+ default:
+ pc = "unknown (error)";
+ break;
+ }
+ MSGF(gfc, "\t%d channel - %s\n", cfg->channels_out, pc);
+
+ switch (cfg->vbr) {
+ case vbr_off:
+ pc = "off";
+ break;
+ default:
+ pc = "all";
+ break;
+ }
+ MSGF(gfc, "\tpadding: %s\n", pc);
+
+ if (vbr_default == cfg->vbr)
+ pc = "(default)";
+ else if (cfg->free_format)
+ pc = "(free format)";
+ else
+ pc = "";
+ switch (cfg->vbr) {
+ case vbr_off:
+ MSGF(gfc, "\tconstant bitrate - CBR %s\n", pc);
+ break;
+ case vbr_abr:
+ MSGF(gfc, "\tvariable bitrate - ABR %s\n", pc);
+ break;
+ case vbr_rh:
+ MSGF(gfc, "\tvariable bitrate - VBR rh %s\n", pc);
+ break;
+ case vbr_mt:
+ MSGF(gfc, "\tvariable bitrate - VBR mt %s\n", pc);
+ break;
+ case vbr_mtrh:
+ MSGF(gfc, "\tvariable bitrate - VBR mtrh %s\n", pc);
+ break;
+ default:
+ MSGF(gfc, "\t ?? oops, some new one ?? \n");
+ break;
+ }
+ if (cfg->write_lame_tag)
+ MSGF(gfc, "\tusing LAME Tag\n");
+ MSGF(gfc, "\t...\n");
+
+ /* everything controlling psychoacoustic settings, like ATH, etc.
+ */
+ MSGF(gfc, "\npsychoacoustic:\n\n");
+
+ switch (cfg->short_blocks) {
+ default:
+ case short_block_not_set:
+ pc = "?";
+ break;
+ case short_block_allowed:
+ pc = "allowed";
+ break;
+ case short_block_coupled:
+ pc = "channel coupled";
+ break;
+ case short_block_dispensed:
+ pc = "dispensed";
+ break;
+ case short_block_forced:
+ pc = "forced";
+ break;
+ }
+ MSGF(gfc, "\tusing short blocks: %s\n", pc);
+ MSGF(gfc, "\tsubblock gain: %d\n", cfg->subblock_gain);
+ MSGF(gfc, "\tadjust masking: %g dB\n", gfc->sv_qnt.mask_adjust);
+ MSGF(gfc, "\tadjust masking short: %g dB\n", gfc->sv_qnt.mask_adjust_short);
+ MSGF(gfc, "\tquantization comparison: %d\n", cfg->quant_comp);
+ MSGF(gfc, "\t ^ comparison short blocks: %d\n", cfg->quant_comp_short);
+ MSGF(gfc, "\tnoise shaping: %d\n", cfg->noise_shaping);
+ MSGF(gfc, "\t ^ amplification: %d\n", cfg->noise_shaping_amp);
+ MSGF(gfc, "\t ^ stopping: %d\n", cfg->noise_shaping_stop);
+
+ pc = "using";
+ if (cfg->ATHshort)
+ pc = "the only masking for short blocks";
+ if (cfg->ATHonly)
+ pc = "the only masking";
+ if (cfg->noATH)
+ pc = "not used";
+ MSGF(gfc, "\tATH: %s\n", pc);
+ MSGF(gfc, "\t ^ type: %d\n", cfg->ATHtype);
+ MSGF(gfc, "\t ^ shape: %g%s\n", cfg->ATHcurve, " (only for type 4)");
+ MSGF(gfc, "\t ^ level adjustement: %g dB\n", cfg->ATH_offset_db);
+ MSGF(gfc, "\t ^ adjust type: %d\n", gfc->ATH->use_adjust);
+ MSGF(gfc, "\t ^ adjust sensitivity power: %f\n", gfc->ATH->aa_sensitivity_p);
+
+ MSGF(gfc, "\texperimental psy tunings by Naoki Shibata\n");
+ MSGF(gfc, "\t adjust masking bass=%g dB, alto=%g dB, treble=%g dB, sfb21=%g dB\n",
+ 10 * log10(gfc->sv_qnt.longfact[0]),
+ 10 * log10(gfc->sv_qnt.longfact[7]),
+ 10 * log10(gfc->sv_qnt.longfact[14]), 10 * log10(gfc->sv_qnt.longfact[21]));
+
+ pc = cfg->use_temporal_masking_effect ? "yes" : "no";
+ MSGF(gfc, "\tusing temporal masking effect: %s\n", pc);
+ MSGF(gfc, "\tinterchannel masking ratio: %g\n", cfg->interChRatio);
+ MSGF(gfc, "\t...\n");
+
+ /* that's all ?
+ */
+ MSGF(gfc, "\n");
+ return;
+}
+
+
+static void
+save_gain_values(lame_internal_flags * gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ RpgStateVar_t const *const rsv = &gfc->sv_rpg;
+ RpgResult_t *const rov = &gfc->ov_rpg;
+ /* save the ReplayGain value */
+ if (cfg->findReplayGain) {
+ FLOAT const RadioGain = (FLOAT) GetTitleGain(rsv->rgdata);
+ if (NEQ(RadioGain, GAIN_NOT_ENOUGH_SAMPLES)) {
+ rov->RadioGain = (int) floor(RadioGain * 10.0 + 0.5); /* round to nearest */
+ }
+ else {
+ rov->RadioGain = 0;
+ }
+ }
+
+ /* find the gain and scale change required for no clipping */
+ if (cfg->findPeakSample) {
+ rov->noclipGainChange = (int) ceil(log10(rov->PeakSample / 32767.0) * 20.0 * 10.0); /* round up */
+
+ if (rov->noclipGainChange > 0) { /* clipping occurs */
+ rov->noclipScale = floor((32767.0f / rov->PeakSample) * 100.0f) / 100.0f; /* round down */
+ }
+ else /* no clipping */
+ rov->noclipScale = -1.0f;
+ }
+}
+
+
+
+static int
+update_inbuffer_size(lame_internal_flags * gfc, const int nsamples)
+{
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ if (esv->in_buffer_0 == 0 || esv->in_buffer_nsamples < nsamples) {
+ if (esv->in_buffer_0) {
+ free(esv->in_buffer_0);
+ }
+ if (esv->in_buffer_1) {
+ free(esv->in_buffer_1);
+ }
+ esv->in_buffer_0 = lame_calloc(sample_t, nsamples);
+ esv->in_buffer_1 = lame_calloc(sample_t, nsamples);
+ esv->in_buffer_nsamples = nsamples;
+ }
+ if (esv->in_buffer_0 == NULL || esv->in_buffer_1 == NULL) {
+ if (esv->in_buffer_0) {
+ free(esv->in_buffer_0);
+ }
+ if (esv->in_buffer_1) {
+ free(esv->in_buffer_1);
+ }
+ esv->in_buffer_0 = 0;
+ esv->in_buffer_1 = 0;
+ esv->in_buffer_nsamples = 0;
+ ERRORF(gfc, "Error: can't allocate in_buffer buffer\n");
+ return -2;
+ }
+ return 0;
+}
+
+
+static int
+calcNeeded(SessionConfig_t const * cfg)
+{
+ int mf_needed;
+ int pcm_samples_per_frame = 576 * cfg->mode_gr;
+
+ /* some sanity checks */
+#if ENCDELAY < MDCTDELAY
+# error ENCDELAY is less than MDCTDELAY, see encoder.h
+#endif
+#if FFTOFFSET > BLKSIZE
+# error FFTOFFSET is greater than BLKSIZE, see encoder.h
+#endif
+
+ mf_needed = BLKSIZE + pcm_samples_per_frame - FFTOFFSET; /* amount needed for FFT */
+ /*mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); */
+ mf_needed = Max(mf_needed, 512 + pcm_samples_per_frame - 32);
+
+ assert(MFSIZE >= mf_needed);
+
+ return mf_needed;
+}
+
+
+/*
+ * THE MAIN LAME ENCODING INTERFACE
+ * mt 3/00
+ *
+ * input pcm data, output (maybe) mp3 frames.
+ * This routine handles all buffering, resampling and filtering for you.
+ * The required mp3buffer_size can be computed from num_samples,
+ * samplerate and encoding rate, but here is a worst case estimate:
+ *
+ * mp3buffer_size in bytes = 1.25*num_samples + 7200
+ *
+ * return code = number of bytes output in mp3buffer. can be 0
+ *
+ * NOTE: this routine uses LAME's internal PCM data representation,
+ * 'sample_t'. It should not be used by any application.
+ * applications should use lame_encode_buffer(),
+ * lame_encode_buffer_float()
+ * lame_encode_buffer_int()
+ * etc... depending on what type of data they are working with.
+*/
+static int
+lame_encode_buffer_sample_t(lame_internal_flags * gfc,
+ int nsamples, unsigned char *mp3buf, const int mp3buf_size)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int pcm_samples_per_frame = 576 * cfg->mode_gr;
+ int mp3size = 0, ret, i, ch, mf_needed;
+ int mp3out;
+ sample_t *mfbuf[2];
+ sample_t *in_buffer[2];
+
+ if (gfc->class_id != LAME_ID)
+ return -3;
+
+ if (nsamples == 0)
+ return 0;
+
+ /* copy out any tags that may have been written into bitstream */
+ { /* if user specifed buffer size = 0, dont check size */
+ int const buf_size = mp3buf_size == 0 ? INT_MAX : mp3buf_size;
+ mp3out = copy_buffer(gfc, mp3buf, buf_size, 0);
+ }
+ if (mp3out < 0)
+ return mp3out; /* not enough buffer space */
+ mp3buf += mp3out;
+ mp3size += mp3out;
+
+ in_buffer[0] = esv->in_buffer_0;
+ in_buffer[1] = esv->in_buffer_1;
+
+ mf_needed = calcNeeded(cfg);
+
+ mfbuf[0] = esv->mfbuf[0];
+ mfbuf[1] = esv->mfbuf[1];
+
+ while (nsamples > 0) {
+ sample_t const *in_buffer_ptr[2];
+ int n_in = 0; /* number of input samples processed with fill_buffer */
+ int n_out = 0; /* number of samples output with fill_buffer */
+ /* n_in <> n_out if we are resampling */
+
+ in_buffer_ptr[0] = in_buffer[0];
+ in_buffer_ptr[1] = in_buffer[1];
+ /* copy in new samples into mfbuf, with resampling */
+ fill_buffer(gfc, mfbuf, &in_buffer_ptr[0], nsamples, &n_in, &n_out);
+
+ /* compute ReplayGain of resampled input if requested */
+ if (cfg->findReplayGain && !cfg->decode_on_the_fly)
+ if (AnalyzeSamples
+ (gfc->sv_rpg.rgdata, &mfbuf[0][esv->mf_size], &mfbuf[1][esv->mf_size], n_out,
+ cfg->channels_out) == GAIN_ANALYSIS_ERROR)
+ return -6;
+
+
+
+ /* update in_buffer counters */
+ nsamples -= n_in;
+ in_buffer[0] += n_in;
+ if (cfg->channels_out == 2)
+ in_buffer[1] += n_in;
+
+ /* update mfbuf[] counters */
+ esv->mf_size += n_out;
+ assert(esv->mf_size <= MFSIZE);
+
+ /* lame_encode_flush may have set gfc->mf_sample_to_encode to 0
+ * so we have to reinitialize it here when that happened.
+ */
+ if (esv->mf_samples_to_encode < 1) {
+ esv->mf_samples_to_encode = ENCDELAY + POSTDELAY;
+ }
+ esv->mf_samples_to_encode += n_out;
+
+
+ if (esv->mf_size >= mf_needed) {
+ /* encode the frame. */
+ /* mp3buf = pointer to current location in buffer */
+ /* mp3buf_size = size of original mp3 output buffer */
+ /* = 0 if we should not worry about the */
+ /* buffer size because calling program is */
+ /* to lazy to compute it */
+ /* mp3size = size of data written to buffer so far */
+ /* mp3buf_size-mp3size = amount of space avalable */
+
+ int buf_size = mp3buf_size - mp3size;
+ if (mp3buf_size == 0)
+ buf_size = INT_MAX;
+
+ ret = lame_encode_mp3_frame(gfc, mfbuf[0], mfbuf[1], mp3buf, buf_size);
+
+ if (ret < 0)
+ return ret;
+ mp3buf += ret;
+ mp3size += ret;
+
+ /* shift out old samples */
+ esv->mf_size -= pcm_samples_per_frame;
+ esv->mf_samples_to_encode -= pcm_samples_per_frame;
+ for (ch = 0; ch < cfg->channels_out; ch++)
+ for (i = 0; i < esv->mf_size; i++)
+ mfbuf[ch][i] = mfbuf[ch][i + pcm_samples_per_frame];
+ }
+ }
+ assert(nsamples == 0);
+
+ return mp3size;
+}
+
+enum PCMSampleType
+{ pcm_short_type
+, pcm_int_type
+, pcm_long_type
+, pcm_float_type
+, pcm_double_type
+};
+
+static void
+lame_copy_inbuffer(lame_internal_flags* gfc,
+ void const* l, void const* r, int nsamples,
+ enum PCMSampleType pcm_type, int jump, FLOAT s)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ sample_t* ib0 = esv->in_buffer_0;
+ sample_t* ib1 = esv->in_buffer_1;
+ FLOAT m[2][2];
+
+ /* Apply user defined re-scaling */
+ m[0][0] = s * cfg->pcm_transform[0][0];
+ m[0][1] = s * cfg->pcm_transform[0][1];
+ m[1][0] = s * cfg->pcm_transform[1][0];
+ m[1][1] = s * cfg->pcm_transform[1][1];
+
+ /* make a copy of input buffer, changing type to sample_t */
+#define COPY_AND_TRANSFORM(T) \
+{ \
+ T const *bl = l, *br = r; \
+ int i; \
+ for (i = 0; i < nsamples; i++) { \
+ sample_t const xl = *bl; \
+ sample_t const xr = *br; \
+ sample_t const u = xl * m[0][0] + xr * m[0][1]; \
+ sample_t const v = xl * m[1][0] + xr * m[1][1]; \
+ ib0[i] = u; \
+ ib1[i] = v; \
+ bl += jump; \
+ br += jump; \
+ } \
+}
+ switch ( pcm_type ) {
+ case pcm_short_type:
+ COPY_AND_TRANSFORM(short int);
+ break;
+ case pcm_int_type:
+ COPY_AND_TRANSFORM(int);
+ break;
+ case pcm_long_type:
+ COPY_AND_TRANSFORM(long int);
+ break;
+ case pcm_float_type:
+ COPY_AND_TRANSFORM(float);
+ break;
+ case pcm_double_type:
+ COPY_AND_TRANSFORM(double);
+ break;
+ }
+}
+
+
+static int
+lame_encode_buffer_template(lame_global_flags * gfp,
+ void const* buffer_l, void const* buffer_r, const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size, enum PCMSampleType pcm_type, int aa, FLOAT norm)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ SessionConfig_t const *const cfg = &gfc->cfg;
+
+ if (nsamples == 0)
+ return 0;
+
+ if (update_inbuffer_size(gfc, nsamples) != 0) {
+ return -2;
+ }
+ /* make a copy of input buffer, changing type to sample_t */
+ if (cfg->channels_in > 1) {
+ if (buffer_l == 0 || buffer_r == 0) {
+ return 0;
+ }
+ lame_copy_inbuffer(gfc, buffer_l, buffer_r, nsamples, pcm_type, aa, norm);
+ }
+ else {
+ if (buffer_l == 0) {
+ return 0;
+ }
+ lame_copy_inbuffer(gfc, buffer_l, buffer_l, nsamples, pcm_type, aa, norm);
+ }
+
+ return lame_encode_buffer_sample_t(gfc, nsamples, mp3buf, mp3buf_size);
+ }
+ }
+ return -3;
+}
+
+int
+lame_encode_buffer(lame_global_flags * gfp,
+ const short int pcm_l[], const short int pcm_r[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_short_type, 1, 1.0);
+}
+
+
+int
+lame_encode_buffer_float(lame_global_flags * gfp,
+ const float pcm_l[], const float pcm_r[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- 32768 for full scale */
+ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 1.0);
+}
+
+
+int
+lame_encode_buffer_ieee_float(lame_t gfp,
+ const float pcm_l[], const float pcm_r[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- 1.0 for full scale */
+ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 32767.0);
+}
+
+
+int
+lame_encode_buffer_interleaved_ieee_float(lame_t gfp,
+ const float pcm[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- 1.0 for full scale */
+ return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_float_type, 2, 32767.0);
+}
+
+
+int
+lame_encode_buffer_ieee_double(lame_t gfp,
+ const double pcm_l[], const double pcm_r[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- 1.0 for full scale */
+ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_double_type, 1, 32767.0);
+}
+
+
+int
+lame_encode_buffer_interleaved_ieee_double(lame_t gfp,
+ const double pcm[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- 1.0 for full scale */
+ return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_double_type, 2, 32767.0);
+}
+
+
+int
+lame_encode_buffer_int(lame_global_flags * gfp,
+ const int pcm_l[], const int pcm_r[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- MAX_INT for full scale */
+ FLOAT const norm = (1.0 / (1L << (8 * sizeof(int) - 16)));
+ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_int_type, 1, norm);
+}
+
+
+int
+lame_encode_buffer_long2(lame_global_flags * gfp,
+ const long pcm_l[], const long pcm_r[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- MAX_LONG for full scale */
+ FLOAT const norm = (1.0 / (1L << (8 * sizeof(long) - 16)));
+ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, norm);
+}
+
+
+int
+lame_encode_buffer_long(lame_global_flags * gfp,
+ const long pcm_l[], const long pcm_r[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- 32768 for full scale */
+ return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, 1.0);
+}
+
+
+
+int
+lame_encode_buffer_interleaved(lame_global_flags * gfp,
+ short int pcm[], int nsamples,
+ unsigned char *mp3buf, int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- MAX_SHORT for full scale */
+ return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_short_type, 2, 1.0);
+}
+
+
+int
+lame_encode_buffer_interleaved_int(lame_t gfp,
+ const int pcm[], const int nsamples,
+ unsigned char *mp3buf, const int mp3buf_size)
+{
+ /* input is assumed to be normalized to +/- MAX(int) for full scale */
+ FLOAT const norm = (1.0 / (1L << (8 * sizeof(int)-16)));
+ return lame_encode_buffer_template(gfp, pcm, pcm + 1, nsamples, mp3buf, mp3buf_size, pcm_int_type, 2, norm);
+}
+
+
+
+
+/*****************************************************************
+ Flush mp3 buffer, pad with ancillary data so last frame is complete.
+ Reset reservoir size to 0
+ but keep all PCM samples and MDCT data in memory
+ This option is used to break a large file into several mp3 files
+ that when concatenated together will decode with no gaps
+ Because we set the reservoir=0, they will also decode seperately
+ with no errors.
+*********************************************************************/
+int
+lame_encode_flush_nogap(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)
+{
+ int rc = -3;
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ flush_bitstream(gfc);
+ /* if user specifed buffer size = 0, dont check size */
+ if (mp3buffer_size == 0)
+ mp3buffer_size = INT_MAX;
+ rc = copy_buffer(gfc, mp3buffer, mp3buffer_size, 1);
+ save_gain_values(gfc);
+ }
+ }
+ return rc;
+}
+
+
+/* called by lame_init_params. You can also call this after flush_nogap
+ if you want to write new id3v2 and Xing VBR tags into the bitstream */
+int
+lame_init_bitstream(lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags *const gfc = gfp->internal_flags;
+ if (gfc != 0) {
+ gfc->ov_enc.frame_number = 0;
+
+ if (gfp->write_id3tag_automatic) {
+ (void) id3tag_write_v2(gfp);
+ }
+ /* initialize histogram data optionally used by frontend */
+ memset(gfc->ov_enc.bitrate_channelmode_hist, 0,
+ sizeof(gfc->ov_enc.bitrate_channelmode_hist));
+ memset(gfc->ov_enc.bitrate_blocktype_hist, 0,
+ sizeof(gfc->ov_enc.bitrate_blocktype_hist));
+
+ gfc->ov_rpg.PeakSample = 0.0;
+
+ /* Write initial VBR Header to bitstream and init VBR data */
+ if (gfc->cfg.write_lame_tag)
+ (void) InitVbrTag(gfp);
+
+
+ return 0;
+ }
+ }
+ return -3;
+}
+
+
+/*****************************************************************/
+/* flush internal PCM sample buffers, then mp3 buffers */
+/* then write id3 v1 tags into bitstream. */
+/*****************************************************************/
+
+int
+lame_encode_flush(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)
+{
+ lame_internal_flags *gfc;
+ SessionConfig_t const *cfg;
+ EncStateVar_t *esv;
+ short int buffer[2][1152];
+ int imp3 = 0, mp3count, mp3buffer_size_remaining;
+
+ /* we always add POSTDELAY=288 padding to make sure granule with real
+ * data can be complety decoded (because of 50% overlap with next granule */
+ int end_padding;
+ int frames_left;
+ int samples_to_encode;
+ int pcm_samples_per_frame;
+ int mf_needed;
+ int is_resampling_necessary;
+ double resample_ratio = 1;
+
+ if (!is_lame_global_flags_valid(gfp)) {
+ return -3;
+ }
+ gfc = gfp->internal_flags;
+ if (!is_lame_internal_flags_valid(gfc)) {
+ return -3;
+ }
+ cfg = &gfc->cfg;
+ esv = &gfc->sv_enc;
+
+ /* Was flush already called? */
+ if (esv->mf_samples_to_encode < 1) {
+ return 0;
+ }
+ pcm_samples_per_frame = 576 * cfg->mode_gr;
+ mf_needed = calcNeeded(cfg);
+
+ samples_to_encode = esv->mf_samples_to_encode - POSTDELAY;
+
+ memset(buffer, 0, sizeof(buffer));
+ mp3count = 0;
+
+ is_resampling_necessary = isResamplingNecessary(cfg);
+ if (is_resampling_necessary) {
+ resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out;
+ /* delay due to resampling; needs to be fixed, if resampling code gets changed */
+ samples_to_encode += 16. / resample_ratio;
+ }
+ end_padding = pcm_samples_per_frame - (samples_to_encode % pcm_samples_per_frame);
+ if (end_padding < 576)
+ end_padding += pcm_samples_per_frame;
+ gfc->ov_enc.encoder_padding = end_padding;
+
+ frames_left = (samples_to_encode + end_padding) / pcm_samples_per_frame;
+ while (frames_left > 0 && imp3 >= 0) {
+ int const frame_num = gfc->ov_enc.frame_number;
+ int bunch = mf_needed - esv->mf_size;
+
+ bunch *= resample_ratio;
+ if (bunch > 1152) bunch = 1152;
+ if (bunch < 1) bunch = 1;
+
+ mp3buffer_size_remaining = mp3buffer_size - mp3count;
+
+ /* if user specifed buffer size = 0, dont check size */
+ if (mp3buffer_size == 0)
+ mp3buffer_size_remaining = 0;
+
+ /* send in a frame of 0 padding until all internal sample buffers
+ * are flushed
+ */
+ imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], bunch,
+ mp3buffer, mp3buffer_size_remaining);
+
+ mp3buffer += imp3;
+ mp3count += imp3;
+ { /* even a single pcm sample can produce several frames!
+ * for example: 1 Hz input file resampled to 8 kHz mpeg2.5
+ */
+ int const new_frames = gfc->ov_enc.frame_number - frame_num;
+ if (new_frames > 0)
+ frames_left -= new_frames;
+ }
+ }
+ /* Set esv->mf_samples_to_encode to 0, so we may detect
+ * and break loops calling it more than once in a row.
+ */
+ esv->mf_samples_to_encode = 0;
+
+ if (imp3 < 0) {
+ /* some type of fatal error */
+ return imp3;
+ }
+
+ mp3buffer_size_remaining = mp3buffer_size - mp3count;
+ /* if user specifed buffer size = 0, dont check size */
+ if (mp3buffer_size == 0)
+ mp3buffer_size_remaining = INT_MAX;
+
+ /* mp3 related stuff. bit buffer might still contain some mp3 data */
+ flush_bitstream(gfc);
+ imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 1);
+ save_gain_values(gfc);
+ if (imp3 < 0) {
+ /* some type of fatal error */
+ return imp3;
+ }
+ mp3buffer += imp3;
+ mp3count += imp3;
+ mp3buffer_size_remaining = mp3buffer_size - mp3count;
+ /* if user specifed buffer size = 0, dont check size */
+ if (mp3buffer_size == 0)
+ mp3buffer_size_remaining = INT_MAX;
+
+ if (gfp->write_id3tag_automatic) {
+ /* write a id3 tag to the bitstream */
+ (void) id3tag_write_v1(gfp);
+
+ imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 0);
+
+ if (imp3 < 0) {
+ return imp3;
+ }
+ mp3count += imp3;
+ }
+#if 0
+ {
+ int const ed = gfc->ov_enc.encoder_delay;
+ int const ep = gfc->ov_enc.encoder_padding;
+ int const ns = (gfc->ov_enc.frame_number * pcm_samples_per_frame) - (ed + ep);
+ double duration = ns;
+ duration /= cfg->samplerate_out;
+ MSGF(gfc, "frames=%d\n", gfc->ov_enc.frame_number);
+ MSGF(gfc, "pcm_samples_per_frame=%d\n", pcm_samples_per_frame);
+ MSGF(gfc, "encoder delay=%d\n", ed);
+ MSGF(gfc, "encoder padding=%d\n", ep);
+ MSGF(gfc, "sample count=%d (%g)\n", ns, cfg->samplerate_in * duration);
+ MSGF(gfc, "duration=%g sec\n", duration);
+ }
+#endif
+ return mp3count;
+}
+
+/***********************************************************************
+ *
+ * lame_close ()
+ *
+ * frees internal buffers
+ *
+ ***********************************************************************/
+
+int
+lame_close(lame_global_flags * gfp)
+{
+ int ret = 0;
+ if (gfp && gfp->class_id == LAME_ID) {
+ lame_internal_flags *const gfc = gfp->internal_flags;
+ gfp->class_id = 0;
+ if (NULL == gfc || gfc->class_id != LAME_ID) {
+ ret = -3;
+ }
+ if (NULL != gfc) {
+ gfc->lame_init_params_successful = 0;
+ gfc->class_id = 0;
+ /* this routine will free all malloc'd data in gfc, and then free gfc: */
+ freegfc(gfc);
+ gfp->internal_flags = NULL;
+ }
+ if (gfp->lame_allocated_gfp) {
+ gfp->lame_allocated_gfp = 0;
+ free(gfp);
+ }
+ }
+ return ret;
+}
+
+/*****************************************************************/
+/* flush internal mp3 buffers, and free internal buffers */
+/*****************************************************************/
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+int CDECL
+lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size);
+#else
+#endif
+
+int
+lame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)
+{
+ int const ret = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);
+
+ (void) lame_close(gfp);
+
+ return ret;
+}
+
+/*****************************************************************/
+/* write VBR Xing header, and ID3 version 1 tag, if asked for */
+/*****************************************************************/
+void lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream);
+
+void
+lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream)
+{
+ lame_internal_flags *gfc;
+ SessionConfig_t const *cfg;
+ if (!is_lame_global_flags_valid(gfp)) {
+ return;
+ }
+ gfc = gfp->internal_flags;
+ if (!is_lame_internal_flags_valid(gfc)) {
+ return;
+ }
+ cfg = &gfc->cfg;
+ if (!cfg->write_lame_tag) {
+ return;
+ }
+ /* Write Xing header again */
+ if (fpStream && !fseek(fpStream, 0, SEEK_SET)) {
+ int rc = PutVbrTag(gfp, fpStream);
+ switch (rc) {
+ default:
+ /* OK */
+ break;
+
+ case -1:
+ ERRORF(gfc, "Error: could not update LAME tag.\n");
+ break;
+
+ case -2:
+ ERRORF(gfc, "Error: could not update LAME tag, file not seekable.\n");
+ break;
+
+ case -3:
+ ERRORF(gfc, "Error: could not update LAME tag, file not readable.\n");
+ break;
+ }
+ }
+}
+
+
+static int
+lame_init_internal_flags(lame_internal_flags* gfc)
+{
+ if (NULL == gfc)
+ return -1;
+
+ gfc->cfg.vbr_min_bitrate_index = 1; /* not 0 ????? */
+ gfc->cfg.vbr_max_bitrate_index = 13; /* not 14 ????? */
+ gfc->cfg.decode_on_the_fly = 0;
+ gfc->cfg.findReplayGain = 0;
+ gfc->cfg.findPeakSample = 0;
+
+ gfc->sv_qnt.OldValue[0] = 180;
+ gfc->sv_qnt.OldValue[1] = 180;
+ gfc->sv_qnt.CurrentStep[0] = 4;
+ gfc->sv_qnt.CurrentStep[1] = 4;
+ gfc->sv_qnt.masking_lower = 1;
+
+ /* The reason for
+ * int mf_samples_to_encode = ENCDELAY + POSTDELAY;
+ * ENCDELAY = internal encoder delay. And then we have to add POSTDELAY=288
+ * because of the 50% MDCT overlap. A 576 MDCT granule decodes to
+ * 1152 samples. To synthesize the 576 samples centered under this granule
+ * we need the previous granule for the first 288 samples (no problem), and
+ * the next granule for the next 288 samples (not possible if this is last
+ * granule). So we need to pad with 288 samples to make sure we can
+ * encode the 576 samples we are interested in.
+ */
+ gfc->sv_enc.mf_samples_to_encode = ENCDELAY + POSTDELAY;
+ gfc->sv_enc.mf_size = ENCDELAY - MDCTDELAY; /* we pad input with this many 0's */
+ gfc->ov_enc.encoder_padding = 0;
+ gfc->ov_enc.encoder_delay = ENCDELAY;
+
+ gfc->ov_rpg.RadioGain = 0;
+ gfc->ov_rpg.noclipGainChange = 0;
+ gfc->ov_rpg.noclipScale = -1.0;
+
+ gfc->ATH = lame_calloc(ATH_t, 1);
+ if (NULL == gfc->ATH)
+ return -2; /* maybe error codes should be enumerated in lame.h ?? */
+
+ gfc->sv_rpg.rgdata = lame_calloc(replaygain_t, 1);
+ if (NULL == gfc->sv_rpg.rgdata) {
+ return -2;
+ }
+ return 0;
+}
+
+/* initialize mp3 encoder */
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+static
+#else
+#endif
+int
+lame_init_old(lame_global_flags * gfp)
+{
+ disable_FPE(); /* disable floating point exceptions */
+
+ memset(gfp, 0, sizeof(lame_global_flags));
+
+ gfp->class_id = LAME_ID;
+
+ /* Global flags. set defaults here for non-zero values */
+ /* see lame.h for description */
+ /* set integer values to -1 to mean that LAME will compute the
+ * best value, UNLESS the calling program as set it
+ * (and the value is no longer -1)
+ */
+ gfp->strict_ISO = MDB_MAXIMUM;
+
+ gfp->mode = NOT_SET;
+ gfp->original = 1;
+ gfp->samplerate_in = 44100;
+ gfp->num_channels = 2;
+ gfp->num_samples = MAX_U_32_NUM;
+
+ gfp->write_lame_tag = 1;
+ gfp->quality = -1;
+ gfp->short_blocks = short_block_not_set;
+ gfp->subblock_gain = -1;
+
+ gfp->lowpassfreq = 0;
+ gfp->highpassfreq = 0;
+ gfp->lowpasswidth = -1;
+ gfp->highpasswidth = -1;
+
+ gfp->VBR = vbr_off;
+ gfp->VBR_q = 4;
+ gfp->VBR_mean_bitrate_kbps = 128;
+ gfp->VBR_min_bitrate_kbps = 0;
+ gfp->VBR_max_bitrate_kbps = 0;
+ gfp->VBR_hard_min = 0;
+
+ gfp->quant_comp = -1;
+ gfp->quant_comp_short = -1;
+
+ gfp->msfix = -1;
+
+ gfp->attackthre = -1;
+ gfp->attackthre_s = -1;
+
+ gfp->scale = 1;
+ gfp->scale_left = 1;
+ gfp->scale_right = 1;
+
+ gfp->ATHcurve = -1;
+ gfp->ATHtype = -1; /* default = -1 = set in lame_init_params */
+ /* 2 = equal loudness curve */
+ gfp->athaa_sensitivity = 0.0; /* no offset */
+ gfp->athaa_type = -1;
+ gfp->useTemporal = -1;
+ gfp->interChRatio = -1;
+
+ gfp->findReplayGain = 0;
+ gfp->decode_on_the_fly = 0;
+
+ gfp->asm_optimizations.mmx = 1;
+ gfp->asm_optimizations.amd3dnow = 1;
+ gfp->asm_optimizations.sse = 1;
+
+ gfp->preset = 0;
+
+ gfp->write_id3tag_automatic = 1;
+
+ gfp->report.debugf = &lame_report_def;
+ gfp->report.errorf = &lame_report_def;
+ gfp->report.msgf = &lame_report_def;
+
+ gfp->internal_flags = lame_calloc(lame_internal_flags, 1);
+
+ if (lame_init_internal_flags(gfp->internal_flags) < 0) {
+ freegfc(gfp->internal_flags);
+ gfp->internal_flags = 0;
+ return -1;
+ }
+ return 0;
+}
+
+
+lame_global_flags *
+lame_init(void)
+{
+ lame_global_flags *gfp;
+ int ret;
+
+ init_log_table();
+
+ gfp = lame_calloc(lame_global_flags, 1);
+ if (gfp == NULL)
+ return NULL;
+
+ ret = lame_init_old(gfp);
+ if (ret != 0) {
+ free(gfp);
+ return NULL;
+ }
+
+ gfp->lame_allocated_gfp = 1;
+ return gfp;
+}
+
+
+/***********************************************************************
+ *
+ * some simple statistics
+ *
+ * Robert Hegemann 2000-10-11
+ *
+ ***********************************************************************/
+
+/* histogram of used bitrate indexes:
+ * One has to weight them to calculate the average bitrate in kbps
+ *
+ * bitrate indices:
+ * there are 14 possible bitrate indices, 0 has the special meaning
+ * "free format" which is not possible to mix with VBR and 15 is forbidden
+ * anyway.
+ *
+ * stereo modes:
+ * 0: LR number of left-right encoded frames
+ * 1: LR-I number of left-right and intensity encoded frames
+ * 2: MS number of mid-side encoded frames
+ * 3: MS-I number of mid-side and intensity encoded frames
+ *
+ * 4: number of encoded frames
+ *
+ */
+
+void
+lame_bitrate_kbps(const lame_global_flags * gfp, int bitrate_kbps[14])
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int i;
+ if (cfg->free_format) {
+ for (i = 0; i < 14; i++)
+ bitrate_kbps[i] = -1;
+ bitrate_kbps[0] = cfg->avg_bitrate;
+ }
+ else {
+ for (i = 0; i < 14; i++)
+ bitrate_kbps[i] = bitrate_table[cfg->version][i + 1];
+ }
+ }
+ }
+}
+
+
+void
+lame_bitrate_hist(const lame_global_flags * gfp, int bitrate_count[14])
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t const *const eov = &gfc->ov_enc;
+ int i;
+
+ if (cfg->free_format) {
+ for (i = 0; i < 14; i++) {
+ bitrate_count[i] = 0;
+ }
+ bitrate_count[0] = eov->bitrate_channelmode_hist[0][4];
+ }
+ else {
+ for (i = 0; i < 14; i++) {
+ bitrate_count[i] = eov->bitrate_channelmode_hist[i + 1][4];
+ }
+ }
+ }
+ }
+}
+
+
+void
+lame_stereo_mode_hist(const lame_global_flags * gfp, int stmode_count[4])
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ EncResult_t const *const eov = &gfc->ov_enc;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ stmode_count[i] = eov->bitrate_channelmode_hist[15][i];
+ }
+ }
+ }
+}
+
+
+
+void
+lame_bitrate_stereo_mode_hist(const lame_global_flags * gfp, int bitrate_stmode_count[14][4])
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t const *const eov = &gfc->ov_enc;
+ int i;
+ int j;
+
+ if (cfg->free_format) {
+ for (j = 0; j < 14; j++)
+ for (i = 0; i < 4; i++) {
+ bitrate_stmode_count[j][i] = 0;
+ }
+ for (i = 0; i < 4; i++) {
+ bitrate_stmode_count[0][i] = eov->bitrate_channelmode_hist[0][i];
+ }
+ }
+ else {
+ for (j = 0; j < 14; j++) {
+ for (i = 0; i < 4; i++) {
+ bitrate_stmode_count[j][i] = eov->bitrate_channelmode_hist[j + 1][i];
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void
+lame_block_type_hist(const lame_global_flags * gfp, int btype_count[6])
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ EncResult_t const *const eov = &gfc->ov_enc;
+ int i;
+
+ for (i = 0; i < 6; ++i) {
+ btype_count[i] = eov->bitrate_blocktype_hist[15][i];
+ }
+ }
+ }
+}
+
+
+
+void
+lame_bitrate_block_type_hist(const lame_global_flags * gfp, int bitrate_btype_count[14][6])
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t const *const eov = &gfc->ov_enc;
+ int i, j;
+
+ if (cfg->free_format) {
+ for (j = 0; j < 14; ++j) {
+ for (i = 0; i < 6; ++i) {
+ bitrate_btype_count[j][i] = 0;
+ }
+ }
+ for (i = 0; i < 6; ++i) {
+ bitrate_btype_count[0][i] = eov->bitrate_blocktype_hist[0][i];
+ }
+ }
+ else {
+ for (j = 0; j < 14; ++j) {
+ for (i = 0; i < 6; ++i) {
+ bitrate_btype_count[j][i] = eov->bitrate_blocktype_hist[j + 1][i];
+ }
+ }
+ }
+ }
+ }
+}
+
+/* end of lame.c */
diff --git a/pkg/lame/clame/lame.h b/pkg/lame/clame/lame.h
new file mode 100644
index 0000000..5196690
--- /dev/null
+++ b/pkg/lame/clame/lame.h
@@ -0,0 +1,1342 @@
+/*
+ * Interface to MP3 LAME encoding engine
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: lame.h,v 1.192 2017/08/31 14:14:46 robert Exp $ */
+
+#ifndef LAME_LAME_H
+#define LAME_LAME_H
+
+/* for size_t typedef */
+#include
+/* for va_list typedef */
+#include
+/* for FILE typedef, TODO: remove when removing lame_mp3_tags_fid */
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef void (*lame_report_function)(const char *format, va_list ap);
+
+#if defined(WIN32) || defined(_WIN32)
+#undef CDECL
+#define CDECL __cdecl
+#else
+#define CDECL
+#endif
+
+#define DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1
+
+typedef enum vbr_mode_e {
+ vbr_off=0,
+ vbr_mt, /* obsolete, same as vbr_mtrh */
+ vbr_rh,
+ vbr_abr,
+ vbr_mtrh,
+ vbr_max_indicator, /* Don't use this! It's used for sanity checks. */
+ vbr_default=vbr_mtrh /* change this to change the default VBR mode of LAME */
+} vbr_mode;
+
+
+/* MPEG modes */
+typedef enum MPEG_mode_e {
+ STEREO = 0,
+ JOINT_STEREO,
+ DUAL_CHANNEL, /* LAME doesn't supports this! */
+ MONO,
+ NOT_SET,
+ MAX_INDICATOR /* Don't use this! It's used for sanity checks. */
+} MPEG_mode;
+
+/* Padding types */
+typedef enum Padding_type_e {
+ PAD_NO = 0,
+ PAD_ALL,
+ PAD_ADJUST,
+ PAD_MAX_INDICATOR /* Don't use this! It's used for sanity checks. */
+} Padding_type;
+
+
+
+/*presets*/
+typedef enum preset_mode_e {
+ /*values from 8 to 320 should be reserved for abr bitrates*/
+ /*for abr I'd suggest to directly use the targeted bitrate as a value*/
+ ABR_8 = 8,
+ ABR_320 = 320,
+
+ V9 = 410, /*Vx to match Lame and VBR_xx to match FhG*/
+ VBR_10 = 410,
+ V8 = 420,
+ VBR_20 = 420,
+ V7 = 430,
+ VBR_30 = 430,
+ V6 = 440,
+ VBR_40 = 440,
+ V5 = 450,
+ VBR_50 = 450,
+ V4 = 460,
+ VBR_60 = 460,
+ V3 = 470,
+ VBR_70 = 470,
+ V2 = 480,
+ VBR_80 = 480,
+ V1 = 490,
+ VBR_90 = 490,
+ V0 = 500,
+ VBR_100 = 500,
+
+
+
+ /*still there for compatibility*/
+ R3MIX = 1000,
+ STANDARD = 1001,
+ EXTREME = 1002,
+ INSANE = 1003,
+ STANDARD_FAST = 1004,
+ EXTREME_FAST = 1005,
+ MEDIUM = 1006,
+ MEDIUM_FAST = 1007
+} preset_mode;
+
+
+/*asm optimizations*/
+typedef enum asm_optimizations_e {
+ MMX = 1,
+ AMD_3DNOW = 2,
+ SSE = 3
+} asm_optimizations;
+
+
+/* psychoacoustic model */
+typedef enum Psy_model_e {
+ PSY_GPSYCHO = 1,
+ PSY_NSPSYTUNE = 2
+} Psy_model;
+
+
+/* buffer considerations */
+typedef enum buffer_constraint_e {
+ MDB_DEFAULT=0,
+ MDB_STRICT_ISO=1,
+ MDB_MAXIMUM=2
+} buffer_constraint;
+
+
+struct lame_global_struct;
+typedef struct lame_global_struct lame_global_flags;
+typedef lame_global_flags *lame_t;
+
+
+
+
+/***********************************************************************
+ *
+ * The LAME API
+ * These functions should be called, in this order, for each
+ * MP3 file to be encoded. See the file "API" for more documentation
+ *
+ ***********************************************************************/
+
+
+/*
+ * REQUIRED:
+ * initialize the encoder. sets default for all encoder parameters,
+ * returns NULL if some malloc()'s failed
+ * otherwise returns pointer to structure needed for all future
+ * API calls.
+ */
+lame_global_flags * CDECL lame_init(void);
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* obsolete version */
+int CDECL lame_init_old(lame_global_flags *);
+#endif
+
+/*
+ * OPTIONAL:
+ * set as needed to override defaults
+ */
+
+/********************************************************************
+ * input stream description
+ ***********************************************************************/
+/* number of samples. default = 2^32-1 */
+int CDECL lame_set_num_samples(lame_global_flags *, unsigned long);
+unsigned long CDECL lame_get_num_samples(const lame_global_flags *);
+
+/* input sample rate in Hz. default = 44100hz */
+int CDECL lame_set_in_samplerate(lame_global_flags *, int);
+int CDECL lame_get_in_samplerate(const lame_global_flags *);
+
+/* number of channels in input stream. default=2 */
+int CDECL lame_set_num_channels(lame_global_flags *, int);
+int CDECL lame_get_num_channels(const lame_global_flags *);
+
+/*
+ scale the input by this amount before encoding. default=1
+ (not used by decoding routines)
+*/
+int CDECL lame_set_scale(lame_global_flags *, float);
+float CDECL lame_get_scale(const lame_global_flags *);
+
+/*
+ scale the channel 0 (left) input by this amount before encoding. default=1
+ (not used by decoding routines)
+*/
+int CDECL lame_set_scale_left(lame_global_flags *, float);
+float CDECL lame_get_scale_left(const lame_global_flags *);
+
+/*
+ scale the channel 1 (right) input by this amount before encoding. default=1
+ (not used by decoding routines)
+*/
+int CDECL lame_set_scale_right(lame_global_flags *, float);
+float CDECL lame_get_scale_right(const lame_global_flags *);
+
+/*
+ output sample rate in Hz. default = 0, which means LAME picks best value
+ based on the amount of compression. MPEG only allows:
+ MPEG1 32, 44.1, 48khz
+ MPEG2 16, 22.05, 24
+ MPEG2.5 8, 11.025, 12
+ (not used by decoding routines)
+*/
+int CDECL lame_set_out_samplerate(lame_global_flags *, int);
+int CDECL lame_get_out_samplerate(const lame_global_flags *);
+
+
+/********************************************************************
+ * general control parameters
+ ***********************************************************************/
+/* 1=cause LAME to collect data for an MP3 frame analyzer. default=0 */
+int CDECL lame_set_analysis(lame_global_flags *, int);
+int CDECL lame_get_analysis(const lame_global_flags *);
+
+/*
+ 1 = write a Xing VBR header frame.
+ default = 1
+ this variable must have been added by a Hungarian notation Windows programmer :-)
+*/
+int CDECL lame_set_bWriteVbrTag(lame_global_flags *, int);
+int CDECL lame_get_bWriteVbrTag(const lame_global_flags *);
+
+/* 1=decode only. use lame/mpglib to convert mp3/ogg to wav. default=0 */
+int CDECL lame_set_decode_only(lame_global_flags *, int);
+int CDECL lame_get_decode_only(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* 1=encode a Vorbis .ogg file. default=0 */
+/* DEPRECATED */
+int CDECL lame_set_ogg(lame_global_flags *, int);
+int CDECL lame_get_ogg(const lame_global_flags *);
+#endif
+
+/*
+ internal algorithm selection. True quality is determined by the bitrate
+ but this variable will effect quality by selecting expensive or cheap algorithms.
+ quality=0..9. 0=best (very slow). 9=worst.
+ recommended: 2 near-best quality, not too slow
+ 5 good quality, fast
+ 7 ok quality, really fast
+*/
+int CDECL lame_set_quality(lame_global_flags *, int);
+int CDECL lame_get_quality(const lame_global_flags *);
+
+/*
+ mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono
+ default: lame picks based on compression ration and input channels
+*/
+int CDECL lame_set_mode(lame_global_flags *, MPEG_mode);
+MPEG_mode CDECL lame_get_mode(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/*
+ mode_automs. Use a M/S mode with a switching threshold based on
+ compression ratio
+ DEPRECATED
+*/
+int CDECL lame_set_mode_automs(lame_global_flags *, int);
+int CDECL lame_get_mode_automs(const lame_global_flags *);
+#endif
+
+/*
+ force_ms. Force M/S for all frames. For testing only.
+ default = 0 (disabled)
+*/
+int CDECL lame_set_force_ms(lame_global_flags *, int);
+int CDECL lame_get_force_ms(const lame_global_flags *);
+
+/* use free_format? default = 0 (disabled) */
+int CDECL lame_set_free_format(lame_global_flags *, int);
+int CDECL lame_get_free_format(const lame_global_flags *);
+
+/* perform ReplayGain analysis? default = 0 (disabled) */
+int CDECL lame_set_findReplayGain(lame_global_flags *, int);
+int CDECL lame_get_findReplayGain(const lame_global_flags *);
+
+/* decode on the fly. Search for the peak sample. If the ReplayGain
+ * analysis is enabled then perform the analysis on the decoded data
+ * stream. default = 0 (disabled)
+ * NOTE: if this option is set the build-in decoder should not be used */
+int CDECL lame_set_decode_on_the_fly(lame_global_flags *, int);
+int CDECL lame_get_decode_on_the_fly(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* DEPRECATED: now does the same as lame_set_findReplayGain()
+ default = 0 (disabled) */
+int CDECL lame_set_ReplayGain_input(lame_global_flags *, int);
+int CDECL lame_get_ReplayGain_input(const lame_global_flags *);
+
+/* DEPRECATED: now does the same as
+ lame_set_decode_on_the_fly() && lame_set_findReplayGain()
+ default = 0 (disabled) */
+int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int);
+int CDECL lame_get_ReplayGain_decode(const lame_global_flags *);
+
+/* DEPRECATED: now does the same as lame_set_decode_on_the_fly()
+ default = 0 (disabled) */
+int CDECL lame_set_findPeakSample(lame_global_flags *, int);
+int CDECL lame_get_findPeakSample(const lame_global_flags *);
+#endif
+
+/* counters for gapless encoding */
+int CDECL lame_set_nogap_total(lame_global_flags*, int);
+int CDECL lame_get_nogap_total(const lame_global_flags*);
+
+int CDECL lame_set_nogap_currentindex(lame_global_flags* , int);
+int CDECL lame_get_nogap_currentindex(const lame_global_flags*);
+
+
+/*
+ * OPTIONAL:
+ * Set printf like error/debug/message reporting functions.
+ * The second argument has to be a pointer to a function which looks like
+ * void my_debugf(const char *format, va_list ap)
+ * {
+ * (void) vfprintf(stdout, format, ap);
+ * }
+ * If you use NULL as the value of the pointer in the set function, the
+ * lame buildin function will be used (prints to stderr).
+ * To quiet any output you have to replace the body of the example function
+ * with just "return;" and use it in the set function.
+ */
+int CDECL lame_set_errorf(lame_global_flags *, lame_report_function);
+int CDECL lame_set_debugf(lame_global_flags *, lame_report_function);
+int CDECL lame_set_msgf (lame_global_flags *, lame_report_function);
+
+
+
+/* set one of brate compression ratio. default is compression ratio of 11. */
+int CDECL lame_set_brate(lame_global_flags *, int);
+int CDECL lame_get_brate(const lame_global_flags *);
+int CDECL lame_set_compression_ratio(lame_global_flags *, float);
+float CDECL lame_get_compression_ratio(const lame_global_flags *);
+
+
+int CDECL lame_set_preset( lame_global_flags* gfp, int );
+int CDECL lame_set_asm_optimizations( lame_global_flags* gfp, int, int );
+
+
+
+/********************************************************************
+ * frame params
+ ***********************************************************************/
+/* mark as copyright. default=0 */
+int CDECL lame_set_copyright(lame_global_flags *, int);
+int CDECL lame_get_copyright(const lame_global_flags *);
+
+/* mark as original. default=1 */
+int CDECL lame_set_original(lame_global_flags *, int);
+int CDECL lame_get_original(const lame_global_flags *);
+
+/* error_protection. Use 2 bytes from each frame for CRC checksum. default=0 */
+int CDECL lame_set_error_protection(lame_global_flags *, int);
+int CDECL lame_get_error_protection(const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* padding_type. 0=pad no frames 1=pad all frames 2=adjust padding(default) */
+int CDECL lame_set_padding_type(lame_global_flags *, Padding_type);
+Padding_type CDECL lame_get_padding_type(const lame_global_flags *);
+#endif
+
+/* MP3 'private extension' bit Meaningless. default=0 */
+int CDECL lame_set_extension(lame_global_flags *, int);
+int CDECL lame_get_extension(const lame_global_flags *);
+
+/* enforce strict ISO compliance. default=0 */
+int CDECL lame_set_strict_ISO(lame_global_flags *, int);
+int CDECL lame_get_strict_ISO(const lame_global_flags *);
+
+
+/********************************************************************
+ * quantization/noise shaping
+ ***********************************************************************/
+
+/* disable the bit reservoir. For testing only. default=0 */
+int CDECL lame_set_disable_reservoir(lame_global_flags *, int);
+int CDECL lame_get_disable_reservoir(const lame_global_flags *);
+
+/* select a different "best quantization" function. default=0 */
+int CDECL lame_set_quant_comp(lame_global_flags *, int);
+int CDECL lame_get_quant_comp(const lame_global_flags *);
+int CDECL lame_set_quant_comp_short(lame_global_flags *, int);
+int CDECL lame_get_quant_comp_short(const lame_global_flags *);
+
+int CDECL lame_set_experimentalX(lame_global_flags *, int); /* compatibility*/
+int CDECL lame_get_experimentalX(const lame_global_flags *);
+
+/* another experimental option. for testing only */
+int CDECL lame_set_experimentalY(lame_global_flags *, int);
+int CDECL lame_get_experimentalY(const lame_global_flags *);
+
+/* another experimental option. for testing only */
+int CDECL lame_set_experimentalZ(lame_global_flags *, int);
+int CDECL lame_get_experimentalZ(const lame_global_flags *);
+
+/* Naoki's psycho acoustic model. default=0 */
+int CDECL lame_set_exp_nspsytune(lame_global_flags *, int);
+int CDECL lame_get_exp_nspsytune(const lame_global_flags *);
+
+void CDECL lame_set_msfix(lame_global_flags *, double);
+float CDECL lame_get_msfix(const lame_global_flags *);
+
+
+/********************************************************************
+ * VBR control
+ ***********************************************************************/
+/* Types of VBR. default = vbr_off = CBR */
+int CDECL lame_set_VBR(lame_global_flags *, vbr_mode);
+vbr_mode CDECL lame_get_VBR(const lame_global_flags *);
+
+/* VBR quality level. 0=highest 9=lowest */
+int CDECL lame_set_VBR_q(lame_global_flags *, int);
+int CDECL lame_get_VBR_q(const lame_global_flags *);
+
+/* VBR quality level. 0=highest 9=lowest, Range [0,...,10[ */
+int CDECL lame_set_VBR_quality(lame_global_flags *, float);
+float CDECL lame_get_VBR_quality(const lame_global_flags *);
+
+/* Ignored except for VBR=vbr_abr (ABR mode) */
+int CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *);
+
+int CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *);
+
+int CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int);
+int CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *);
+
+/*
+ 1=strictly enforce VBR_min_bitrate. Normally it will be violated for
+ analog silence
+*/
+int CDECL lame_set_VBR_hard_min(lame_global_flags *, int);
+int CDECL lame_get_VBR_hard_min(const lame_global_flags *);
+
+/* for preset */
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+int CDECL lame_set_preset_expopts(lame_global_flags *, int);
+#endif
+
+/********************************************************************
+ * Filtering control
+ ***********************************************************************/
+/* freq in Hz to apply lowpass. Default = 0 = lame chooses. -1 = disabled */
+int CDECL lame_set_lowpassfreq(lame_global_flags *, int);
+int CDECL lame_get_lowpassfreq(const lame_global_flags *);
+/* width of transition band, in Hz. Default = one polyphase filter band */
+int CDECL lame_set_lowpasswidth(lame_global_flags *, int);
+int CDECL lame_get_lowpasswidth(const lame_global_flags *);
+
+/* freq in Hz to apply highpass. Default = 0 = lame chooses. -1 = disabled */
+int CDECL lame_set_highpassfreq(lame_global_flags *, int);
+int CDECL lame_get_highpassfreq(const lame_global_flags *);
+/* width of transition band, in Hz. Default = one polyphase filter band */
+int CDECL lame_set_highpasswidth(lame_global_flags *, int);
+int CDECL lame_get_highpasswidth(const lame_global_flags *);
+
+
+/********************************************************************
+ * psycho acoustics and other arguments which you should not change
+ * unless you know what you are doing
+ ***********************************************************************/
+
+/* only use ATH for masking */
+int CDECL lame_set_ATHonly(lame_global_flags *, int);
+int CDECL lame_get_ATHonly(const lame_global_flags *);
+
+/* only use ATH for short blocks */
+int CDECL lame_set_ATHshort(lame_global_flags *, int);
+int CDECL lame_get_ATHshort(const lame_global_flags *);
+
+/* disable ATH */
+int CDECL lame_set_noATH(lame_global_flags *, int);
+int CDECL lame_get_noATH(const lame_global_flags *);
+
+/* select ATH formula */
+int CDECL lame_set_ATHtype(lame_global_flags *, int);
+int CDECL lame_get_ATHtype(const lame_global_flags *);
+
+/* lower ATH by this many db */
+int CDECL lame_set_ATHlower(lame_global_flags *, float);
+float CDECL lame_get_ATHlower(const lame_global_flags *);
+
+/* select ATH adaptive adjustment type */
+int CDECL lame_set_athaa_type( lame_global_flags *, int);
+int CDECL lame_get_athaa_type( const lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* select the loudness approximation used by the ATH adaptive auto-leveling */
+int CDECL lame_set_athaa_loudapprox( lame_global_flags *, int);
+int CDECL lame_get_athaa_loudapprox( const lame_global_flags *);
+#endif
+
+/* adjust (in dB) the point below which adaptive ATH level adjustment occurs */
+int CDECL lame_set_athaa_sensitivity( lame_global_flags *, float);
+float CDECL lame_get_athaa_sensitivity( const lame_global_flags* );
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* OBSOLETE: predictability limit (ISO tonality formula) */
+int CDECL lame_set_cwlimit(lame_global_flags *, int);
+int CDECL lame_get_cwlimit(const lame_global_flags *);
+#endif
+
+/*
+ allow blocktypes to differ between channels?
+ default: 0 for jstereo, 1 for stereo
+*/
+int CDECL lame_set_allow_diff_short(lame_global_flags *, int);
+int CDECL lame_get_allow_diff_short(const lame_global_flags *);
+
+/* use temporal masking effect (default = 1) */
+int CDECL lame_set_useTemporal(lame_global_flags *, int);
+int CDECL lame_get_useTemporal(const lame_global_flags *);
+
+/* use temporal masking effect (default = 1) */
+int CDECL lame_set_interChRatio(lame_global_flags *, float);
+float CDECL lame_get_interChRatio(const lame_global_flags *);
+
+/* disable short blocks */
+int CDECL lame_set_no_short_blocks(lame_global_flags *, int);
+int CDECL lame_get_no_short_blocks(const lame_global_flags *);
+
+/* force short blocks */
+int CDECL lame_set_force_short_blocks(lame_global_flags *, int);
+int CDECL lame_get_force_short_blocks(const lame_global_flags *);
+
+/* Input PCM is emphased PCM (for instance from one of the rarely
+ emphased CDs), it is STRONGLY not recommended to use this, because
+ psycho does not take it into account, and last but not least many decoders
+ ignore these bits */
+int CDECL lame_set_emphasis(lame_global_flags *, int);
+int CDECL lame_get_emphasis(const lame_global_flags *);
+
+
+
+/************************************************************************/
+/* internal variables, cannot be set... */
+/* provided because they may be of use to calling application */
+/************************************************************************/
+/* version 0=MPEG-2 1=MPEG-1 (2=MPEG-2.5) */
+int CDECL lame_get_version(const lame_global_flags *);
+
+/* encoder delay */
+int CDECL lame_get_encoder_delay(const lame_global_flags *);
+
+/*
+ padding appended to the input to make sure decoder can fully decode
+ all input. Note that this value can only be calculated during the
+ call to lame_encoder_flush(). Before lame_encoder_flush() has
+ been called, the value of encoder_padding = 0.
+*/
+int CDECL lame_get_encoder_padding(const lame_global_flags *);
+
+/* size of MPEG frame */
+int CDECL lame_get_framesize(const lame_global_flags *);
+
+/* number of PCM samples buffered, but not yet encoded to mp3 data. */
+int CDECL lame_get_mf_samples_to_encode( const lame_global_flags* gfp );
+
+/*
+ size (bytes) of mp3 data buffered, but not yet encoded.
+ this is the number of bytes which would be output by a call to
+ lame_encode_flush_nogap. NOTE: lame_encode_flush() will return
+ more bytes than this because it will encode the reamining buffered
+ PCM samples before flushing the mp3 buffers.
+*/
+int CDECL lame_get_size_mp3buffer( const lame_global_flags* gfp );
+
+/* number of frames encoded so far */
+int CDECL lame_get_frameNum(const lame_global_flags *);
+
+/*
+ lame's estimate of the total number of frames to be encoded
+ only valid if calling program set num_samples
+*/
+int CDECL lame_get_totalframes(const lame_global_flags *);
+
+/* RadioGain value. Multiplied by 10 and rounded to the nearest. */
+int CDECL lame_get_RadioGain(const lame_global_flags *);
+
+/* AudiophileGain value. Multipled by 10 and rounded to the nearest. */
+int CDECL lame_get_AudiophileGain(const lame_global_flags *);
+
+/* the peak sample */
+float CDECL lame_get_PeakSample(const lame_global_flags *);
+
+/* Gain change required for preventing clipping. The value is correct only if
+ peak sample searching was enabled. If negative then the waveform
+ already does not clip. The value is multiplied by 10 and rounded up. */
+int CDECL lame_get_noclipGainChange(const lame_global_flags *);
+
+/* user-specified scale factor required for preventing clipping. Value is
+ correct only if peak sample searching was enabled and no user-specified
+ scaling was performed. If negative then either the waveform already does
+ not clip or the value cannot be determined */
+float CDECL lame_get_noclipScale(const lame_global_flags *);
+
+/* returns the limit of PCM samples, which one can pass in an encode call
+ under the constrain of a provided buffer of size buffer_size */
+int CDECL lame_get_maximum_number_of_samples(lame_t gfp, size_t buffer_size);
+
+
+
+
+/*
+ * REQUIRED:
+ * sets more internal configuration based on data provided above.
+ * returns -1 if something failed.
+ */
+int CDECL lame_init_params(lame_global_flags *);
+
+
+/*
+ * OPTIONAL:
+ * get the version number, in a string. of the form:
+ * "3.63 (beta)" or just "3.63".
+ */
+const char* CDECL get_lame_version ( void );
+const char* CDECL get_lame_short_version ( void );
+const char* CDECL get_lame_very_short_version ( void );
+const char* CDECL get_psy_version ( void );
+const char* CDECL get_lame_url ( void );
+const char* CDECL get_lame_os_bitness ( void );
+
+/*
+ * OPTIONAL:
+ * get the version numbers in numerical form.
+ */
+typedef struct {
+ /* generic LAME version */
+ int major;
+ int minor;
+ int alpha; /* 0 if not an alpha version */
+ int beta; /* 0 if not a beta version */
+
+ /* version of the psy model */
+ int psy_major;
+ int psy_minor;
+ int psy_alpha; /* 0 if not an alpha version */
+ int psy_beta; /* 0 if not a beta version */
+
+ /* compile time features */
+ const char *features; /* Don't make assumptions about the contents! */
+} lame_version_t;
+void CDECL get_lame_version_numerical(lame_version_t *);
+
+
+/*
+ * OPTIONAL:
+ * print internal lame configuration to message handler
+ */
+void CDECL lame_print_config(const lame_global_flags* gfp);
+
+void CDECL lame_print_internals( const lame_global_flags *gfp);
+
+
+/*
+ * input pcm data, output (maybe) mp3 frames.
+ * This routine handles all buffering, resampling and filtering for you.
+ *
+ * return code number of bytes output in mp3buf. Can be 0
+ * -1: mp3buf was too small
+ * -2: malloc() problem
+ * -3: lame_init_params() not called
+ * -4: psycho acoustic problems
+ *
+ * The required mp3buf_size can be computed from num_samples,
+ * samplerate and encoding rate, but here is a worst case estimate:
+ *
+ * mp3buf_size in bytes = 1.25*num_samples + 7200
+ *
+ * I think a tighter bound could be: (mt, March 2000)
+ * MPEG1:
+ * num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512
+ * MPEG2:
+ * num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256
+ *
+ * but test first if you use that!
+ *
+ * set mp3buf_size = 0 and LAME will not check if mp3buf_size is
+ * large enough.
+ *
+ * NOTE:
+ * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels
+ * will be averaged into the L channel before encoding only the L channel
+ * This will overwrite the data in buffer_l[] and buffer_r[].
+ *
+*/
+int CDECL lame_encode_buffer (
+ lame_global_flags* gfp, /* global context handle */
+ const short int buffer_l [], /* PCM data for left channel */
+ const short int buffer_r [], /* PCM data for right channel */
+ const int nsamples, /* number of samples per channel */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ const int mp3buf_size ); /* number of valid octets in this
+ stream */
+
+/*
+ * as above, but input has L & R channel data interleaved.
+ * NOTE:
+ * num_samples = number of samples in the L (or R)
+ * channel, not the total number of samples in pcm[]
+ */
+int CDECL lame_encode_buffer_interleaved(
+ lame_global_flags* gfp, /* global context handlei */
+ short int pcm[], /* PCM data for left and right
+ channel, interleaved */
+ int num_samples, /* number of samples per channel,
+ _not_ number of samples in
+ pcm[] */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ int mp3buf_size ); /* number of valid octets in this
+ stream */
+
+
+/* as lame_encode_buffer, but for 'float's.
+ * !! NOTE: !! data must still be scaled to be in the same range as
+ * short int, +/- 32768
+ */
+int CDECL lame_encode_buffer_float(
+ lame_global_flags* gfp, /* global context handle */
+ const float pcm_l [], /* PCM data for left channel */
+ const float pcm_r [], /* PCM data for right channel */
+ const int nsamples, /* number of samples per channel */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ const int mp3buf_size ); /* number of valid octets in this
+ stream */
+
+/* as lame_encode_buffer, but for 'float's.
+ * !! NOTE: !! data must be scaled to +/- 1 full scale
+ */
+int CDECL lame_encode_buffer_ieee_float(
+ lame_t gfp,
+ const float pcm_l [], /* PCM data for left channel */
+ const float pcm_r [], /* PCM data for right channel */
+ const int nsamples,
+ unsigned char * mp3buf,
+ const int mp3buf_size);
+int CDECL lame_encode_buffer_interleaved_ieee_float(
+ lame_t gfp,
+ const float pcm[], /* PCM data for left and right
+ channel, interleaved */
+ const int nsamples,
+ unsigned char * mp3buf,
+ const int mp3buf_size);
+
+/* as lame_encode_buffer, but for 'double's.
+ * !! NOTE: !! data must be scaled to +/- 1 full scale
+ */
+int CDECL lame_encode_buffer_ieee_double(
+ lame_t gfp,
+ const double pcm_l [], /* PCM data for left channel */
+ const double pcm_r [], /* PCM data for right channel */
+ const int nsamples,
+ unsigned char * mp3buf,
+ const int mp3buf_size);
+int CDECL lame_encode_buffer_interleaved_ieee_double(
+ lame_t gfp,
+ const double pcm[], /* PCM data for left and right
+ channel, interleaved */
+ const int nsamples,
+ unsigned char * mp3buf,
+ const int mp3buf_size);
+
+/* as lame_encode_buffer, but for long's
+ * !! NOTE: !! data must still be scaled to be in the same range as
+ * short int, +/- 32768
+ *
+ * This scaling was a mistake (doesn't allow one to exploit full
+ * precision of type 'long'. Use lame_encode_buffer_long2() instead.
+ *
+ */
+int CDECL lame_encode_buffer_long(
+ lame_global_flags* gfp, /* global context handle */
+ const long buffer_l [], /* PCM data for left channel */
+ const long buffer_r [], /* PCM data for right channel */
+ const int nsamples, /* number of samples per channel */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ const int mp3buf_size ); /* number of valid octets in this
+ stream */
+
+/* Same as lame_encode_buffer_long(), but with correct scaling.
+ * !! NOTE: !! data must still be scaled to be in the same range as
+ * type 'long'. Data should be in the range: +/- 2^(8*size(long)-1)
+ *
+ */
+int CDECL lame_encode_buffer_long2(
+ lame_global_flags* gfp, /* global context handle */
+ const long buffer_l [], /* PCM data for left channel */
+ const long buffer_r [], /* PCM data for right channel */
+ const int nsamples, /* number of samples per channel */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ const int mp3buf_size ); /* number of valid octets in this
+ stream */
+
+/* as lame_encode_buffer, but for int's
+ * !! NOTE: !! input should be scaled to the maximum range of 'int'
+ * If int is 4 bytes, then the values should range from
+ * +/- 2147483648.
+ *
+ * This routine does not (and cannot, without loosing precision) use
+ * the same scaling as the rest of the lame_encode_buffer() routines.
+ *
+ */
+int CDECL lame_encode_buffer_int(
+ lame_global_flags* gfp, /* global context handle */
+ const int buffer_l [], /* PCM data for left channel */
+ const int buffer_r [], /* PCM data for right channel */
+ const int nsamples, /* number of samples per channel */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ const int mp3buf_size ); /* number of valid octets in this
+ stream */
+
+/*
+ * as above, but for interleaved data.
+ * !! NOTE: !! data must still be scaled to be in the same range as
+ * type 'int32_t'. Data should be in the range: +/- 2^(8*size(int32_t)-1)
+ * NOTE:
+ * num_samples = number of samples in the L (or R)
+ * channel, not the total number of samples in pcm[]
+ */
+int
+lame_encode_buffer_interleaved_int(
+ lame_t gfp,
+ const int pcm [], /* PCM data for left and right
+ channel, interleaved */
+ const int nsamples, /* number of samples per channel,
+ _not_ number of samples in
+ pcm[] */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ const int mp3buf_size ); /* number of valid octets in this
+ stream */
+
+
+
+/*
+ * REQUIRED:
+ * lame_encode_flush will flush the intenal PCM buffers, padding with
+ * 0's to make sure the final frame is complete, and then flush
+ * the internal MP3 buffers, and thus may return a
+ * final few mp3 frames. 'mp3buf' should be at least 7200 bytes long
+ * to hold all possible emitted data.
+ *
+ * will also write id3v1 tags (if any) into the bitstream
+ *
+ * return code = number of bytes output to mp3buf. Can be 0
+ */
+int CDECL lame_encode_flush(
+ lame_global_flags * gfp, /* global context handle */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ int size); /* number of valid octets in this stream */
+
+/*
+ * OPTIONAL:
+ * lame_encode_flush_nogap will flush the internal mp3 buffers and pad
+ * the last frame with ancillary data so it is a complete mp3 frame.
+ *
+ * 'mp3buf' should be at least 7200 bytes long
+ * to hold all possible emitted data.
+ *
+ * After a call to this routine, the outputed mp3 data is complete, but
+ * you may continue to encode new PCM samples and write future mp3 data
+ * to a different file. The two mp3 files will play back with no gaps
+ * if they are concatenated together.
+ *
+ * This routine will NOT write id3v1 tags into the bitstream.
+ *
+ * return code = number of bytes output to mp3buf. Can be 0
+ */
+int CDECL lame_encode_flush_nogap(
+ lame_global_flags * gfp, /* global context handle */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ int size); /* number of valid octets in this stream */
+
+/*
+ * OPTIONAL:
+ * Normally, this is called by lame_init_params(). It writes id3v2 and
+ * Xing headers into the front of the bitstream, and sets frame counters
+ * and bitrate histogram data to 0. You can also call this after
+ * lame_encode_flush_nogap().
+ */
+int CDECL lame_init_bitstream(
+ lame_global_flags * gfp); /* global context handle */
+
+
+
+/*
+ * OPTIONAL: some simple statistics
+ * a bitrate histogram to visualize the distribution of used frame sizes
+ * a stereo mode histogram to visualize the distribution of used stereo
+ * modes, useful in joint-stereo mode only
+ * 0: LR left-right encoded
+ * 1: LR-I left-right and intensity encoded (currently not supported)
+ * 2: MS mid-side encoded
+ * 3: MS-I mid-side and intensity encoded (currently not supported)
+ *
+ * attention: don't call them after lame_encode_finish
+ * suggested: lame_encode_flush -> lame_*_hist -> lame_close
+ */
+
+void CDECL lame_bitrate_hist(
+ const lame_global_flags * gfp,
+ int bitrate_count[14] );
+void CDECL lame_bitrate_kbps(
+ const lame_global_flags * gfp,
+ int bitrate_kbps [14] );
+void CDECL lame_stereo_mode_hist(
+ const lame_global_flags * gfp,
+ int stereo_mode_count[4] );
+
+void CDECL lame_bitrate_stereo_mode_hist (
+ const lame_global_flags * gfp,
+ int bitrate_stmode_count[14][4] );
+
+void CDECL lame_block_type_hist (
+ const lame_global_flags * gfp,
+ int btype_count[6] );
+
+void CDECL lame_bitrate_block_type_hist (
+ const lame_global_flags * gfp,
+ int bitrate_btype_count[14][6] );
+
+#if (DEPRECATED_OR_OBSOLETE_CODE_REMOVED && 0)
+#else
+/*
+ * OPTIONAL:
+ * lame_mp3_tags_fid will rewrite a Xing VBR tag to the mp3 file with file
+ * pointer fid. These calls perform forward and backwards seeks, so make
+ * sure fid is a real file. Make sure lame_encode_flush has been called,
+ * and all mp3 data has been written to the file before calling this
+ * function.
+ * NOTE:
+ * if VBR tags are turned off by the user, or turned off by LAME because
+ * the output is not a regular file, this call does nothing
+ * NOTE:
+ * LAME wants to read from the file to skip an optional ID3v2 tag, so
+ * make sure you opened the file for writing and reading.
+ * NOTE:
+ * You can call lame_get_lametag_frame instead, if you want to insert
+ * the lametag yourself.
+*/
+void CDECL lame_mp3_tags_fid(lame_global_flags *, FILE* fid);
+#endif
+
+/*
+ * OPTIONAL:
+ * lame_get_lametag_frame copies the final LAME-tag into 'buffer'.
+ * The function returns the number of bytes copied into buffer, or
+ * the required buffer size, if the provided buffer is too small.
+ * Function failed, if the return value is larger than 'size'!
+ * Make sure lame_encode flush has been called before calling this function.
+ * NOTE:
+ * if VBR tags are turned off by the user, or turned off by LAME,
+ * this call does nothing and returns 0.
+ * NOTE:
+ * LAME inserted an empty frame in the beginning of mp3 audio data,
+ * which you have to replace by the final LAME-tag frame after encoding.
+ * In case there is no ID3v2 tag, usually this frame will be the very first
+ * data in your mp3 file. If you put some other leading data into your
+ * file, you'll have to do some bookkeeping about where to write this buffer.
+ */
+size_t CDECL lame_get_lametag_frame(
+ const lame_global_flags *, unsigned char* buffer, size_t size);
+
+/*
+ * REQUIRED:
+ * final call to free all remaining buffers
+ */
+int CDECL lame_close (lame_global_flags *);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/*
+ * OBSOLETE:
+ * lame_encode_finish combines lame_encode_flush() and lame_close() in
+ * one call. However, once this call is made, the statistics routines
+ * will no longer work because the data will have been cleared, and
+ * lame_mp3_tags_fid() cannot be called to add data to the VBR header
+ */
+int CDECL lame_encode_finish(
+ lame_global_flags* gfp,
+ unsigned char* mp3buf,
+ int size );
+#endif
+
+
+
+
+
+
+/*********************************************************************
+ *
+ * decoding
+ *
+ * a simple interface to mpglib, part of mpg123, is also included if
+ * libmp3lame is compiled with HAVE_MPGLIB
+ *
+ *********************************************************************/
+
+struct hip_global_struct;
+typedef struct hip_global_struct hip_global_flags;
+typedef hip_global_flags *hip_t;
+
+
+typedef struct {
+ int header_parsed; /* 1 if header was parsed and following data was
+ computed */
+ int stereo; /* number of channels */
+ int samplerate; /* sample rate */
+ int bitrate; /* bitrate */
+ int mode; /* mp3 frame type */
+ int mode_ext; /* mp3 frame type */
+ int framesize; /* number of samples per mp3 frame */
+
+ /* this data is only computed if mpglib detects a Xing VBR header */
+ unsigned long nsamp; /* number of samples in mp3 file. */
+ int totalframes; /* total number of frames in mp3 file */
+
+ /* this data is not currently computed by the mpglib routines */
+ int framenum; /* frames decoded counter */
+} mp3data_struct;
+
+/* required call to initialize decoder */
+hip_t CDECL hip_decode_init(void);
+
+/* cleanup call to exit decoder */
+int CDECL hip_decode_exit(hip_t gfp);
+
+/* HIP reporting functions */
+void CDECL hip_set_errorf(hip_t gfp, lame_report_function f);
+void CDECL hip_set_debugf(hip_t gfp, lame_report_function f);
+void CDECL hip_set_msgf (hip_t gfp, lame_report_function f);
+
+/*********************************************************************
+ * input 1 mp3 frame, output (maybe) pcm data.
+ *
+ * nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r);
+ *
+ * input:
+ * len : number of bytes of mp3 data in mp3buf
+ * mp3buf[len] : mp3 data to be decoded
+ *
+ * output:
+ * nout: -1 : decoding error
+ * 0 : need more data before we can complete the decode
+ * >0 : returned 'nout' samples worth of data in pcm_l,pcm_r
+ * pcm_l[nout] : left channel data
+ * pcm_r[nout] : right channel data
+ *
+ *********************************************************************/
+int CDECL hip_decode( hip_t gfp
+ , unsigned char * mp3buf
+ , size_t len
+ , short pcm_l[]
+ , short pcm_r[]
+ );
+
+/* same as hip_decode, and also returns mp3 header data */
+int CDECL hip_decode_headers( hip_t gfp
+ , unsigned char* mp3buf
+ , size_t len
+ , short pcm_l[]
+ , short pcm_r[]
+ , mp3data_struct* mp3data
+ );
+
+/* same as hip_decode, but returns at most one frame */
+int CDECL hip_decode1( hip_t gfp
+ , unsigned char* mp3buf
+ , size_t len
+ , short pcm_l[]
+ , short pcm_r[]
+ );
+
+/* same as hip_decode1, but returns at most one frame and mp3 header data */
+int CDECL hip_decode1_headers( hip_t gfp
+ , unsigned char* mp3buf
+ , size_t len
+ , short pcm_l[]
+ , short pcm_r[]
+ , mp3data_struct* mp3data
+ );
+
+/* same as hip_decode1_headers, but also returns enc_delay and enc_padding
+ from VBR Info tag, (-1 if no info tag was found) */
+int CDECL hip_decode1_headersB( hip_t gfp
+ , unsigned char* mp3buf
+ , size_t len
+ , short pcm_l[]
+ , short pcm_r[]
+ , mp3data_struct* mp3data
+ , int *enc_delay
+ , int *enc_padding
+ );
+
+
+
+/* OBSOLETE:
+ * lame_decode... functions are there to keep old code working
+ * but it is strongly recommended to replace calls by hip_decode...
+ * function calls, see above.
+ */
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+int CDECL lame_decode_init(void);
+int CDECL lame_decode(
+ unsigned char * mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[] );
+int CDECL lame_decode_headers(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[],
+ mp3data_struct* mp3data );
+int CDECL lame_decode1(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[] );
+int CDECL lame_decode1_headers(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[],
+ mp3data_struct* mp3data );
+int CDECL lame_decode1_headersB(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[],
+ mp3data_struct* mp3data,
+ int *enc_delay,
+ int *enc_padding );
+int CDECL lame_decode_exit(void);
+
+#endif /* obsolete lame_decode API calls */
+
+
+/*********************************************************************
+ *
+ * id3tag stuff
+ *
+ *********************************************************************/
+
+/*
+ * id3tag.h -- Interface to write ID3 version 1 and 2 tags.
+ *
+ * Copyright (C) 2000 Don Melton.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* utility to obtain alphabetically sorted list of genre names with numbers */
+void CDECL id3tag_genre_list(
+ void (*handler)(int, const char *, void *),
+ void* cookie);
+
+void CDECL id3tag_init (lame_t gfp);
+
+/* force addition of version 2 tag */
+void CDECL id3tag_add_v2 (lame_t gfp);
+
+/* add only a version 1 tag */
+void CDECL id3tag_v1_only (lame_t gfp);
+
+/* add only a version 2 tag */
+void CDECL id3tag_v2_only (lame_t gfp);
+
+/* pad version 1 tag with spaces instead of nulls */
+void CDECL id3tag_space_v1 (lame_t gfp);
+
+/* pad version 2 tag with extra 128 bytes */
+void CDECL id3tag_pad_v2 (lame_t gfp);
+
+/* pad version 2 tag with extra n bytes */
+void CDECL id3tag_set_pad (lame_t gfp, size_t n);
+
+void CDECL id3tag_set_title(lame_t gfp, const char* title);
+void CDECL id3tag_set_artist(lame_t gfp, const char* artist);
+void CDECL id3tag_set_album(lame_t gfp, const char* album);
+void CDECL id3tag_set_year(lame_t gfp, const char* year);
+void CDECL id3tag_set_comment(lame_t gfp, const char* comment);
+
+/* return -1 result if track number is out of ID3v1 range
+ and ignored for ID3v1 */
+int CDECL id3tag_set_track(lame_t gfp, const char* track);
+
+/* return non-zero result if genre name or number is invalid
+ result 0: OK
+ result -1: genre number out of range
+ result -2: no valid ID3v1 genre name, mapped to ID3v1 'Other'
+ but taken as-is for ID3v2 genre tag */
+int CDECL id3tag_set_genre(lame_t gfp, const char* genre);
+
+/* return non-zero result if field name is invalid */
+int CDECL id3tag_set_fieldvalue(lame_t gfp, const char* fieldvalue);
+
+/* return non-zero result if image type is invalid */
+int CDECL id3tag_set_albumart(lame_t gfp, const char* image, size_t size);
+
+/* lame_get_id3v1_tag copies ID3v1 tag into buffer.
+ * Function returns number of bytes copied into buffer, or number
+ * of bytes rquired if buffer 'size' is too small.
+ * Function fails, if returned value is larger than 'size'.
+ * NOTE:
+ * This functions does nothing, if user/LAME disabled ID3v1 tag.
+ */
+size_t CDECL lame_get_id3v1_tag(lame_t gfp, unsigned char* buffer, size_t size);
+
+/* lame_get_id3v2_tag copies ID3v2 tag into buffer.
+ * Function returns number of bytes copied into buffer, or number
+ * of bytes rquired if buffer 'size' is too small.
+ * Function fails, if returned value is larger than 'size'.
+ * NOTE:
+ * This functions does nothing, if user/LAME disabled ID3v2 tag.
+ */
+size_t CDECL lame_get_id3v2_tag(lame_t gfp, unsigned char* buffer, size_t size);
+
+/* normaly lame_init_param writes ID3v2 tags into the audio stream
+ * Call lame_set_write_id3tag_automatic(gfp, 0) before lame_init_param
+ * to turn off this behaviour and get ID3v2 tag with above function
+ * write it yourself into your file.
+ */
+void CDECL lame_set_write_id3tag_automatic(lame_global_flags * gfp, int);
+int CDECL lame_get_write_id3tag_automatic(lame_global_flags const* gfp);
+
+/* experimental */
+int CDECL id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text);
+
+/* experimental */
+int CDECL id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text);
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+#else
+/* experimental */
+int CDECL id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text);
+
+/* experimental */
+int CDECL id3tag_set_comment_ucs2(lame_t gfp, char const *lang,
+ unsigned short const *desc, unsigned short const *text);
+
+/* experimental */
+int CDECL id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue);
+#endif
+
+/* experimental */
+int CDECL id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue);
+
+/* experimental */
+int CDECL id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text);
+
+/* experimental */
+int CDECL id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text);
+
+
+/***********************************************************************
+*
+* list of valid bitrates [kbps] & sample frequencies [Hz].
+* first index: 0: MPEG-2 values (sample frequencies 16...24 kHz)
+* 1: MPEG-1 values (sample frequencies 32...48 kHz)
+* 2: MPEG-2.5 values (sample frequencies 8...12 kHz)
+***********************************************************************/
+
+extern const int bitrate_table [3][16];
+extern const int samplerate_table [3][ 4];
+
+/* access functions for use in DLL, global vars are not exported */
+int CDECL lame_get_bitrate(int mpeg_version, int table_index);
+int CDECL lame_get_samplerate(int mpeg_version, int table_index);
+
+
+/* maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER
+ as well since lame_encode_buffer() also returns ID3v2 tag data */
+#define LAME_MAXALBUMART (128 * 1024)
+
+/* maximum size of mp3buffer needed if you encode at most 1152 samples for
+ each call to lame_encode_buffer. see lame_encode_buffer() below
+ (LAME_MAXMP3BUFFER is now obsolete) */
+#define LAME_MAXMP3BUFFER (16384 + LAME_MAXALBUMART)
+
+
+typedef enum {
+ LAME_OKAY = 0,
+ LAME_NOERROR = 0,
+ LAME_GENERICERROR = -1,
+ LAME_NOMEM = -10,
+ LAME_BADBITRATE = -11,
+ LAME_BADSAMPFREQ = -12,
+ LAME_INTERNALERROR = -13,
+
+ FRONTEND_READERROR = -80,
+ FRONTEND_WRITEERROR = -81,
+ FRONTEND_FILETOOLARGE = -82
+
+} lame_errorcodes_t;
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* LAME_LAME_H */
+
diff --git a/pkg/lame/clame/lame_global_flags.h b/pkg/lame/clame/lame_global_flags.h
new file mode 100644
index 0000000..ad9e677
--- /dev/null
+++ b/pkg/lame/clame/lame_global_flags.h
@@ -0,0 +1,184 @@
+#ifndef LAME_GLOBAL_FLAGS_H
+#define LAME_GLOBAL_FLAGS_H
+
+#ifndef lame_internal_flags_defined
+#define lame_internal_flags_defined
+struct lame_internal_flags;
+typedef struct lame_internal_flags lame_internal_flags;
+#endif
+
+
+typedef enum short_block_e {
+ short_block_not_set = -1, /* allow LAME to decide */
+ short_block_allowed = 0, /* LAME may use them, even different block types for L/R */
+ short_block_coupled, /* LAME may use them, but always same block types in L/R */
+ short_block_dispensed, /* LAME will not use short blocks, long blocks only */
+ short_block_forced /* LAME will not use long blocks, short blocks only */
+} short_block_t;
+
+/***********************************************************************
+*
+* Control Parameters set by User. These parameters are here for
+* backwards compatibility with the old, non-shared lib API.
+* Please use the lame_set_variablename() functions below
+*
+*
+***********************************************************************/
+struct lame_global_struct {
+ unsigned int class_id;
+
+ /* input description */
+ unsigned long num_samples; /* number of samples. default=2^32-1 */
+ int num_channels; /* input number of channels. default=2 */
+ int samplerate_in; /* input_samp_rate in Hz. default=44.1 kHz */
+ int samplerate_out; /* output_samp_rate.
+ default: LAME picks best value
+ at least not used for MP3 decoding:
+ Remember 44.1 kHz MP3s and AC97 */
+ float scale; /* scale input by this amount before encoding
+ at least not used for MP3 decoding */
+ float scale_left; /* scale input of channel 0 (left) by this
+ amount before encoding */
+ float scale_right; /* scale input of channel 1 (right) by this
+ amount before encoding */
+
+ /* general control params */
+ int analysis; /* collect data for a MP3 frame analyzer? */
+ int write_lame_tag; /* add Xing VBR tag? */
+ int decode_only; /* use lame/mpglib to convert mp3 to wav */
+ int quality; /* quality setting 0=best, 9=worst default=5 */
+ MPEG_mode mode; /* see enum in lame.h
+ default = LAME picks best value */
+ int force_ms; /* force M/S mode. requires mode=1 */
+ int free_format; /* use free format? default=0 */
+ int findReplayGain; /* find the RG value? default=0 */
+ int decode_on_the_fly; /* decode on the fly? default=0 */
+ int write_id3tag_automatic; /* 1 (default) writes ID3 tags, 0 not */
+
+ int nogap_total;
+ int nogap_current;
+
+ int substep_shaping;
+ int noise_shaping;
+ int subblock_gain; /* 0 = no, 1 = yes */
+ int use_best_huffman; /* 0 = no. 1=outside loop 2=inside loop(slow) */
+
+ /*
+ * set either brate>0 or compression_ratio>0, LAME will compute
+ * the value of the variable not set.
+ * Default is compression_ratio = 11.025
+ */
+ int brate; /* bitrate */
+ float compression_ratio; /* sizeof(wav file)/sizeof(mp3 file) */
+
+
+ /* frame params */
+ int copyright; /* mark as copyright. default=0 */
+ int original; /* mark as original. default=1 */
+ int extension; /* the MP3 'private extension' bit.
+ Meaningless */
+ int emphasis; /* Input PCM is emphased PCM (for
+ instance from one of the rarely
+ emphased CDs), it is STRONGLY not
+ recommended to use this, because
+ psycho does not take it into account,
+ and last but not least many decoders
+ don't care about these bits */
+ int error_protection; /* use 2 bytes per frame for a CRC
+ checksum. default=0 */
+ int strict_ISO; /* enforce ISO spec as much as possible */
+
+ int disable_reservoir; /* use bit reservoir? */
+
+ /* quantization/noise shaping */
+ int quant_comp;
+ int quant_comp_short;
+ int experimentalY;
+ int experimentalZ;
+ int exp_nspsytune;
+
+ int preset;
+
+ /* VBR control */
+ vbr_mode VBR;
+ float VBR_q_frac; /* Range [0,...,1[ */
+ int VBR_q; /* Range [0,...,9] */
+ int VBR_mean_bitrate_kbps;
+ int VBR_min_bitrate_kbps;
+ int VBR_max_bitrate_kbps;
+ int VBR_hard_min; /* strictly enforce VBR_min_bitrate
+ normaly, it will be violated for analog
+ silence */
+
+
+ /* resampling and filtering */
+ int lowpassfreq; /* freq in Hz. 0=lame choses.
+ -1=no filter */
+ int highpassfreq; /* freq in Hz. 0=lame choses.
+ -1=no filter */
+ int lowpasswidth; /* freq width of filter, in Hz
+ (default=15%) */
+ int highpasswidth; /* freq width of filter, in Hz
+ (default=15%) */
+
+
+
+ /*
+ * psycho acoustics and other arguments which you should not change
+ * unless you know what you are doing
+ */
+ float maskingadjust;
+ float maskingadjust_short;
+ int ATHonly; /* only use ATH */
+ int ATHshort; /* only use ATH for short blocks */
+ int noATH; /* disable ATH */
+ int ATHtype; /* select ATH formula */
+ float ATHcurve; /* change ATH formula 4 shape */
+ float ATH_lower_db; /* lower ATH by this many db */
+ int athaa_type; /* select ATH auto-adjust scheme */
+ float athaa_sensitivity; /* dB, tune active region of auto-level */
+ short_block_t short_blocks;
+ int useTemporal; /* use temporal masking effect */
+ float interChRatio;
+ float msfix; /* Naoki's adjustment of Mid/Side maskings */
+
+ int tune; /* 0 off, 1 on */
+ float tune_value_a; /* used to pass values for debugging and stuff */
+
+ float attackthre; /* attack threshold for L/R/M channel */
+ float attackthre_s; /* attack threshold for S channel */
+
+
+ struct {
+ void (*msgf) (const char *format, va_list ap);
+ void (*debugf) (const char *format, va_list ap);
+ void (*errorf) (const char *format, va_list ap);
+ } report;
+
+ /************************************************************************/
+ /* internal variables, do not set... */
+ /* provided because they may be of use to calling application */
+ /************************************************************************/
+
+ int lame_allocated_gfp; /* is this struct owned by calling
+ program or lame? */
+
+
+
+ /**************************************************************************/
+ /* more internal variables are stored in this structure: */
+ /**************************************************************************/
+ lame_internal_flags *internal_flags;
+
+
+ struct {
+ int mmx;
+ int amd3dnow;
+ int sse;
+
+ } asm_optimizations;
+};
+
+int is_lame_global_flags_valid(const lame_global_flags * gfp);
+
+#endif /* LAME_GLOBAL_FLAGS_H */
diff --git a/pkg/lame/clame/lame_intrin.h b/pkg/lame/clame/lame_intrin.h
new file mode 100644
index 0000000..bc4c189
--- /dev/null
+++ b/pkg/lame/clame/lame_intrin.h
@@ -0,0 +1,33 @@
+/*
+ * lame_intrin.h include file
+ *
+ * Copyright (c) 2006 Gabriel Bouvigne
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef LAME_INTRIN_H
+#define LAME_INTRIN_H
+
+
+void
+init_xrpow_core_sse(gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum);
+
+void
+fht_SSE2(FLOAT* , int);
+
+#endif
diff --git a/pkg/lame/clame/machine.h b/pkg/lame/clame/machine.h
new file mode 100644
index 0000000..bf6fff2
--- /dev/null
+++ b/pkg/lame/clame/machine.h
@@ -0,0 +1,189 @@
+/*
+ * Machine dependent defines/includes for LAME.
+ *
+ * Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_MACHINE_H
+#define LAME_MACHINE_H
+
+#include "version.h"
+
+#include
+#include
+
+#ifdef STDC_HEADERS
+# include
+# include
+#else
+# ifndef HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr(), *strrchr();
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(__riscos__) && defined(FPA10)
+# include "ymath.h"
+#else
+# include
+#endif
+#include
+
+#include
+
+#ifdef HAVE_ERRNO_H
+# include
+#endif
+#ifdef HAVE_FCNTL_H
+# include
+#endif
+
+#if defined(macintosh)
+# include
+# include
+#else
+# include
+# include
+#endif
+
+#ifdef HAVE_INTTYPES_H
+# include
+#else
+# ifdef HAVE_STDINT_H
+# include
+# endif
+#endif
+
+#ifdef WITH_DMALLOC
+#include
+#endif
+
+/*
+ * 3 different types of pow() functions:
+ * - table lookup
+ * - pow()
+ * - exp() on some machines this is claimed to be faster than pow()
+ */
+
+#define POW20(x) (assert(0 <= (x+Q_MAX2) && x < Q_MAX), pow20[x+Q_MAX2])
+/*#define POW20(x) pow(2.0,((double)(x)-210)*.25) */
+/*#define POW20(x) exp( ((double)(x)-210)*(.25*LOG2) ) */
+
+#define IPOW20(x) (assert(0 <= x && x < Q_MAX), ipow20[x])
+/*#define IPOW20(x) exp( -((double)(x)-210)*.1875*LOG2 ) */
+/*#define IPOW20(x) pow(2.0,-((double)(x)-210)*.1875) */
+
+/* in case this is used without configure */
+#ifndef inline
+# define inline
+#endif
+
+#if defined(_MSC_VER)
+# undef inline
+# define inline _inline
+#elif defined(__SASC) || defined(__GNUC__) || defined(__ICC) || defined(__ECC)
+/* if __GNUC__ we always want to inline, not only if the user requests it */
+# undef inline
+# define inline __inline
+#endif
+
+#if defined(_MSC_VER)
+# pragma warning( disable : 4244 )
+/*# pragma warning( disable : 4305 ) */
+#endif
+
+/*
+ * FLOAT for variables which require at least 32 bits
+ * FLOAT8 for variables which require at least 64 bits
+ *
+ * On some machines, 64 bit will be faster than 32 bit. Also, some math
+ * routines require 64 bit float, so setting FLOAT=float will result in a
+ * lot of conversions.
+ */
+
+#if ( defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) )
+# define WIN32_LEAN_AND_MEAN
+# include
+# include
+# define FLOAT_MAX FLT_MAX
+#else
+# ifndef FLOAT
+typedef float FLOAT;
+# ifdef FLT_MAX
+# define FLOAT_MAX FLT_MAX
+# else
+# define FLOAT_MAX 1e37 /* approx */
+# endif
+# endif
+#endif
+
+#ifndef FLOAT8
+typedef double FLOAT8;
+# ifdef DBL_MAX
+# define FLOAT8_MAX DBL_MAX
+# else
+# define FLOAT8_MAX 1e99 /* approx */
+# endif
+#else
+# ifdef FLT_MAX
+# define FLOAT8_MAX FLT_MAX
+# else
+# define FLOAT8_MAX 1e37 /* approx */
+# endif
+#endif
+
+/* sample_t must be floating point, at least 32 bits */
+typedef FLOAT sample_t;
+
+#define dimension_of(array) (sizeof(array)/sizeof(array[0]))
+#define beyond(array) (array+dimension_of(array))
+#define compiletime_assert(expression) enum{static_assert_##FILE##_##LINE = 1/((expression)?1:0)}
+#define lame_calloc(TYPE, COUNT) ((TYPE*)calloc(COUNT, sizeof(TYPE)))
+#define multiple_of(CHUNK, COUNT) (\
+ ( (COUNT) < 1 || (CHUNK) < 1 || (COUNT) % (CHUNK) == 0 ) \
+ ? (COUNT) \
+ : ((COUNT) + (CHUNK) - (COUNT) % (CHUNK)) \
+ )
+
+#if 1
+#define EQ(a,b) (\
+(fabs(a) > fabs(b)) \
+ ? (fabs((a)-(b)) <= (fabs(a) * 1e-6f)) \
+ : (fabs((a)-(b)) <= (fabs(b) * 1e-6f)))
+#else
+#define EQ(a,b) (fabs((a)-(b))<1E-37)
+#endif
+
+#define NEQ(a,b) (!EQ(a,b))
+
+#ifdef _MSC_VER
+# if _MSC_VER < 1400
+# define fabsf fabs
+# define powf pow
+# define log10f log10
+# endif
+#endif
+
+#endif
+
+/* end of machine.h */
diff --git a/pkg/lame/clame/mpglib_interface.c b/pkg/lame/clame/mpglib_interface.c
new file mode 100644
index 0000000..d0f0b1d
--- /dev/null
+++ b/pkg/lame/clame/mpglib_interface.c
@@ -0,0 +1,477 @@
+/* -*- mode: C; mode: fold -*- */
+/*
+ * LAME MP3 encoding engine
+ *
+ * Copyright (c) 1999-2000 Mark Taylor
+ * Copyright (c) 2003 Olcios
+ * Copyright (c) 2008 Robert Hegemann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: mpglib_interface.c,v 1.44 2012/02/18 13:09:00 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#ifdef HAVE_MPGLIB
+#define hip_global_struct mpstr_tag
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "interface.h"
+
+#include "util.h"
+
+
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+/*
+ * OBSOLETE:
+ * - kept to let it link
+ * - forward declaration to silence compiler
+ */
+int CDECL lame_decode_init(void);
+int CDECL lame_decode(
+ unsigned char * mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[] );
+int CDECL lame_decode_headers(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[],
+ mp3data_struct* mp3data );
+int CDECL lame_decode1(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[] );
+int CDECL lame_decode1_headers(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[],
+ mp3data_struct* mp3data );
+int CDECL lame_decode1_headersB(
+ unsigned char* mp3buf,
+ int len,
+ short pcm_l[],
+ short pcm_r[],
+ mp3data_struct* mp3data,
+ int *enc_delay,
+ int *enc_padding );
+int CDECL lame_decode_exit(void);
+#endif
+
+
+static MPSTR mp;
+
+int
+lame_decode_exit(void)
+{
+ ExitMP3(&mp);
+ return 0;
+}
+
+
+int
+lame_decode_init(void)
+{
+ (void) InitMP3(&mp);
+ return 0;
+}
+
+
+
+
+/* copy mono samples */
+#define COPY_MONO(DST_TYPE, SRC_TYPE) \
+ DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw; \
+ SRC_TYPE const *p_samples = (SRC_TYPE const *)p; \
+ for (i = 0; i < processed_samples; i++) \
+ *pcm_l++ = (DST_TYPE)(*p_samples++);
+
+/* copy stereo samples */
+#define COPY_STEREO(DST_TYPE, SRC_TYPE) \
+ DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw, *pcm_r = (DST_TYPE *)pcm_r_raw; \
+ SRC_TYPE const *p_samples = (SRC_TYPE const *)p; \
+ for (i = 0; i < processed_samples; i++) { \
+ *pcm_l++ = (DST_TYPE)(*p_samples++); \
+ *pcm_r++ = (DST_TYPE)(*p_samples++); \
+ }
+
+
+
+/*
+ * For lame_decode: return code
+ * -1 error
+ * 0 ok, but need more data before outputing any samples
+ * n number of samples output. either 576 or 1152 depending on MP3 file.
+ */
+
+static int
+decode1_headersB_clipchoice(PMPSTR pmp, unsigned char *buffer, size_t len,
+ char pcm_l_raw[], char pcm_r_raw[], mp3data_struct * mp3data,
+ int *enc_delay, int *enc_padding,
+ char *p, size_t psize, int decoded_sample_size,
+ int (*decodeMP3_ptr) (PMPSTR, unsigned char *, int, char *, int,
+ int *))
+{
+ static const int smpls[2][4] = {
+ /* Layer I II III */
+ {0, 384, 1152, 1152}, /* MPEG-1 */
+ {0, 384, 1152, 576} /* MPEG-2(.5) */
+ };
+
+ int processed_bytes;
+ int processed_samples; /* processed samples per channel */
+ int ret;
+ int i;
+ int const len_l = len < INT_MAX ? (int) len : INT_MAX;
+ int const psize_l = psize < INT_MAX ? (int) psize : INT_MAX;
+
+ mp3data->header_parsed = 0;
+ ret = (*decodeMP3_ptr) (pmp, buffer, len_l, p, psize_l, &processed_bytes);
+ /* three cases:
+ * 1. headers parsed, but data not complete
+ * pmp->header_parsed==1
+ * pmp->framesize=0
+ * pmp->fsizeold=size of last frame, or 0 if this is first frame
+ *
+ * 2. headers, data parsed, but ancillary data not complete
+ * pmp->header_parsed==1
+ * pmp->framesize=size of frame
+ * pmp->fsizeold=size of last frame, or 0 if this is first frame
+ *
+ * 3. frame fully decoded:
+ * pmp->header_parsed==0
+ * pmp->framesize=0
+ * pmp->fsizeold=size of frame (which is now the last frame)
+ *
+ */
+ if (pmp->header_parsed || pmp->fsizeold > 0 || pmp->framesize > 0) {
+ mp3data->header_parsed = 1;
+ mp3data->stereo = pmp->fr.stereo;
+ mp3data->samplerate = freqs[pmp->fr.sampling_frequency];
+ mp3data->mode = pmp->fr.mode;
+ mp3data->mode_ext = pmp->fr.mode_ext;
+ mp3data->framesize = smpls[pmp->fr.lsf][pmp->fr.lay];
+
+ /* free format, we need the entire frame before we can determine
+ * the bitrate. If we haven't gotten the entire frame, bitrate=0 */
+ if (pmp->fsizeold > 0) /* works for free format and fixed, no overrun, temporal results are < 400.e6 */
+ mp3data->bitrate = 8 * (4 + pmp->fsizeold) * mp3data->samplerate /
+ (1.e3 * mp3data->framesize) + 0.5;
+ else if (pmp->framesize > 0)
+ mp3data->bitrate = 8 * (4 + pmp->framesize) * mp3data->samplerate /
+ (1.e3 * mp3data->framesize) + 0.5;
+ else
+ mp3data->bitrate = tabsel_123[pmp->fr.lsf][pmp->fr.lay - 1][pmp->fr.bitrate_index];
+
+
+
+ if (pmp->num_frames > 0) {
+ /* Xing VBR header found and num_frames was set */
+ mp3data->totalframes = pmp->num_frames;
+ mp3data->nsamp = mp3data->framesize * pmp->num_frames;
+ *enc_delay = pmp->enc_delay;
+ *enc_padding = pmp->enc_padding;
+ }
+ }
+
+ switch (ret) {
+ case MP3_OK:
+ switch (pmp->fr.stereo) {
+ case 1:
+ processed_samples = processed_bytes / decoded_sample_size;
+ if (decoded_sample_size == sizeof(short)) {
+ COPY_MONO(short, short)
+ }
+ else {
+ COPY_MONO(sample_t, FLOAT)
+ }
+ break;
+ case 2:
+ processed_samples = (processed_bytes / decoded_sample_size) >> 1;
+ if (decoded_sample_size == sizeof(short)) {
+ COPY_STEREO(short, short)
+ }
+ else {
+ COPY_STEREO(sample_t, FLOAT)
+ }
+ break;
+ default:
+ processed_samples = -1;
+ assert(0);
+ break;
+ }
+ break;
+
+ case MP3_NEED_MORE:
+ processed_samples = 0;
+ break;
+
+ case MP3_ERR:
+ processed_samples = -1;
+ break;
+
+ default:
+ processed_samples = -1;
+ assert(0);
+ break;
+ }
+
+ /*fprintf(stderr,"ok, more, err: %i %i %i\n", MP3_OK, MP3_NEED_MORE, MP3_ERR ); */
+ /*fprintf(stderr,"ret = %i out=%i\n", ret, processed_samples ); */
+ return processed_samples;
+}
+
+
+#define OUTSIZE_CLIPPED (4096*sizeof(short))
+
+int
+lame_decode1_headersB(unsigned char *buffer,
+ int len,
+ short pcm_l[], short pcm_r[], mp3data_struct * mp3data,
+ int *enc_delay, int *enc_padding)
+{
+ static char out[OUTSIZE_CLIPPED];
+
+ return decode1_headersB_clipchoice(&mp, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data,
+ enc_delay, enc_padding, out, OUTSIZE_CLIPPED,
+ sizeof(short), decodeMP3);
+}
+
+
+
+
+
+/*
+ * For lame_decode: return code
+ * -1 error
+ * 0 ok, but need more data before outputing any samples
+ * n number of samples output. Will be at most one frame of
+ * MPEG data.
+ */
+
+int
+lame_decode1_headers(unsigned char *buffer,
+ int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
+{
+ int enc_delay, enc_padding;
+ return lame_decode1_headersB(buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding);
+}
+
+
+int
+lame_decode1(unsigned char *buffer, int len, short pcm_l[], short pcm_r[])
+{
+ mp3data_struct mp3data;
+
+ return lame_decode1_headers(buffer, len, pcm_l, pcm_r, &mp3data);
+}
+
+
+/*
+ * For lame_decode: return code
+ * -1 error
+ * 0 ok, but need more data before outputing any samples
+ * n number of samples output. a multiple of 576 or 1152 depending on MP3 file.
+ */
+
+int
+lame_decode_headers(unsigned char *buffer,
+ int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
+{
+ int ret;
+ int totsize = 0; /* number of decoded samples per channel */
+
+ for (;;) {
+ switch (ret = lame_decode1_headers(buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) {
+ case -1:
+ return ret;
+ case 0:
+ return totsize;
+ default:
+ totsize += ret;
+ len = 0; /* future calls to decodeMP3 are just to flush buffers */
+ break;
+ }
+ }
+}
+
+
+int
+lame_decode(unsigned char *buffer, int len, short pcm_l[], short pcm_r[])
+{
+ mp3data_struct mp3data;
+
+ return lame_decode_headers(buffer, len, pcm_l, pcm_r, &mp3data);
+}
+
+
+
+
+hip_t hip_decode_init(void)
+{
+ hip_t hip = lame_calloc(hip_global_flags, 1);
+ InitMP3(hip);
+ return hip;
+}
+
+
+int hip_decode_exit(hip_t hip)
+{
+ if (hip) {
+ ExitMP3(hip);
+ free(hip);
+ }
+ return 0;
+}
+
+
+/* we forbid input with more than 1152 samples per channel for output in the unclipped mode */
+#define OUTSIZE_UNCLIPPED (1152*2*sizeof(FLOAT))
+
+int
+hip_decode1_unclipped(hip_t hip, unsigned char *buffer, size_t len, sample_t pcm_l[], sample_t pcm_r[])
+{
+ static char out[OUTSIZE_UNCLIPPED];
+ mp3data_struct mp3data;
+ int enc_delay, enc_padding;
+
+ if (hip) {
+ return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, &mp3data,
+ &enc_delay, &enc_padding, out, OUTSIZE_UNCLIPPED,
+ sizeof(FLOAT), decodeMP3_unclipped);
+ }
+ return 0;
+}
+
+/*
+ * For hip_decode: return code
+ * -1 error
+ * 0 ok, but need more data before outputing any samples
+ * n number of samples output. Will be at most one frame of
+ * MPEG data.
+ */
+
+int
+hip_decode1_headers(hip_t hip, unsigned char *buffer,
+ size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
+{
+ int enc_delay, enc_padding;
+ return hip_decode1_headersB(hip, buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding);
+}
+
+
+int
+hip_decode1(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[])
+{
+ mp3data_struct mp3data;
+ return hip_decode1_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data);
+}
+
+
+/*
+ * For hip_decode: return code
+ * -1 error
+ * 0 ok, but need more data before outputing any samples
+ * n number of samples output. a multiple of 576 or 1152 depending on MP3 file.
+ */
+
+int
+hip_decode_headers(hip_t hip, unsigned char *buffer,
+ size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)
+{
+ int ret;
+ int totsize = 0; /* number of decoded samples per channel */
+
+ for (;;) {
+ switch (ret = hip_decode1_headers(hip, buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) {
+ case -1:
+ return ret;
+ case 0:
+ return totsize;
+ default:
+ totsize += ret;
+ len = 0; /* future calls to decodeMP3 are just to flush buffers */
+ break;
+ }
+ }
+}
+
+
+int
+hip_decode(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[])
+{
+ mp3data_struct mp3data;
+ return hip_decode_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data);
+}
+
+
+int
+hip_decode1_headersB(hip_t hip, unsigned char *buffer,
+ size_t len,
+ short pcm_l[], short pcm_r[], mp3data_struct * mp3data,
+ int *enc_delay, int *enc_padding)
+{
+ static char out[OUTSIZE_CLIPPED];
+ if (hip) {
+ return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data,
+ enc_delay, enc_padding, out, OUTSIZE_CLIPPED,
+ sizeof(short), decodeMP3);
+ }
+ return -1;
+}
+
+
+void hip_set_pinfo(hip_t hip, plotting_data* pinfo)
+{
+ if (hip) {
+ hip->pinfo = pinfo;
+ }
+}
+
+
+
+void hip_set_errorf(hip_t hip, lame_report_function func)
+{
+ if (hip) {
+ hip->report_err = func;
+ }
+}
+
+void hip_set_debugf(hip_t hip, lame_report_function func)
+{
+ if (hip) {
+ hip->report_dbg = func;
+ }
+}
+
+void hip_set_msgf (hip_t hip, lame_report_function func)
+{
+ if (hip) {
+ hip->report_msg = func;
+ }
+}
+
+#endif
+
+/* end of mpglib_interface.c */
diff --git a/pkg/lame/clame/newmdct.c b/pkg/lame/clame/newmdct.c
new file mode 100644
index 0000000..596cac9
--- /dev/null
+++ b/pkg/lame/clame/newmdct.c
@@ -0,0 +1,1039 @@
+/*
+ * MP3 window subband -> subband filtering -> mdct routine
+ *
+ * Copyright (c) 1999-2000 Takehiro Tominaga
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Special Thanks to Patrick De Smet for your advices.
+ */
+
+/* $Id: newmdct.c,v 1.39 2011/05/07 16:05:17 rbrito Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "newmdct.h"
+
+
+
+#ifndef USE_GOGO_SUBBAND
+static const FLOAT enwindow[] = {
+ -4.77e-07 * 0.740951125354959 / 2.384e-06, 1.03951e-04 * 0.740951125354959 / 2.384e-06,
+ 9.53674e-04 * 0.740951125354959 / 2.384e-06, 2.841473e-03 * 0.740951125354959 / 2.384e-06,
+ 3.5758972e-02 * 0.740951125354959 / 2.384e-06, 3.401756e-03 * 0.740951125354959 / 2.384e-06, 9.83715e-04 * 0.740951125354959 / 2.384e-06, 9.9182e-05 * 0.740951125354959 / 2.384e-06, /* 15 */
+ 1.2398e-05 * 0.740951125354959 / 2.384e-06, 1.91212e-04 * 0.740951125354959 / 2.384e-06,
+ 2.283096e-03 * 0.740951125354959 / 2.384e-06, 1.6994476e-02 * 0.740951125354959 / 2.384e-06,
+ -1.8756866e-02 * 0.740951125354959 / 2.384e-06, -2.630711e-03 * 0.740951125354959 / 2.384e-06,
+ -2.47478e-04 * 0.740951125354959 / 2.384e-06, -1.4782e-05 * 0.740951125354959 / 2.384e-06,
+ 9.063471690191471e-01,
+ 1.960342806591213e-01,
+
+
+ -4.77e-07 * 0.773010453362737 / 2.384e-06, 1.05858e-04 * 0.773010453362737 / 2.384e-06,
+ 9.30786e-04 * 0.773010453362737 / 2.384e-06, 2.521515e-03 * 0.773010453362737 / 2.384e-06,
+ 3.5694122e-02 * 0.773010453362737 / 2.384e-06, 3.643036e-03 * 0.773010453362737 / 2.384e-06, 9.91821e-04 * 0.773010453362737 / 2.384e-06, 9.6321e-05 * 0.773010453362737 / 2.384e-06, /* 14 */
+ 1.1444e-05 * 0.773010453362737 / 2.384e-06, 1.65462e-04 * 0.773010453362737 / 2.384e-06,
+ 2.110004e-03 * 0.773010453362737 / 2.384e-06, 1.6112804e-02 * 0.773010453362737 / 2.384e-06,
+ -1.9634247e-02 * 0.773010453362737 / 2.384e-06, -2.803326e-03 * 0.773010453362737 / 2.384e-06,
+ -2.77042e-04 * 0.773010453362737 / 2.384e-06, -1.6689e-05 * 0.773010453362737 / 2.384e-06,
+ 8.206787908286602e-01,
+ 3.901806440322567e-01,
+
+
+ -4.77e-07 * 0.803207531480645 / 2.384e-06, 1.07288e-04 * 0.803207531480645 / 2.384e-06,
+ 9.02653e-04 * 0.803207531480645 / 2.384e-06, 2.174854e-03 * 0.803207531480645 / 2.384e-06,
+ 3.5586357e-02 * 0.803207531480645 / 2.384e-06, 3.858566e-03 * 0.803207531480645 / 2.384e-06, 9.95159e-04 * 0.803207531480645 / 2.384e-06, 9.3460e-05 * 0.803207531480645 / 2.384e-06, /* 13 */
+ 1.0014e-05 * 0.803207531480645 / 2.384e-06, 1.40190e-04 * 0.803207531480645 / 2.384e-06,
+ 1.937389e-03 * 0.803207531480645 / 2.384e-06, 1.5233517e-02 * 0.803207531480645 / 2.384e-06,
+ -2.0506859e-02 * 0.803207531480645 / 2.384e-06, -2.974033e-03 * 0.803207531480645 / 2.384e-06,
+ -3.07560e-04 * 0.803207531480645 / 2.384e-06, -1.8120e-05 * 0.803207531480645 / 2.384e-06,
+ 7.416505462720353e-01,
+ 5.805693545089249e-01,
+
+
+ -4.77e-07 * 0.831469612302545 / 2.384e-06, 1.08242e-04 * 0.831469612302545 / 2.384e-06,
+ 8.68797e-04 * 0.831469612302545 / 2.384e-06, 1.800537e-03 * 0.831469612302545 / 2.384e-06,
+ 3.5435200e-02 * 0.831469612302545 / 2.384e-06, 4.049301e-03 * 0.831469612302545 / 2.384e-06, 9.94205e-04 * 0.831469612302545 / 2.384e-06, 9.0599e-05 * 0.831469612302545 / 2.384e-06, /* 12 */
+ 9.060e-06 * 0.831469612302545 / 2.384e-06, 1.16348e-04 * 0.831469612302545 / 2.384e-06,
+ 1.766682e-03 * 0.831469612302545 / 2.384e-06, 1.4358521e-02 * 0.831469612302545 / 2.384e-06,
+ -2.1372318e-02 * 0.831469612302545 / 2.384e-06, -3.14188e-03 * 0.831469612302545 / 2.384e-06,
+ -3.39031e-04 * 0.831469612302545 / 2.384e-06, -1.9550e-05 * 0.831469612302545 / 2.384e-06,
+ 6.681786379192989e-01,
+ 7.653668647301797e-01,
+
+
+ -4.77e-07 * 0.857728610000272 / 2.384e-06, 1.08719e-04 * 0.857728610000272 / 2.384e-06,
+ 8.29220e-04 * 0.857728610000272 / 2.384e-06, 1.399517e-03 * 0.857728610000272 / 2.384e-06,
+ 3.5242081e-02 * 0.857728610000272 / 2.384e-06, 4.215240e-03 * 0.857728610000272 / 2.384e-06, 9.89437e-04 * 0.857728610000272 / 2.384e-06, 8.7261e-05 * 0.857728610000272 / 2.384e-06, /* 11 */
+ 8.106e-06 * 0.857728610000272 / 2.384e-06, 9.3937e-05 * 0.857728610000272 / 2.384e-06,
+ 1.597881e-03 * 0.857728610000272 / 2.384e-06, 1.3489246e-02 * 0.857728610000272 / 2.384e-06,
+ -2.2228718e-02 * 0.857728610000272 / 2.384e-06, -3.306866e-03 * 0.857728610000272 / 2.384e-06,
+ -3.71456e-04 * 0.857728610000272 / 2.384e-06, -2.1458e-05 * 0.857728610000272 / 2.384e-06,
+ 5.993769336819237e-01,
+ 9.427934736519954e-01,
+
+
+ -4.77e-07 * 0.881921264348355 / 2.384e-06, 1.08719e-04 * 0.881921264348355 / 2.384e-06,
+ 7.8392e-04 * 0.881921264348355 / 2.384e-06, 9.71317e-04 * 0.881921264348355 / 2.384e-06,
+ 3.5007000e-02 * 0.881921264348355 / 2.384e-06, 4.357815e-03 * 0.881921264348355 / 2.384e-06, 9.80854e-04 * 0.881921264348355 / 2.384e-06, 8.3923e-05 * 0.881921264348355 / 2.384e-06, /* 10 */
+ 7.629e-06 * 0.881921264348355 / 2.384e-06, 7.2956e-05 * 0.881921264348355 / 2.384e-06,
+ 1.432419e-03 * 0.881921264348355 / 2.384e-06, 1.2627602e-02 * 0.881921264348355 / 2.384e-06,
+ -2.3074150e-02 * 0.881921264348355 / 2.384e-06, -3.467083e-03 * 0.881921264348355 / 2.384e-06,
+ -4.04358e-04 * 0.881921264348355 / 2.384e-06, -2.3365e-05 * 0.881921264348355 / 2.384e-06,
+ 5.345111359507916e-01,
+ 1.111140466039205e+00,
+
+
+ -9.54e-07 * 0.903989293123443 / 2.384e-06, 1.08242e-04 * 0.903989293123443 / 2.384e-06,
+ 7.31945e-04 * 0.903989293123443 / 2.384e-06, 5.15938e-04 * 0.903989293123443 / 2.384e-06,
+ 3.4730434e-02 * 0.903989293123443 / 2.384e-06, 4.477024e-03 * 0.903989293123443 / 2.384e-06, 9.68933e-04 * 0.903989293123443 / 2.384e-06, 8.0585e-05 * 0.903989293123443 / 2.384e-06, /* 9 */
+ 6.676e-06 * 0.903989293123443 / 2.384e-06, 5.2929e-05 * 0.903989293123443 / 2.384e-06,
+ 1.269817e-03 * 0.903989293123443 / 2.384e-06, 1.1775017e-02 * 0.903989293123443 / 2.384e-06,
+ -2.3907185e-02 * 0.903989293123443 / 2.384e-06, -3.622532e-03 * 0.903989293123443 / 2.384e-06,
+ -4.38213e-04 * 0.903989293123443 / 2.384e-06, -2.5272e-05 * 0.903989293123443 / 2.384e-06,
+ 4.729647758913199e-01,
+ 1.268786568327291e+00,
+
+
+ -9.54e-07 * 0.92387953251128675613 / 2.384e-06,
+ 1.06812e-04 * 0.92387953251128675613 / 2.384e-06,
+ 6.74248e-04 * 0.92387953251128675613 / 2.384e-06,
+ 3.3379e-05 * 0.92387953251128675613 / 2.384e-06,
+ 3.4412861e-02 * 0.92387953251128675613 / 2.384e-06,
+ 4.573822e-03 * 0.92387953251128675613 / 2.384e-06,
+ 9.54151e-04 * 0.92387953251128675613 / 2.384e-06,
+ 7.6771e-05 * 0.92387953251128675613 / 2.384e-06,
+ 6.199e-06 * 0.92387953251128675613 / 2.384e-06, 3.4332e-05 * 0.92387953251128675613 / 2.384e-06,
+ 1.111031e-03 * 0.92387953251128675613 / 2.384e-06,
+ 1.0933399e-02 * 0.92387953251128675613 / 2.384e-06,
+ -2.4725437e-02 * 0.92387953251128675613 / 2.384e-06,
+ -3.771782e-03 * 0.92387953251128675613 / 2.384e-06,
+ -4.72546e-04 * 0.92387953251128675613 / 2.384e-06,
+ -2.7657e-05 * 0.92387953251128675613 / 2.384e-06,
+ 4.1421356237309504879e-01, /* tan(PI/8) */
+ 1.414213562373095e+00,
+
+
+ -9.54e-07 * 0.941544065183021 / 2.384e-06, 1.05381e-04 * 0.941544065183021 / 2.384e-06,
+ 6.10352e-04 * 0.941544065183021 / 2.384e-06, -4.75883e-04 * 0.941544065183021 / 2.384e-06,
+ 3.4055710e-02 * 0.941544065183021 / 2.384e-06, 4.649162e-03 * 0.941544065183021 / 2.384e-06, 9.35555e-04 * 0.941544065183021 / 2.384e-06, 7.3433e-05 * 0.941544065183021 / 2.384e-06, /* 7 */
+ 5.245e-06 * 0.941544065183021 / 2.384e-06, 1.7166e-05 * 0.941544065183021 / 2.384e-06,
+ 9.56535e-04 * 0.941544065183021 / 2.384e-06, 1.0103703e-02 * 0.941544065183021 / 2.384e-06,
+ -2.5527000e-02 * 0.941544065183021 / 2.384e-06, -3.914356e-03 * 0.941544065183021 / 2.384e-06,
+ -5.07355e-04 * 0.941544065183021 / 2.384e-06, -3.0041e-05 * 0.941544065183021 / 2.384e-06,
+ 3.578057213145241e-01,
+ 1.546020906725474e+00,
+
+
+ -9.54e-07 * 0.956940335732209 / 2.384e-06, 1.02520e-04 * 0.956940335732209 / 2.384e-06,
+ 5.39303e-04 * 0.956940335732209 / 2.384e-06, -1.011848e-03 * 0.956940335732209 / 2.384e-06,
+ 3.3659935e-02 * 0.956940335732209 / 2.384e-06, 4.703045e-03 * 0.956940335732209 / 2.384e-06, 9.15051e-04 * 0.956940335732209 / 2.384e-06, 7.0095e-05 * 0.956940335732209 / 2.384e-06, /* 6 */
+ 4.768e-06 * 0.956940335732209 / 2.384e-06, 9.54e-07 * 0.956940335732209 / 2.384e-06,
+ 8.06808e-04 * 0.956940335732209 / 2.384e-06, 9.287834e-03 * 0.956940335732209 / 2.384e-06,
+ -2.6310921e-02 * 0.956940335732209 / 2.384e-06, -4.048824e-03 * 0.956940335732209 / 2.384e-06,
+ -5.42164e-04 * 0.956940335732209 / 2.384e-06, -3.2425e-05 * 0.956940335732209 / 2.384e-06,
+ 3.033466836073424e-01,
+ 1.662939224605090e+00,
+
+
+ -1.431e-06 * 0.970031253194544 / 2.384e-06, 9.9182e-05 * 0.970031253194544 / 2.384e-06,
+ 4.62532e-04 * 0.970031253194544 / 2.384e-06, -1.573563e-03 * 0.970031253194544 / 2.384e-06,
+ 3.3225536e-02 * 0.970031253194544 / 2.384e-06, 4.737377e-03 * 0.970031253194544 / 2.384e-06, 8.91685e-04 * 0.970031253194544 / 2.384e-06, 6.6280e-05 * 0.970031253194544 / 2.384e-06, /* 5 */
+ 4.292e-06 * 0.970031253194544 / 2.384e-06, -1.3828e-05 * 0.970031253194544 / 2.384e-06,
+ 6.61850e-04 * 0.970031253194544 / 2.384e-06, 8.487225e-03 * 0.970031253194544 / 2.384e-06,
+ -2.7073860e-02 * 0.970031253194544 / 2.384e-06, -4.174709e-03 * 0.970031253194544 / 2.384e-06,
+ -5.76973e-04 * 0.970031253194544 / 2.384e-06, -3.4809e-05 * 0.970031253194544 / 2.384e-06,
+ 2.504869601913055e-01,
+ 1.763842528696710e+00,
+
+
+ -1.431e-06 * 0.98078528040323 / 2.384e-06, 9.5367e-05 * 0.98078528040323 / 2.384e-06,
+ 3.78609e-04 * 0.98078528040323 / 2.384e-06, -2.161503e-03 * 0.98078528040323 / 2.384e-06,
+ 3.2754898e-02 * 0.98078528040323 / 2.384e-06, 4.752159e-03 * 0.98078528040323 / 2.384e-06, 8.66413e-04 * 0.98078528040323 / 2.384e-06, 6.2943e-05 * 0.98078528040323 / 2.384e-06, /* 4 */
+ 3.815e-06 * 0.98078528040323 / 2.384e-06, -2.718e-05 * 0.98078528040323 / 2.384e-06,
+ 5.22137e-04 * 0.98078528040323 / 2.384e-06, 7.703304e-03 * 0.98078528040323 / 2.384e-06,
+ -2.7815342e-02 * 0.98078528040323 / 2.384e-06, -4.290581e-03 * 0.98078528040323 / 2.384e-06,
+ -6.11782e-04 * 0.98078528040323 / 2.384e-06, -3.7670e-05 * 0.98078528040323 / 2.384e-06,
+ 1.989123673796580e-01,
+ 1.847759065022573e+00,
+
+
+ -1.907e-06 * 0.989176509964781 / 2.384e-06, 9.0122e-05 * 0.989176509964781 / 2.384e-06,
+ 2.88486e-04 * 0.989176509964781 / 2.384e-06, -2.774239e-03 * 0.989176509964781 / 2.384e-06,
+ 3.2248020e-02 * 0.989176509964781 / 2.384e-06, 4.748821e-03 * 0.989176509964781 / 2.384e-06, 8.38757e-04 * 0.989176509964781 / 2.384e-06, 5.9605e-05 * 0.989176509964781 / 2.384e-06, /* 3 */
+ 3.338e-06 * 0.989176509964781 / 2.384e-06, -3.9577e-05 * 0.989176509964781 / 2.384e-06,
+ 3.88145e-04 * 0.989176509964781 / 2.384e-06, 6.937027e-03 * 0.989176509964781 / 2.384e-06,
+ -2.8532982e-02 * 0.989176509964781 / 2.384e-06, -4.395962e-03 * 0.989176509964781 / 2.384e-06,
+ -6.46591e-04 * 0.989176509964781 / 2.384e-06, -4.0531e-05 * 0.989176509964781 / 2.384e-06,
+ 1.483359875383474e-01,
+ 1.913880671464418e+00,
+
+
+ -1.907e-06 * 0.995184726672197 / 2.384e-06, 8.4400e-05 * 0.995184726672197 / 2.384e-06,
+ 1.91689e-04 * 0.995184726672197 / 2.384e-06, -3.411293e-03 * 0.995184726672197 / 2.384e-06,
+ 3.1706810e-02 * 0.995184726672197 / 2.384e-06, 4.728317e-03 * 0.995184726672197 / 2.384e-06,
+ 8.09669e-04 * 0.995184726672197 / 2.384e-06, 5.579e-05 * 0.995184726672197 / 2.384e-06,
+ 3.338e-06 * 0.995184726672197 / 2.384e-06, -5.0545e-05 * 0.995184726672197 / 2.384e-06,
+ 2.59876e-04 * 0.995184726672197 / 2.384e-06, 6.189346e-03 * 0.995184726672197 / 2.384e-06,
+ -2.9224873e-02 * 0.995184726672197 / 2.384e-06, -4.489899e-03 * 0.995184726672197 / 2.384e-06,
+ -6.80923e-04 * 0.995184726672197 / 2.384e-06, -4.3392e-05 * 0.995184726672197 / 2.384e-06,
+ 9.849140335716425e-02,
+ 1.961570560806461e+00,
+
+
+ -2.384e-06 * 0.998795456205172 / 2.384e-06, 7.7724e-05 * 0.998795456205172 / 2.384e-06,
+ 8.8215e-05 * 0.998795456205172 / 2.384e-06, -4.072189e-03 * 0.998795456205172 / 2.384e-06,
+ 3.1132698e-02 * 0.998795456205172 / 2.384e-06, 4.691124e-03 * 0.998795456205172 / 2.384e-06,
+ 7.79152e-04 * 0.998795456205172 / 2.384e-06, 5.2929e-05 * 0.998795456205172 / 2.384e-06,
+ 2.861e-06 * 0.998795456205172 / 2.384e-06, -6.0558e-05 * 0.998795456205172 / 2.384e-06,
+ 1.37329e-04 * 0.998795456205172 / 2.384e-06, 5.462170e-03 * 0.998795456205172 / 2.384e-06,
+ -2.9890060e-02 * 0.998795456205172 / 2.384e-06, -4.570484e-03 * 0.998795456205172 / 2.384e-06,
+ -7.14302e-04 * 0.998795456205172 / 2.384e-06, -4.6253e-05 * 0.998795456205172 / 2.384e-06,
+ 4.912684976946725e-02,
+ 1.990369453344394e+00,
+
+
+ 3.5780907e-02 * SQRT2 * 0.5 / 2.384e-06, 1.7876148e-02 * SQRT2 * 0.5 / 2.384e-06,
+ 3.134727e-03 * SQRT2 * 0.5 / 2.384e-06, 2.457142e-03 * SQRT2 * 0.5 / 2.384e-06,
+ 9.71317e-04 * SQRT2 * 0.5 / 2.384e-06, 2.18868e-04 * SQRT2 * 0.5 / 2.384e-06,
+ 1.01566e-04 * SQRT2 * 0.5 / 2.384e-06, 1.3828e-05 * SQRT2 * 0.5 / 2.384e-06,
+
+ 3.0526638e-02 / 2.384e-06, 4.638195e-03 / 2.384e-06, 7.47204e-04 / 2.384e-06,
+ 4.9591e-05 / 2.384e-06,
+ 4.756451e-03 / 2.384e-06, 2.1458e-05 / 2.384e-06, -6.9618e-05 / 2.384e-06, /* 2.384e-06/2.384e-06 */
+};
+#endif
+
+
+#define NS 12
+#define NL 36
+
+static const FLOAT win[4][NL] = {
+ {
+ 2.382191739347913e-13,
+ 6.423305872147834e-13,
+ 9.400849094049688e-13,
+ 1.122435026096556e-12,
+ 1.183840321267481e-12,
+ 1.122435026096556e-12,
+ 9.400849094049690e-13,
+ 6.423305872147839e-13,
+ 2.382191739347918e-13,
+
+ 5.456116108943412e-12,
+ 4.878985199565852e-12,
+ 4.240448995017367e-12,
+ 3.559909094758252e-12,
+ 2.858043359288075e-12,
+ 2.156177623817898e-12,
+ 1.475637723558783e-12,
+ 8.371015190102974e-13,
+ 2.599706096327376e-13,
+
+ -5.456116108943412e-12,
+ -4.878985199565852e-12,
+ -4.240448995017367e-12,
+ -3.559909094758252e-12,
+ -2.858043359288076e-12,
+ -2.156177623817898e-12,
+ -1.475637723558783e-12,
+ -8.371015190102975e-13,
+ -2.599706096327376e-13,
+
+ -2.382191739347923e-13,
+ -6.423305872147843e-13,
+ -9.400849094049696e-13,
+ -1.122435026096556e-12,
+ -1.183840321267481e-12,
+ -1.122435026096556e-12,
+ -9.400849094049694e-13,
+ -6.423305872147840e-13,
+ -2.382191739347918e-13,
+ },
+ {
+ 2.382191739347913e-13,
+ 6.423305872147834e-13,
+ 9.400849094049688e-13,
+ 1.122435026096556e-12,
+ 1.183840321267481e-12,
+ 1.122435026096556e-12,
+ 9.400849094049688e-13,
+ 6.423305872147841e-13,
+ 2.382191739347918e-13,
+
+ 5.456116108943413e-12,
+ 4.878985199565852e-12,
+ 4.240448995017367e-12,
+ 3.559909094758253e-12,
+ 2.858043359288075e-12,
+ 2.156177623817898e-12,
+ 1.475637723558782e-12,
+ 8.371015190102975e-13,
+ 2.599706096327376e-13,
+
+ -5.461314069809755e-12,
+ -4.921085770524055e-12,
+ -4.343405037091838e-12,
+ -3.732668368707687e-12,
+ -3.093523840190885e-12,
+ -2.430835727329465e-12,
+ -1.734679010007751e-12,
+ -9.748253656609281e-13,
+ -2.797435120168326e-13,
+
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ -2.283748241799531e-13,
+ -4.037858874020686e-13,
+ -2.146547464825323e-13,
+ },
+ {
+ 1.316524975873958e-01, /* win[SHORT_TYPE] */
+ 4.142135623730950e-01,
+ 7.673269879789602e-01,
+
+ 1.091308501069271e+00, /* tantab_l */
+ 1.303225372841206e+00,
+ 1.569685577117490e+00,
+ 1.920982126971166e+00,
+ 2.414213562373094e+00,
+ 3.171594802363212e+00,
+ 4.510708503662055e+00,
+ 7.595754112725146e+00,
+ 2.290376554843115e+01,
+
+ 0.98480775301220802032, /* cx */
+ 0.64278760968653936292,
+ 0.34202014332566882393,
+ 0.93969262078590842791,
+ -0.17364817766693030343,
+ -0.76604444311897790243,
+ 0.86602540378443870761,
+ 0.500000000000000e+00,
+
+ -5.144957554275265e-01, /* ca */
+ -4.717319685649723e-01,
+ -3.133774542039019e-01,
+ -1.819131996109812e-01,
+ -9.457419252642064e-02,
+ -4.096558288530405e-02,
+ -1.419856857247115e-02,
+ -3.699974673760037e-03,
+
+ 8.574929257125442e-01, /* cs */
+ 8.817419973177052e-01,
+ 9.496286491027329e-01,
+ 9.833145924917901e-01,
+ 9.955178160675857e-01,
+ 9.991605581781475e-01,
+ 9.998991952444470e-01,
+ 9.999931550702802e-01,
+ },
+ {
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 0.000000000000000e+00,
+ 2.283748241799531e-13,
+ 4.037858874020686e-13,
+ 2.146547464825323e-13,
+
+ 5.461314069809755e-12,
+ 4.921085770524055e-12,
+ 4.343405037091838e-12,
+ 3.732668368707687e-12,
+ 3.093523840190885e-12,
+ 2.430835727329466e-12,
+ 1.734679010007751e-12,
+ 9.748253656609281e-13,
+ 2.797435120168326e-13,
+
+ -5.456116108943413e-12,
+ -4.878985199565852e-12,
+ -4.240448995017367e-12,
+ -3.559909094758253e-12,
+ -2.858043359288075e-12,
+ -2.156177623817898e-12,
+ -1.475637723558782e-12,
+ -8.371015190102975e-13,
+ -2.599706096327376e-13,
+
+ -2.382191739347913e-13,
+ -6.423305872147834e-13,
+ -9.400849094049688e-13,
+ -1.122435026096556e-12,
+ -1.183840321267481e-12,
+ -1.122435026096556e-12,
+ -9.400849094049688e-13,
+ -6.423305872147841e-13,
+ -2.382191739347918e-13,
+ }
+};
+
+#define tantab_l (win[SHORT_TYPE]+3)
+#define cx (win[SHORT_TYPE]+12)
+#define ca (win[SHORT_TYPE]+20)
+#define cs (win[SHORT_TYPE]+28)
+
+/************************************************************************
+*
+* window_subband()
+*
+* PURPOSE: Overlapping window on PCM samples
+*
+* SEMANTICS:
+* 32 16-bit pcm samples are scaled to fractional 2's complement and
+* concatenated to the end of the window buffer #x#. The updated window
+* buffer #x# is then windowed by the analysis window #c# to produce the
+* windowed sample #z#
+*
+************************************************************************/
+
+/*
+ * new IDCT routine written by Takehiro TOMINAGA
+ */
+static const int order[] = {
+ 0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29,
+ 2, 3, 18, 19, 10, 11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31
+};
+
+
+/* returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 */
+inline static void
+window_subband(const sample_t * x1, FLOAT a[SBLIMIT])
+{
+ int i;
+ FLOAT const *wp = enwindow + 10;
+
+ const sample_t *x2 = &x1[238 - 14 - 286];
+
+ for (i = -15; i < 0; i++) {
+ FLOAT w, s, t;
+
+ w = wp[-10];
+ s = x2[-224] * w;
+ t = x1[224] * w;
+ w = wp[-9];
+ s += x2[-160] * w;
+ t += x1[160] * w;
+ w = wp[-8];
+ s += x2[-96] * w;
+ t += x1[96] * w;
+ w = wp[-7];
+ s += x2[-32] * w;
+ t += x1[32] * w;
+ w = wp[-6];
+ s += x2[32] * w;
+ t += x1[-32] * w;
+ w = wp[-5];
+ s += x2[96] * w;
+ t += x1[-96] * w;
+ w = wp[-4];
+ s += x2[160] * w;
+ t += x1[-160] * w;
+ w = wp[-3];
+ s += x2[224] * w;
+ t += x1[-224] * w;
+
+ w = wp[-2];
+ s += x1[-256] * w;
+ t -= x2[256] * w;
+ w = wp[-1];
+ s += x1[-192] * w;
+ t -= x2[192] * w;
+ w = wp[0];
+ s += x1[-128] * w;
+ t -= x2[128] * w;
+ w = wp[1];
+ s += x1[-64] * w;
+ t -= x2[64] * w;
+ w = wp[2];
+ s += x1[0] * w;
+ t -= x2[0] * w;
+ w = wp[3];
+ s += x1[64] * w;
+ t -= x2[-64] * w;
+ w = wp[4];
+ s += x1[128] * w;
+ t -= x2[-128] * w;
+ w = wp[5];
+ s += x1[192] * w;
+ t -= x2[-192] * w;
+
+ /*
+ * this multiplyer could be removed, but it needs more 256 FLOAT data.
+ * thinking about the data cache performance, I think we should not
+ * use such a huge table. tt 2000/Oct/25
+ */
+ s *= wp[6];
+ w = t - s;
+ a[30 + i * 2] = t + s;
+ a[31 + i * 2] = wp[7] * w;
+ wp += 18;
+ x1--;
+ x2++;
+ }
+ {
+ FLOAT s, t, u, v;
+ t = x1[-16] * wp[-10];
+ s = x1[-32] * wp[-2];
+ t += (x1[-48] - x1[16]) * wp[-9];
+ s += x1[-96] * wp[-1];
+ t += (x1[-80] + x1[48]) * wp[-8];
+ s += x1[-160] * wp[0];
+ t += (x1[-112] - x1[80]) * wp[-7];
+ s += x1[-224] * wp[1];
+ t += (x1[-144] + x1[112]) * wp[-6];
+ s -= x1[32] * wp[2];
+ t += (x1[-176] - x1[144]) * wp[-5];
+ s -= x1[96] * wp[3];
+ t += (x1[-208] + x1[176]) * wp[-4];
+ s -= x1[160] * wp[4];
+ t += (x1[-240] - x1[208]) * wp[-3];
+ s -= x1[224];
+
+ u = s - t;
+ v = s + t;
+
+ t = a[14];
+ s = a[15] - t;
+
+ a[31] = v + t; /* A0 */
+ a[30] = u + s; /* A1 */
+ a[15] = u - s; /* A2 */
+ a[14] = v - t; /* A3 */
+ }
+ {
+ FLOAT xr;
+ xr = a[28] - a[0];
+ a[0] += a[28];
+ a[28] = xr * wp[-2 * 18 + 7];
+ xr = a[29] - a[1];
+ a[1] += a[29];
+ a[29] = xr * wp[-2 * 18 + 7];
+
+ xr = a[26] - a[2];
+ a[2] += a[26];
+ a[26] = xr * wp[-4 * 18 + 7];
+ xr = a[27] - a[3];
+ a[3] += a[27];
+ a[27] = xr * wp[-4 * 18 + 7];
+
+ xr = a[24] - a[4];
+ a[4] += a[24];
+ a[24] = xr * wp[-6 * 18 + 7];
+ xr = a[25] - a[5];
+ a[5] += a[25];
+ a[25] = xr * wp[-6 * 18 + 7];
+
+ xr = a[22] - a[6];
+ a[6] += a[22];
+ a[22] = xr * SQRT2;
+ xr = a[23] - a[7];
+ a[7] += a[23];
+ a[23] = xr * SQRT2 - a[7];
+ a[7] -= a[6];
+ a[22] -= a[7];
+ a[23] -= a[22];
+
+ xr = a[6];
+ a[6] = a[31] - xr;
+ a[31] = a[31] + xr;
+ xr = a[7];
+ a[7] = a[30] - xr;
+ a[30] = a[30] + xr;
+ xr = a[22];
+ a[22] = a[15] - xr;
+ a[15] = a[15] + xr;
+ xr = a[23];
+ a[23] = a[14] - xr;
+ a[14] = a[14] + xr;
+
+ xr = a[20] - a[8];
+ a[8] += a[20];
+ a[20] = xr * wp[-10 * 18 + 7];
+ xr = a[21] - a[9];
+ a[9] += a[21];
+ a[21] = xr * wp[-10 * 18 + 7];
+
+ xr = a[18] - a[10];
+ a[10] += a[18];
+ a[18] = xr * wp[-12 * 18 + 7];
+ xr = a[19] - a[11];
+ a[11] += a[19];
+ a[19] = xr * wp[-12 * 18 + 7];
+
+ xr = a[16] - a[12];
+ a[12] += a[16];
+ a[16] = xr * wp[-14 * 18 + 7];
+ xr = a[17] - a[13];
+ a[13] += a[17];
+ a[17] = xr * wp[-14 * 18 + 7];
+
+ xr = -a[20] + a[24];
+ a[20] += a[24];
+ a[24] = xr * wp[-12 * 18 + 7];
+ xr = -a[21] + a[25];
+ a[21] += a[25];
+ a[25] = xr * wp[-12 * 18 + 7];
+
+ xr = a[4] - a[8];
+ a[4] += a[8];
+ a[8] = xr * wp[-12 * 18 + 7];
+ xr = a[5] - a[9];
+ a[5] += a[9];
+ a[9] = xr * wp[-12 * 18 + 7];
+
+ xr = a[0] - a[12];
+ a[0] += a[12];
+ a[12] = xr * wp[-4 * 18 + 7];
+ xr = a[1] - a[13];
+ a[1] += a[13];
+ a[13] = xr * wp[-4 * 18 + 7];
+ xr = a[16] - a[28];
+ a[16] += a[28];
+ a[28] = xr * wp[-4 * 18 + 7];
+ xr = -a[17] + a[29];
+ a[17] += a[29];
+ a[29] = xr * wp[-4 * 18 + 7];
+
+ xr = SQRT2 * (a[2] - a[10]);
+ a[2] += a[10];
+ a[10] = xr;
+ xr = SQRT2 * (a[3] - a[11]);
+ a[3] += a[11];
+ a[11] = xr;
+ xr = SQRT2 * (-a[18] + a[26]);
+ a[18] += a[26];
+ a[26] = xr - a[18];
+ xr = SQRT2 * (-a[19] + a[27]);
+ a[19] += a[27];
+ a[27] = xr - a[19];
+
+ xr = a[2];
+ a[19] -= a[3];
+ a[3] -= xr;
+ a[2] = a[31] - xr;
+ a[31] += xr;
+ xr = a[3];
+ a[11] -= a[19];
+ a[18] -= xr;
+ a[3] = a[30] - xr;
+ a[30] += xr;
+ xr = a[18];
+ a[27] -= a[11];
+ a[19] -= xr;
+ a[18] = a[15] - xr;
+ a[15] += xr;
+
+ xr = a[19];
+ a[10] -= xr;
+ a[19] = a[14] - xr;
+ a[14] += xr;
+ xr = a[10];
+ a[11] -= xr;
+ a[10] = a[23] - xr;
+ a[23] += xr;
+ xr = a[11];
+ a[26] -= xr;
+ a[11] = a[22] - xr;
+ a[22] += xr;
+ xr = a[26];
+ a[27] -= xr;
+ a[26] = a[7] - xr;
+ a[7] += xr;
+
+ xr = a[27];
+ a[27] = a[6] - xr;
+ a[6] += xr;
+
+ xr = SQRT2 * (a[0] - a[4]);
+ a[0] += a[4];
+ a[4] = xr;
+ xr = SQRT2 * (a[1] - a[5]);
+ a[1] += a[5];
+ a[5] = xr;
+ xr = SQRT2 * (a[16] - a[20]);
+ a[16] += a[20];
+ a[20] = xr;
+ xr = SQRT2 * (a[17] - a[21]);
+ a[17] += a[21];
+ a[21] = xr;
+
+ xr = -SQRT2 * (a[8] - a[12]);
+ a[8] += a[12];
+ a[12] = xr - a[8];
+ xr = -SQRT2 * (a[9] - a[13]);
+ a[9] += a[13];
+ a[13] = xr - a[9];
+ xr = -SQRT2 * (a[25] - a[29]);
+ a[25] += a[29];
+ a[29] = xr - a[25];
+ xr = -SQRT2 * (a[24] + a[28]);
+ a[24] -= a[28];
+ a[28] = xr - a[24];
+
+ xr = a[24] - a[16];
+ a[24] = xr;
+ xr = a[20] - xr;
+ a[20] = xr;
+ xr = a[28] - xr;
+ a[28] = xr;
+
+ xr = a[25] - a[17];
+ a[25] = xr;
+ xr = a[21] - xr;
+ a[21] = xr;
+ xr = a[29] - xr;
+ a[29] = xr;
+
+ xr = a[17] - a[1];
+ a[17] = xr;
+ xr = a[9] - xr;
+ a[9] = xr;
+ xr = a[25] - xr;
+ a[25] = xr;
+ xr = a[5] - xr;
+ a[5] = xr;
+ xr = a[21] - xr;
+ a[21] = xr;
+ xr = a[13] - xr;
+ a[13] = xr;
+ xr = a[29] - xr;
+ a[29] = xr;
+
+ xr = a[1] - a[0];
+ a[1] = xr;
+ xr = a[16] - xr;
+ a[16] = xr;
+ xr = a[17] - xr;
+ a[17] = xr;
+ xr = a[8] - xr;
+ a[8] = xr;
+ xr = a[9] - xr;
+ a[9] = xr;
+ xr = a[24] - xr;
+ a[24] = xr;
+ xr = a[25] - xr;
+ a[25] = xr;
+ xr = a[4] - xr;
+ a[4] = xr;
+ xr = a[5] - xr;
+ a[5] = xr;
+ xr = a[20] - xr;
+ a[20] = xr;
+ xr = a[21] - xr;
+ a[21] = xr;
+ xr = a[12] - xr;
+ a[12] = xr;
+ xr = a[13] - xr;
+ a[13] = xr;
+ xr = a[28] - xr;
+ a[28] = xr;
+ xr = a[29] - xr;
+ a[29] = xr;
+
+ xr = a[0];
+ a[0] += a[31];
+ a[31] -= xr;
+ xr = a[1];
+ a[1] += a[30];
+ a[30] -= xr;
+ xr = a[16];
+ a[16] += a[15];
+ a[15] -= xr;
+ xr = a[17];
+ a[17] += a[14];
+ a[14] -= xr;
+ xr = a[8];
+ a[8] += a[23];
+ a[23] -= xr;
+ xr = a[9];
+ a[9] += a[22];
+ a[22] -= xr;
+ xr = a[24];
+ a[24] += a[7];
+ a[7] -= xr;
+ xr = a[25];
+ a[25] += a[6];
+ a[6] -= xr;
+ xr = a[4];
+ a[4] += a[27];
+ a[27] -= xr;
+ xr = a[5];
+ a[5] += a[26];
+ a[26] -= xr;
+ xr = a[20];
+ a[20] += a[11];
+ a[11] -= xr;
+ xr = a[21];
+ a[21] += a[10];
+ a[10] -= xr;
+ xr = a[12];
+ a[12] += a[19];
+ a[19] -= xr;
+ xr = a[13];
+ a[13] += a[18];
+ a[18] -= xr;
+ xr = a[28];
+ a[28] += a[3];
+ a[3] -= xr;
+ xr = a[29];
+ a[29] += a[2];
+ a[2] -= xr;
+ }
+
+}
+
+
+/*-------------------------------------------------------------------*/
+/* */
+/* Function: Calculation of the MDCT */
+/* In the case of long blocks (type 0,1,3) there are */
+/* 36 coefficents in the time domain and 18 in the frequency */
+/* domain. */
+/* In the case of short blocks (type 2) there are 3 */
+/* transformations with short length. This leads to 12 coefficents */
+/* in the time and 6 in the frequency domain. In this case the */
+/* results are stored side by side in the vector out[]. */
+/* */
+/* New layer3 */
+/* */
+/*-------------------------------------------------------------------*/
+
+inline static void
+mdct_short(FLOAT * inout)
+{
+ int l;
+ for (l = 0; l < 3; l++) {
+ FLOAT tc0, tc1, tc2, ts0, ts1, ts2;
+
+ ts0 = inout[2 * 3] * win[SHORT_TYPE][0] - inout[5 * 3];
+ tc0 = inout[0 * 3] * win[SHORT_TYPE][2] - inout[3 * 3];
+ tc1 = ts0 + tc0;
+ tc2 = ts0 - tc0;
+
+ ts0 = inout[5 * 3] * win[SHORT_TYPE][0] + inout[2 * 3];
+ tc0 = inout[3 * 3] * win[SHORT_TYPE][2] + inout[0 * 3];
+ ts1 = ts0 + tc0;
+ ts2 = -ts0 + tc0;
+
+ tc0 = (inout[1 * 3] * win[SHORT_TYPE][1] - inout[4 * 3]) * 2.069978111953089e-11; /* tritab_s[1] */
+ ts0 = (inout[4 * 3] * win[SHORT_TYPE][1] + inout[1 * 3]) * 2.069978111953089e-11; /* tritab_s[1] */
+
+ inout[3 * 0] = tc1 * 1.907525191737280e-11 /* tritab_s[2] */ + tc0;
+ inout[3 * 5] = -ts1 * 1.907525191737280e-11 /* tritab_s[0] */ + ts0;
+
+ tc2 = tc2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[2] */ ;
+ ts1 = ts1 * 0.5 * 1.907525191737281e-11 + ts0;
+ inout[3 * 1] = tc2 - ts1;
+ inout[3 * 2] = tc2 + ts1;
+
+ tc1 = tc1 * 0.5 * 1.907525191737281e-11 - tc0;
+ ts2 = ts2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[0] */ ;
+ inout[3 * 3] = tc1 + ts2;
+ inout[3 * 4] = tc1 - ts2;
+
+ inout++;
+ }
+}
+
+inline static void
+mdct_long(FLOAT * out, FLOAT const *in)
+{
+ FLOAT ct, st;
+ {
+ FLOAT tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8;
+ /* 1,2, 5,6, 9,10, 13,14, 17 */
+ tc1 = in[17] - in[9];
+ tc3 = in[15] - in[11];
+ tc4 = in[14] - in[12];
+ ts5 = in[0] + in[8];
+ ts6 = in[1] + in[7];
+ ts7 = in[2] + in[6];
+ ts8 = in[3] + in[5];
+
+ out[17] = (ts5 + ts7 - ts8) - (ts6 - in[4]);
+ st = (ts5 + ts7 - ts8) * cx[7] + (ts6 - in[4]);
+ ct = (tc1 - tc3 - tc4) * cx[6];
+ out[5] = ct + st;
+ out[6] = ct - st;
+
+ tc2 = (in[16] - in[10]) * cx[6];
+ ts6 = ts6 * cx[7] + in[4];
+ ct = tc1 * cx[0] + tc2 + tc3 * cx[1] + tc4 * cx[2];
+ st = -ts5 * cx[4] + ts6 - ts7 * cx[5] + ts8 * cx[3];
+ out[1] = ct + st;
+ out[2] = ct - st;
+
+ ct = tc1 * cx[1] - tc2 - tc3 * cx[2] + tc4 * cx[0];
+ st = -ts5 * cx[5] + ts6 - ts7 * cx[3] + ts8 * cx[4];
+ out[9] = ct + st;
+ out[10] = ct - st;
+
+ ct = tc1 * cx[2] - tc2 + tc3 * cx[0] - tc4 * cx[1];
+ st = ts5 * cx[3] - ts6 + ts7 * cx[4] - ts8 * cx[5];
+ out[13] = ct + st;
+ out[14] = ct - st;
+ }
+ {
+ FLOAT ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8;
+
+ ts1 = in[8] - in[0];
+ ts3 = in[6] - in[2];
+ ts4 = in[5] - in[3];
+ tc5 = in[17] + in[9];
+ tc6 = in[16] + in[10];
+ tc7 = in[15] + in[11];
+ tc8 = in[14] + in[12];
+
+ out[0] = (tc5 + tc7 + tc8) + (tc6 + in[13]);
+ ct = (tc5 + tc7 + tc8) * cx[7] - (tc6 + in[13]);
+ st = (ts1 - ts3 + ts4) * cx[6];
+ out[11] = ct + st;
+ out[12] = ct - st;
+
+ ts2 = (in[7] - in[1]) * cx[6];
+ tc6 = in[13] - tc6 * cx[7];
+ ct = tc5 * cx[3] - tc6 + tc7 * cx[4] + tc8 * cx[5];
+ st = ts1 * cx[2] + ts2 + ts3 * cx[0] + ts4 * cx[1];
+ out[3] = ct + st;
+ out[4] = ct - st;
+
+ ct = -tc5 * cx[5] + tc6 - tc7 * cx[3] - tc8 * cx[4];
+ st = ts1 * cx[1] + ts2 - ts3 * cx[2] - ts4 * cx[0];
+ out[7] = ct + st;
+ out[8] = ct - st;
+
+ ct = -tc5 * cx[4] + tc6 - tc7 * cx[5] - tc8 * cx[3];
+ st = ts1 * cx[0] - ts2 + ts3 * cx[1] - ts4 * cx[2];
+ out[15] = ct + st;
+ out[16] = ct - st;
+ }
+}
+
+
+void
+mdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int gr, k, ch;
+ const sample_t *wk;
+
+ wk = w0 + 286;
+ /* thinking cache performance, ch->gr loop is better than gr->ch loop */
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ int band;
+ gr_info *const gi = &(gfc->l3_side.tt[gr][ch]);
+ FLOAT *mdct_enc = gi->xr;
+ FLOAT *samp = esv->sb_sample[ch][1 - gr][0];
+
+ for (k = 0; k < 18 / 2; k++) {
+ window_subband(wk, samp);
+ window_subband(wk + 32, samp + 32);
+ samp += 64;
+ wk += 64;
+ /*
+ * Compensate for inversion in the analysis filter
+ */
+ for (band = 1; band < 32; band += 2) {
+ samp[band - 32] *= -1;
+ }
+ }
+
+ /*
+ * Perform imdct of 18 previous subband samples
+ * + 18 current subband samples
+ */
+ for (band = 0; band < 32; band++, mdct_enc += 18) {
+ int type = gi->block_type;
+ FLOAT const *const band0 = esv->sb_sample[ch][gr][0] + order[band];
+ FLOAT *const band1 = esv->sb_sample[ch][1 - gr][0] + order[band];
+ if (gi->mixed_block_flag && band < 2)
+ type = 0;
+ if (esv->amp_filter[band] < 1e-12) {
+ memset(mdct_enc, 0, 18 * sizeof(FLOAT));
+ }
+ else {
+ if (esv->amp_filter[band] < 1.0) {
+ for (k = 0; k < 18; k++)
+ band1[k * 32] *= esv->amp_filter[band];
+ }
+ if (type == SHORT_TYPE) {
+ for (k = -NS / 4; k < 0; k++) {
+ FLOAT const w = win[SHORT_TYPE][k + 3];
+ mdct_enc[k * 3 + 9] = band0[(9 + k) * 32] * w - band0[(8 - k) * 32];
+ mdct_enc[k * 3 + 18] = band0[(14 - k) * 32] * w + band0[(15 + k) * 32];
+ mdct_enc[k * 3 + 10] = band0[(15 + k) * 32] * w - band0[(14 - k) * 32];
+ mdct_enc[k * 3 + 19] = band1[(2 - k) * 32] * w + band1[(3 + k) * 32];
+ mdct_enc[k * 3 + 11] = band1[(3 + k) * 32] * w - band1[(2 - k) * 32];
+ mdct_enc[k * 3 + 20] = band1[(8 - k) * 32] * w + band1[(9 + k) * 32];
+ }
+ mdct_short(mdct_enc);
+ }
+ else {
+ FLOAT work[18];
+ for (k = -NL / 4; k < 0; k++) {
+ FLOAT a, b;
+ a = win[type][k + 27] * band1[(k + 9) * 32]
+ + win[type][k + 36] * band1[(8 - k) * 32];
+ b = win[type][k + 9] * band0[(k + 9) * 32]
+ - win[type][k + 18] * band0[(8 - k) * 32];
+ work[k + 9] = a - b * tantab_l[k + 9];
+ work[k + 18] = a * tantab_l[k + 9] + b;
+ }
+
+ mdct_long(mdct_enc, work);
+ }
+ }
+ /*
+ * Perform aliasing reduction butterfly
+ */
+ if (type != SHORT_TYPE && band != 0) {
+ for (k = 7; k >= 0; --k) {
+ FLOAT bu, bd;
+ bu = mdct_enc[k] * ca[k] + mdct_enc[-1 - k] * cs[k];
+ bd = mdct_enc[k] * cs[k] - mdct_enc[-1 - k] * ca[k];
+
+ mdct_enc[-1 - k] = bu;
+ mdct_enc[k] = bd;
+ }
+ }
+ }
+ }
+ wk = w1 + 286;
+ if (cfg->mode_gr == 1) {
+ memcpy(esv->sb_sample[ch][0], esv->sb_sample[ch][1], 576 * sizeof(FLOAT));
+ }
+ }
+}
diff --git a/pkg/lame/clame/newmdct.h b/pkg/lame/clame/newmdct.h
new file mode 100644
index 0000000..0b58a95
--- /dev/null
+++ b/pkg/lame/clame/newmdct.h
@@ -0,0 +1,27 @@
+/*
+ * New Modified DCT include file
+ *
+ * Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_NEWMDCT_H
+#define LAME_NEWMDCT_H
+
+void mdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1);
+
+#endif /* LAME_NEWMDCT_H */
diff --git a/pkg/lame/clame/presets.c b/pkg/lame/clame/presets.c
new file mode 100644
index 0000000..93594f5
--- /dev/null
+++ b/pkg/lame/clame/presets.c
@@ -0,0 +1,404 @@
+/*
+ * presets.c -- Apply presets
+ *
+ * Copyright (c) 2002-2008 Gabriel Bouvigne
+ * Copyright (c) 2007-2012 Robert Hegemann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "lame.h"
+#include "machine.h"
+#include "set_get.h"
+#include "encoder.h"
+#include "util.h"
+#include "lame_global_flags.h"
+
+#define SET_OPTION(opt, val, def) if (enforce) \
+ (void) lame_set_##opt(gfp, val); \
+ else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \
+ (void) lame_set_##opt(gfp, val);
+
+#define SET__OPTION(opt, val, def) if (enforce) \
+ lame_set_##opt(gfp, val); \
+ else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \
+ lame_set_##opt(gfp, val);
+
+#undef Min
+#undef Max
+
+static inline int
+min_int(int a, int b)
+{
+ if (a < b) {
+ return a;
+ }
+ return b;
+}
+
+static inline int
+max_int(int a, int b)
+{
+ if (a > b) {
+ return a;
+ }
+ return b;
+}
+
+
+
+typedef struct {
+ int vbr_q;
+ int quant_comp;
+ int quant_comp_s;
+ int expY;
+ FLOAT st_lrm; /*short threshold */
+ FLOAT st_s;
+ FLOAT masking_adj;
+ FLOAT masking_adj_short;
+ FLOAT ath_lower;
+ FLOAT ath_curve;
+ FLOAT ath_sensitivity;
+ FLOAT interch;
+ int safejoint;
+ int sfb21mod;
+ FLOAT msfix;
+ FLOAT minval;
+ FLOAT ath_fixpoint;
+} vbr_presets_t;
+
+ /* *INDENT-OFF* */
+
+ /* Switch mappings for VBR mode VBR_RH */
+ static const vbr_presets_t vbr_old_switch_map[] = {
+ /*vbr_q qcomp_l qcomp_s expY st_lrm st_s mask adj_l adj_s ath_lower ath_curve ath_sens interChR safejoint sfb21mod msfix */
+ {0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97, 5, 100},
+ {1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35, 5, 100},
+ {2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49, 5, 100},
+ {3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64, 5, 100},
+ {4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79, 5, 100},
+ {5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95, 5, 100},
+ {6, 9, 9, 1, 6.60, 145.0, 0.67, 0.65, -14.7, 6.5, -19, 0.0004, 0, 0, 2.30, 5, 100},
+ {7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70, 5, 100},
+ {8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0, 5, 100},
+ {9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0, 5, 100},
+ {10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0, 5, 100}
+ };
+
+ static const vbr_presets_t vbr_mt_psy_switch_map[] = {
+ /*vbr_q qcomp_l qcomp_s expY st_lrm st_s mask adj_l adj_s ath_lower ath_curve ath_sens --- safejoint sfb21mod msfix */
+ {0, 9, 9, 0, 4.20, 25.0, -6.8, -6.8, 7.1, 1, 0, 0, 2, 31, 1.000, 5, 100},
+ {1, 9, 9, 0, 4.20, 25.0, -4.8, -4.8, 5.4, 1.4, -1, 0, 2, 27, 1.122, 5, 98},
+ {2, 9, 9, 0, 4.20, 25.0, -2.6, -2.6, 3.7, 2.0, -3, 0, 2, 23, 1.288, 5, 97},
+ {3, 9, 9, 1, 4.20, 25.0, -1.6, -1.6, 2.0, 2.0, -5, 0, 2, 18, 1.479, 5, 96},
+ {4, 9, 9, 1, 4.20, 25.0, -0.0, -0.0, 0.0, 2.0, -8, 0, 2, 12, 1.698, 5, 95},
+ {5, 9, 9, 1, 4.20, 25.0, 1.3, 1.3, -6, 3.5, -11, 0, 2, 8, 1.950, 5, 94.2},
+#if 0
+ {6, 9, 9, 1, 4.50, 100.0, 1.5, 1.5, -24.0, 6.0, -14, 0, 2, 4, 2.239, 3, 93.9},
+ {7, 9, 9, 1, 4.80, 200.0, 1.7, 1.7, -28.0, 9.0, -20, 0, 2, 0, 2.570, 1, 93.6},
+#else
+ {6, 9, 9, 1, 4.50, 100.0, 2.2, 2.3, -12.0, 6.0, -14, 0, 2, 4, 2.239, 3, 93.9},
+ {7, 9, 9, 1, 4.80, 200.0, 2.7, 2.7, -18.0, 9.0, -17, 0, 2, 0, 2.570, 1, 93.6},
+#endif
+ {8, 9, 9, 1, 5.30, 300.0, 2.8, 2.8, -21.0, 10.0, -23, 0.0002, 0, 0, 2.951, 0, 93.3},
+ {9, 9, 9, 1, 6.60, 300.0, 2.8, 2.8, -23.0, 11.0, -25, 0.0006, 0, 0, 3.388, 0, 93.3},
+ {10, 9, 9, 1, 25.00, 300.0, 2.8, 2.8, -25.0, 12.0, -27, 0.0025, 0, 0, 3.500, 0, 93.3}
+ };
+
+ /* *INDENT-ON* */
+
+static vbr_presets_t const*
+get_vbr_preset(int v)
+{
+ switch (v) {
+ case vbr_mtrh:
+ case vbr_mt:
+ return &vbr_mt_psy_switch_map[0];
+ default:
+ return &vbr_old_switch_map[0];
+ }
+}
+
+#define NOOP(m) (void)p.m
+#define LERP(m) (p.m = p.m + x * (q.m - p.m))
+
+static void
+apply_vbr_preset(lame_global_flags * gfp, int a, int enforce)
+{
+ vbr_presets_t const *vbr_preset = get_vbr_preset(lame_get_VBR(gfp));
+ float x = gfp->VBR_q_frac;
+ vbr_presets_t p = vbr_preset[a];
+ vbr_presets_t q = vbr_preset[a + 1];
+ vbr_presets_t const *set = &p;
+
+ NOOP(vbr_q);
+ NOOP(quant_comp);
+ NOOP(quant_comp_s);
+ NOOP(expY);
+ LERP(st_lrm);
+ LERP(st_s);
+ LERP(masking_adj);
+ LERP(masking_adj_short);
+ LERP(ath_lower);
+ LERP(ath_curve);
+ LERP(ath_sensitivity);
+ LERP(interch);
+ NOOP(safejoint);
+ LERP(sfb21mod);
+ LERP(msfix);
+ LERP(minval);
+ LERP(ath_fixpoint);
+
+ (void) lame_set_VBR_q(gfp, set->vbr_q);
+ SET_OPTION(quant_comp, set->quant_comp, -1);
+ SET_OPTION(quant_comp_short, set->quant_comp_s, -1);
+ if (set->expY) {
+ (void) lame_set_experimentalY(gfp, set->expY);
+ }
+ SET_OPTION(short_threshold_lrm, set->st_lrm, -1);
+ SET_OPTION(short_threshold_s, set->st_s, -1);
+ SET_OPTION(maskingadjust, set->masking_adj, 0);
+ SET_OPTION(maskingadjust_short, set->masking_adj_short, 0);
+ if (lame_get_VBR(gfp) == vbr_mt || lame_get_VBR(gfp) == vbr_mtrh) {
+ lame_set_ATHtype(gfp, 5);
+ }
+ SET_OPTION(ATHlower, set->ath_lower, 0);
+ SET_OPTION(ATHcurve, set->ath_curve, -1);
+ SET_OPTION(athaa_sensitivity, set->ath_sensitivity, 0);
+ if (set->interch > 0) {
+ SET_OPTION(interChRatio, set->interch, -1);
+ }
+
+ /* parameters for which there is no proper set/get interface */
+ if (set->safejoint > 0) {
+ (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2);
+ }
+ if (set->sfb21mod > 0) {
+ int const nsp = lame_get_exp_nspsytune(gfp);
+ int const val = (nsp >> 20) & 63;
+ if (val == 0) {
+ int const sf21mod = (set->sfb21mod << 20) | nsp;
+ (void) lame_set_exp_nspsytune(gfp, sf21mod);
+ }
+ }
+ SET__OPTION(msfix, set->msfix, -1);
+
+ if (enforce == 0) {
+ gfp->VBR_q = a;
+ gfp->VBR_q_frac = x;
+ }
+ gfp->internal_flags->cfg.minval = set->minval;
+ { /* take care of gain adjustments */
+ double const x = fabs(gfp->scale);
+ double const y = (x > 0.f) ? (10.f * log10(x)) : 0.f;
+ gfp->internal_flags->cfg.ATHfixpoint = set->ath_fixpoint - y;
+ }
+}
+
+static int
+apply_abr_preset(lame_global_flags * gfp, int preset, int enforce)
+{
+ typedef struct {
+ int abr_kbps;
+ int quant_comp;
+ int quant_comp_s;
+ int safejoint;
+ FLOAT nsmsfix;
+ FLOAT st_lrm; /*short threshold */
+ FLOAT st_s;
+ FLOAT scale;
+ FLOAT masking_adj;
+ FLOAT ath_lower;
+ FLOAT ath_curve;
+ FLOAT interch;
+ int sfscale;
+ } abr_presets_t;
+
+
+ /* *INDENT-OFF* */
+
+ /*
+ * Switch mappings for ABR mode
+ */
+ const abr_presets_t abr_switch_map[] = {
+ /* kbps quant q_s safejoint nsmsfix st_lrm st_s scale msk ath_lwr ath_curve interch , sfscale */
+ { 8, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -30.0, 11, 0.0012, 1}, /* 8, impossible to use in stereo */
+ { 16, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -25.0, 11, 0.0010, 1}, /* 16 */
+ { 24, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -20.0, 11, 0.0010, 1}, /* 24 */
+ { 32, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -15.0, 11, 0.0010, 1}, /* 32 */
+ { 40, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 40 */
+ { 48, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 48 */
+ { 56, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -6.0, 11, 0.0008, 1}, /* 56 */
+ { 64, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -2.0, 11, 0.0008, 1}, /* 64 */
+ { 80, 9, 9, 0, 0, 6.60, 145, 0.95, 0, .0, 8, 0.0007, 1}, /* 80 */
+ { 96, 9, 9, 0, 2.50, 6.60, 145, 0.95, 0, 1.0, 5.5, 0.0006, 1}, /* 96 */
+ {112, 9, 9, 0, 2.25, 6.60, 145, 0.95, 0, 2.0, 4.5, 0.0005, 1}, /* 112 */
+ {128, 9, 9, 0, 1.95, 6.40, 140, 0.95, 0, 3.0, 4, 0.0002, 1}, /* 128 */
+ {160, 9, 9, 1, 1.79, 6.00, 135, 0.95, -2, 5.0, 3.5, 0, 1}, /* 160 */
+ {192, 9, 9, 1, 1.49, 5.60, 125, 0.97, -4, 7.0, 3, 0, 0}, /* 192 */
+ {224, 9, 9, 1, 1.25, 5.20, 125, 0.98, -6, 9.0, 2, 0, 0}, /* 224 */
+ {256, 9, 9, 1, 0.97, 5.20, 125, 1.00, -8, 10.0, 1, 0, 0}, /* 256 */
+ {320, 9, 9, 1, 0.90, 5.20, 125, 1.00, -10, 12.0, 0, 0, 0} /* 320 */
+ };
+
+ /* *INDENT-ON* */
+
+ /* Variables for the ABR stuff */
+ int r;
+ int actual_bitrate = preset;
+
+ r = nearestBitrateFullIndex(preset);
+
+ (void) lame_set_VBR(gfp, vbr_abr);
+ (void) lame_set_VBR_mean_bitrate_kbps(gfp, (actual_bitrate));
+ (void) lame_set_VBR_mean_bitrate_kbps(gfp, min_int(lame_get_VBR_mean_bitrate_kbps(gfp), 320));
+ (void) lame_set_VBR_mean_bitrate_kbps(gfp, max_int(lame_get_VBR_mean_bitrate_kbps(gfp), 8));
+ (void) lame_set_brate(gfp, lame_get_VBR_mean_bitrate_kbps(gfp));
+
+
+ /* parameters for which there is no proper set/get interface */
+ if (abr_switch_map[r].safejoint > 0)
+ (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); /* safejoint */
+
+ if (abr_switch_map[r].sfscale > 0)
+ (void) lame_set_sfscale(gfp, 1);
+
+
+ SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1);
+ SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1);
+
+ SET__OPTION(msfix, abr_switch_map[r].nsmsfix, -1);
+
+ SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1);
+ SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1);
+
+ /* ABR seems to have big problems with clipping, especially at low bitrates */
+ /* so we compensate for that here by using a scale value depending on bitrate */
+ lame_set_scale(gfp, lame_get_scale(gfp) * abr_switch_map[r].scale);
+
+ SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0);
+ if (abr_switch_map[r].masking_adj > 0) {
+ SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * .9, 0);
+ }
+ else {
+ SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * 1.1, 0);
+ }
+
+
+ SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0);
+ SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1);
+
+ SET_OPTION(interChRatio, abr_switch_map[r].interch, -1);
+
+ (void) abr_switch_map[r].abr_kbps;
+
+ gfp->internal_flags->cfg.minval = 5. * (abr_switch_map[r].abr_kbps / 320.);
+
+ return preset;
+}
+
+
+
+int
+apply_preset(lame_global_flags * gfp, int preset, int enforce)
+{
+ /*translate legacy presets */
+ switch (preset) {
+ case R3MIX:
+ {
+ preset = V3;
+ (void) lame_set_VBR(gfp, vbr_mtrh);
+ break;
+ }
+ case MEDIUM:
+ case MEDIUM_FAST:
+ {
+ preset = V4;
+ (void) lame_set_VBR(gfp, vbr_mtrh);
+ break;
+ }
+ case STANDARD:
+ case STANDARD_FAST:
+ {
+ preset = V2;
+ (void) lame_set_VBR(gfp, vbr_mtrh);
+ break;
+ }
+ case EXTREME:
+ case EXTREME_FAST:
+ {
+ preset = V0;
+ (void) lame_set_VBR(gfp, vbr_mtrh);
+ break;
+ }
+ case INSANE:
+ {
+ preset = 320;
+ gfp->preset = preset;
+ (void) apply_abr_preset(gfp, preset, enforce);
+ lame_set_VBR(gfp, vbr_off);
+ return preset;
+ }
+ }
+
+ gfp->preset = preset;
+ {
+ switch (preset) {
+ case V9:
+ apply_vbr_preset(gfp, 9, enforce);
+ return preset;
+ case V8:
+ apply_vbr_preset(gfp, 8, enforce);
+ return preset;
+ case V7:
+ apply_vbr_preset(gfp, 7, enforce);
+ return preset;
+ case V6:
+ apply_vbr_preset(gfp, 6, enforce);
+ return preset;
+ case V5:
+ apply_vbr_preset(gfp, 5, enforce);
+ return preset;
+ case V4:
+ apply_vbr_preset(gfp, 4, enforce);
+ return preset;
+ case V3:
+ apply_vbr_preset(gfp, 3, enforce);
+ return preset;
+ case V2:
+ apply_vbr_preset(gfp, 2, enforce);
+ return preset;
+ case V1:
+ apply_vbr_preset(gfp, 1, enforce);
+ return preset;
+ case V0:
+ apply_vbr_preset(gfp, 0, enforce);
+ return preset;
+ default:
+ break;
+ }
+ }
+ if (8 <= preset && preset <= 320) {
+ return apply_abr_preset(gfp, preset, enforce);
+ }
+
+ gfp->preset = 0; /*no corresponding preset found */
+ return preset;
+}
diff --git a/pkg/lame/clame/psymodel.c b/pkg/lame/clame/psymodel.c
new file mode 100644
index 0000000..60076ee
--- /dev/null
+++ b/pkg/lame/clame/psymodel.c
@@ -0,0 +1,2167 @@
+/*
+ * psymodel.c
+ *
+ * Copyright (c) 1999-2000 Mark Taylor
+ * Copyright (c) 2001-2002 Naoki Shibata
+ * Copyright (c) 2000-2003 Takehiro Tominaga
+ * Copyright (c) 2000-2012 Robert Hegemann
+ * Copyright (c) 2000-2005 Gabriel Bouvigne
+ * Copyright (c) 2000-2005 Alexander Leidinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: psymodel.c,v 1.216 2017/09/06 19:38:23 aleidinger Exp $ */
+
+
+/*
+PSYCHO ACOUSTICS
+
+
+This routine computes the psycho acoustics, delayed by one granule.
+
+Input: buffer of PCM data (1024 samples).
+
+This window should be centered over the 576 sample granule window.
+The routine will compute the psycho acoustics for
+this granule, but return the psycho acoustics computed
+for the *previous* granule. This is because the block
+type of the previous granule can only be determined
+after we have computed the psycho acoustics for the following
+granule.
+
+Output: maskings and energies for each scalefactor band.
+block type, PE, and some correlation measures.
+The PE is used by CBR modes to determine if extra bits
+from the bit reservoir should be used. The correlation
+measures are used to determine mid/side or regular stereo.
+*/
+/*
+Notation:
+
+barks: a non-linear frequency scale. Mapping from frequency to
+ barks is given by freq2bark()
+
+scalefactor bands: The spectrum (frequencies) are broken into
+ SBMAX "scalefactor bands". Thes bands
+ are determined by the MPEG ISO spec. In
+ the noise shaping/quantization code, we allocate
+ bits among the partition bands to achieve the
+ best possible quality
+
+partition bands: The spectrum is also broken into about
+ 64 "partition bands". Each partition
+ band is about .34 barks wide. There are about 2-5
+ partition bands for each scalefactor band.
+
+LAME computes all psycho acoustic information for each partition
+band. Then at the end of the computations, this information
+is mapped to scalefactor bands. The energy in each scalefactor
+band is taken as the sum of the energy in all partition bands
+which overlap the scalefactor band. The maskings can be computed
+in the same way (and thus represent the average masking in that band)
+or by taking the minmum value multiplied by the number of
+partition bands used (which represents a minimum masking in that band).
+*/
+/*
+The general outline is as follows:
+
+1. compute the energy in each partition band
+2. compute the tonality in each partition band
+3. compute the strength of each partion band "masker"
+4. compute the masking (via the spreading function applied to each masker)
+5. Modifications for mid/side masking.
+
+Each partition band is considiered a "masker". The strength
+of the i'th masker in band j is given by:
+
+ s3(bark(i)-bark(j))*strength(i)
+
+The strength of the masker is a function of the energy and tonality.
+The more tonal, the less masking. LAME uses a simple linear formula
+(controlled by NMT and TMN) which says the strength is given by the
+energy divided by a linear function of the tonality.
+*/
+/*
+s3() is the "spreading function". It is given by a formula
+determined via listening tests.
+
+The total masking in the j'th partition band is the sum over
+all maskings i. It is thus given by the convolution of
+the strength with s3(), the "spreading function."
+
+masking(j) = sum_over_i s3(i-j)*strength(i) = s3 o strength
+
+where "o" = convolution operator. s3 is given by a formula determined
+via listening tests. It is normalized so that s3 o 1 = 1.
+
+Note: instead of a simple convolution, LAME also has the
+option of using "additive masking"
+
+The most critical part is step 2, computing the tonality of each
+partition band. LAME has two tonality estimators. The first
+is based on the ISO spec, and measures how predictiable the
+signal is over time. The more predictable, the more tonal.
+The second measure is based on looking at the spectrum of
+a single granule. The more peaky the spectrum, the more
+tonal. By most indications, the latter approach is better.
+
+Finally, in step 5, the maskings for the mid and side
+channel are possibly increased. Under certain circumstances,
+noise in the mid & side channels is assumed to also
+be masked by strong maskers in the L or R channels.
+
+
+Other data computed by the psy-model:
+
+ms_ratio side-channel / mid-channel masking ratio (for previous granule)
+ms_ratio_next side-channel / mid-channel masking ratio for this granule
+
+percep_entropy[2] L and R values (prev granule) of PE - A measure of how
+ much pre-echo is in the previous granule
+percep_entropy_MS[2] mid and side channel values (prev granule) of percep_entropy
+energy[4] L,R,M,S energy in each channel, prev granule
+blocktype_d[2] block type to use for previous granule
+*/
+
+
+
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "psymodel.h"
+#include "lame_global_flags.h"
+#include "fft.h"
+#include "lame-analysis.h"
+
+
+#define NSFIRLEN 21
+
+#ifdef M_LN10
+#define LN_TO_LOG10 (M_LN10/10)
+#else
+#define LN_TO_LOG10 0.2302585093
+#endif
+
+
+/*
+ L3psycho_anal. Compute psycho acoustics.
+
+ Data returned to the calling program must be delayed by one
+ granule.
+
+ This is done in two places.
+ If we do not need to know the blocktype, the copying
+ can be done here at the top of the program: we copy the data for
+ the last granule (computed during the last call) before it is
+ overwritten with the new data. It looks like this:
+
+ 0. static psymodel_data
+ 1. calling_program_data = psymodel_data
+ 2. compute psymodel_data
+
+ For data which needs to know the blocktype, the copying must be
+ done at the end of this loop, and the old values must be saved:
+
+ 0. static psymodel_data_old
+ 1. compute psymodel_data
+ 2. compute possible block type of this granule
+ 3. compute final block type of previous granule based on #2.
+ 4. calling_program_data = psymodel_data_old
+ 5. psymodel_data_old = psymodel_data
+*/
+
+
+
+
+
+/* psycho_loudness_approx
+ jd - 2001 mar 12
+in: energy - BLKSIZE/2 elements of frequency magnitudes ^ 2
+ gfp - uses out_samplerate, ATHtype (also needed for ATHformula)
+returns: loudness^2 approximation, a positive value roughly tuned for a value
+ of 1.0 for signals near clipping.
+notes: When calibrated, feeding this function binary white noise at sample
+ values +32767 or -32768 should return values that approach 3.
+ ATHformula is used to approximate an equal loudness curve.
+future: Data indicates that the shape of the equal loudness curve varies
+ with intensity. This function might be improved by using an equal
+ loudness curve shaped for typical playback levels (instead of the
+ ATH, that is shaped for the threshold). A flexible realization might
+ simply bend the existing ATH curve to achieve the desired shape.
+ However, the potential gain may not be enough to justify an effort.
+*/
+static FLOAT
+psycho_loudness_approx(FLOAT const *energy, FLOAT const *eql_w)
+{
+ int i;
+ FLOAT loudness_power;
+
+ loudness_power = 0.0;
+ /* apply weights to power in freq. bands */
+ for (i = 0; i < BLKSIZE / 2; ++i)
+ loudness_power += energy[i] * eql_w[i];
+ loudness_power *= VO_SCALE;
+
+ return loudness_power;
+}
+
+/* mask_add optimization */
+/* init the limit values used to avoid computing log in mask_add when it is not necessary */
+
+/* For example, with i = 10*log10(m2/m1)/10*16 (= log10(m2/m1)*16)
+ *
+ * abs(i)>8 is equivalent (as i is an integer) to
+ * abs(i)>=9
+ * i>=9 || i<=-9
+ * equivalent to (as i is the biggest integer smaller than log10(m2/m1)*16
+ * or the smallest integer bigger than log10(m2/m1)*16 depending on the sign of log10(m2/m1)*16)
+ * log10(m2/m1)>=9/16 || log10(m2/m1)<=-9/16
+ * exp10 is strictly increasing thus this is equivalent to
+ * m2/m1 >= 10^(9/16) || m2/m1<=10^(-9/16) which are comparisons to constants
+ */
+
+
+#define I1LIMIT 8 /* as in if(i>8) */
+#define I2LIMIT 23 /* as in if(i>24) -> changed 23 */
+#define MLIMIT 15 /* as in if(m<15) */
+
+/* pow(10, (I1LIMIT + 1) / 16.0); */
+static const FLOAT ma_max_i1 = 3.6517412725483771;
+/* pow(10, (I2LIMIT + 1) / 16.0); */
+static const FLOAT ma_max_i2 = 31.622776601683793;
+/* pow(10, (MLIMIT) / 10.0); */
+static const FLOAT ma_max_m = 31.622776601683793;
+
+ /*This is the masking table:
+ According to tonality, values are going from 0dB (TMN)
+ to 9.3dB (NMT).
+ After additive masking computation, 8dB are added, so
+ final values are going from 8dB to 17.3dB
+ */
+static const FLOAT tab[] = {
+ 1.0 /*pow(10, -0) */ ,
+ 0.79433 /*pow(10, -0.1) */ ,
+ 0.63096 /*pow(10, -0.2) */ ,
+ 0.63096 /*pow(10, -0.2) */ ,
+ 0.63096 /*pow(10, -0.2) */ ,
+ 0.63096 /*pow(10, -0.2) */ ,
+ 0.63096 /*pow(10, -0.2) */ ,
+ 0.25119 /*pow(10, -0.6) */ ,
+ 0.11749 /*pow(10, -0.93) */
+};
+
+static const int tab_mask_add_delta[] = { 2, 2, 2, 1, 1, 1, 0, 0, -1 };
+#define STATIC_ASSERT_EQUAL_DIMENSION(A,B) enum{static_assert_##A=1/((dimension_of(A) == dimension_of(B))?1:0)}
+
+inline static int
+mask_add_delta(int i)
+{
+ STATIC_ASSERT_EQUAL_DIMENSION(tab_mask_add_delta,tab);
+ assert(i < (int)dimension_of(tab));
+ return tab_mask_add_delta[i];
+}
+
+
+static void
+init_mask_add_max_values(void)
+{
+#ifndef NDEBUG
+ FLOAT const _ma_max_i1 = pow(10, (I1LIMIT + 1) / 16.0);
+ FLOAT const _ma_max_i2 = pow(10, (I2LIMIT + 1) / 16.0);
+ FLOAT const _ma_max_m = pow(10, (MLIMIT) / 10.0);
+ assert(fabs(ma_max_i1 - _ma_max_i1) <= FLT_EPSILON);
+ assert(fabs(ma_max_i2 - _ma_max_i2) <= FLT_EPSILON);
+ assert(fabs(ma_max_m - _ma_max_m ) <= FLT_EPSILON);
+#endif
+}
+
+
+
+
+/* addition of simultaneous masking Naoki Shibata 2000/7 */
+inline static FLOAT
+vbrpsy_mask_add(FLOAT m1, FLOAT m2, int b, int delta)
+{
+ static const FLOAT table2[] = {
+ 1.33352 * 1.33352, 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497,
+ 1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, 1.22321 * 1.22321,
+ 1.14758 * 1.14758,
+ 1
+ };
+
+ FLOAT ratio;
+
+ if (m1 < 0) {
+ m1 = 0;
+ }
+ if (m2 < 0) {
+ m2 = 0;
+ }
+ if (m1 <= 0) {
+ return m2;
+ }
+ if (m2 <= 0) {
+ return m1;
+ }
+ if (m2 > m1) {
+ ratio = m2 / m1;
+ }
+ else {
+ ratio = m1 / m2;
+ }
+ if (abs(b) <= delta) { /* approximately, 1 bark = 3 partitions */
+ /* originally 'if(i > 8)' */
+ if (ratio >= ma_max_i1) {
+ return m1 + m2;
+ }
+ else {
+ int i = (int) (FAST_LOG10_X(ratio, 16.0f));
+ return (m1 + m2) * table2[i];
+ }
+ }
+ if (ratio < ma_max_i2) {
+ return m1 + m2;
+ }
+ if (m1 < m2) {
+ m1 = m2;
+ }
+ return m1;
+}
+
+
+/* short block threshold calculation (part 2)
+
+ partition band bo_s[sfb] is at the transition from scalefactor
+ band sfb to the next one sfb+1; enn and thmm have to be split
+ between them
+*/
+static void
+convert_partition2scalefac(PsyConst_CB2SB_t const *const gd, FLOAT const *eb, FLOAT const *thr,
+ FLOAT enn_out[], FLOAT thm_out[])
+{
+ FLOAT enn, thmm;
+ int sb, b, n = gd->n_sb;
+ enn = thmm = 0.0f;
+ for (sb = b = 0; sb < n; ++b, ++sb) {
+ int const bo_sb = gd->bo[sb];
+ int const npart = gd->npart;
+ int const b_lim = bo_sb < npart ? bo_sb : npart;
+ while (b < b_lim) {
+ assert(eb[b] >= 0); /* iff failed, it may indicate some index error elsewhere */
+ assert(thr[b] >= 0);
+ enn += eb[b];
+ thmm += thr[b];
+ b++;
+ }
+ if (b >= npart) {
+ enn_out[sb] = enn;
+ thm_out[sb] = thmm;
+ ++sb;
+ break;
+ }
+ assert(eb[b] >= 0); /* iff failed, it may indicate some index error elsewhere */
+ assert(thr[b] >= 0);
+ {
+ /* at transition sfb -> sfb+1 */
+ FLOAT const w_curr = gd->bo_weight[sb];
+ FLOAT const w_next = 1.0f - w_curr;
+ enn += w_curr * eb[b];
+ thmm += w_curr * thr[b];
+ enn_out[sb] = enn;
+ thm_out[sb] = thmm;
+ enn = w_next * eb[b];
+ thmm = w_next * thr[b];
+ }
+ }
+ /* zero initialize the rest */
+ for (; sb < n; ++sb) {
+ enn_out[sb] = 0;
+ thm_out[sb] = 0;
+ }
+}
+
+static void
+convert_partition2scalefac_s(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn,
+ int sblock)
+{
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;
+ FLOAT enn[SBMAX_s], thm[SBMAX_s];
+ int sb;
+ convert_partition2scalefac(gds, eb, thr, enn, thm);
+ for (sb = 0; sb < SBMAX_s; ++sb) {
+ psv->en[chn].s[sb][sblock] = enn[sb];
+ psv->thm[chn].s[sb][sblock] = thm[sb];
+ }
+}
+
+/* longblock threshold calculation (part 2) */
+static void
+convert_partition2scalefac_l(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn)
+{
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;
+ FLOAT *enn = &psv->en[chn].l[0];
+ FLOAT *thm = &psv->thm[chn].l[0];
+ convert_partition2scalefac(gdl, eb, thr, enn, thm);
+}
+
+static void
+convert_partition2scalefac_l_to_s(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr,
+ int chn)
+{
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->l_to_s;
+ FLOAT enn[SBMAX_s], thm[SBMAX_s];
+ int sb, sblock;
+ convert_partition2scalefac(gds, eb, thr, enn, thm);
+ for (sb = 0; sb < SBMAX_s; ++sb) {
+ FLOAT const scale = 1. / 64.f;
+ FLOAT const tmp_enn = enn[sb];
+ FLOAT const tmp_thm = thm[sb] * scale;
+ for (sblock = 0; sblock < 3; ++sblock) {
+ psv->en[chn].s[sb][sblock] = tmp_enn;
+ psv->thm[chn].s[sb][sblock] = tmp_thm;
+ }
+ }
+}
+
+
+
+static inline FLOAT
+NS_INTERP(FLOAT x, FLOAT y, FLOAT r)
+{
+ /* was pow((x),(r))*pow((y),1-(r)) */
+ if (r >= 1.0f)
+ return x; /* 99.7% of the time */
+ if (r <= 0.0f)
+ return y;
+ if (y > 0.0f)
+ return powf(x / y, r) * y; /* rest of the time */
+ return 0.0f; /* never happens */
+}
+
+
+
+static FLOAT
+pecalc_s(III_psy_ratio const *mr, FLOAT masking_lower)
+{
+ FLOAT pe_s;
+ static const FLOAT regcoef_s[] = {
+ 11.8, /* these values are tuned only for 44.1kHz... */
+ 13.6,
+ 17.2,
+ 32,
+ 46.5,
+ 51.3,
+ 57.5,
+ 67.1,
+ 71.5,
+ 84.6,
+ 97.6,
+ 130,
+/* 255.8 */
+ };
+ unsigned int sb, sblock;
+
+ pe_s = 1236.28f / 4;
+ for (sb = 0; sb < SBMAX_s - 1; sb++) {
+ for (sblock = 0; sblock < 3; sblock++) {
+ FLOAT const thm = mr->thm.s[sb][sblock];
+ assert(sb < dimension_of(regcoef_s));
+ if (thm > 0.0f) {
+ FLOAT const x = thm * masking_lower;
+ FLOAT const en = mr->en.s[sb][sblock];
+ if (en > x) {
+ if (en > x * 1e10f) {
+ pe_s += regcoef_s[sb] * (10.0f * LOG10);
+ }
+ else {
+ assert(x > 0);
+ pe_s += regcoef_s[sb] * FAST_LOG10(en / x);
+ }
+ }
+ }
+ }
+ }
+
+ return pe_s;
+}
+
+static FLOAT
+pecalc_l(III_psy_ratio const *mr, FLOAT masking_lower)
+{
+ FLOAT pe_l;
+ static const FLOAT regcoef_l[] = {
+ 6.8, /* these values are tuned only for 44.1kHz... */
+ 5.8,
+ 5.8,
+ 6.4,
+ 6.5,
+ 9.9,
+ 12.1,
+ 14.4,
+ 15,
+ 18.9,
+ 21.6,
+ 26.9,
+ 34.2,
+ 40.2,
+ 46.8,
+ 56.5,
+ 60.7,
+ 73.9,
+ 85.7,
+ 93.4,
+ 126.1,
+/* 241.3 */
+ };
+ unsigned int sb;
+
+ pe_l = 1124.23f / 4;
+ for (sb = 0; sb < SBMAX_l - 1; sb++) {
+ FLOAT const thm = mr->thm.l[sb];
+ assert(sb < dimension_of(regcoef_l));
+ if (thm > 0.0f) {
+ FLOAT const x = thm * masking_lower;
+ FLOAT const en = mr->en.l[sb];
+ if (en > x) {
+ if (en > x * 1e10f) {
+ pe_l += regcoef_l[sb] * (10.0f * LOG10);
+ }
+ else {
+ assert(x > 0);
+ pe_l += regcoef_l[sb] * FAST_LOG10(en / x);
+ }
+ }
+ }
+ }
+
+ return pe_l;
+}
+
+
+static void
+calc_energy(PsyConst_CB2SB_t const *l, FLOAT const *fftenergy, FLOAT * eb, FLOAT * max, FLOAT * avg)
+{
+ int b, j;
+
+ for (b = j = 0; b < l->npart; ++b) {
+ FLOAT ebb = 0, m = 0;
+ int i;
+ for (i = 0; i < l->numlines[b]; ++i, ++j) {
+ FLOAT const el = fftenergy[j];
+ assert(el >= 0);
+ ebb += el;
+ if (m < el)
+ m = el;
+ }
+ eb[b] = ebb;
+ max[b] = m;
+ avg[b] = ebb * l->rnumlines[b];
+ assert(l->rnumlines[b] >= 0);
+ assert(ebb >= 0);
+ assert(eb[b] >= 0);
+ assert(max[b] >= 0);
+ assert(avg[b] >= 0);
+ }
+}
+
+
+static void
+calc_mask_index_l(lame_internal_flags const *gfc, FLOAT const *max,
+ FLOAT const *avg, unsigned char *mask_idx)
+{
+ PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;
+ FLOAT m, a;
+ int b, k;
+ int const last_tab_entry = sizeof(tab) / sizeof(tab[0]) - 1;
+ b = 0;
+ a = avg[b] + avg[b + 1];
+ assert(a >= 0);
+ if (a > 0.0f) {
+ m = max[b];
+ if (m < max[b + 1])
+ m = max[b + 1];
+ assert((gdl->numlines[b] + gdl->numlines[b + 1] - 1) > 0);
+ a = 20.0f * (m * 2.0f - a)
+ / (a * (gdl->numlines[b] + gdl->numlines[b + 1] - 1));
+ k = (int) a;
+ if (k > last_tab_entry)
+ k = last_tab_entry;
+ mask_idx[b] = k;
+ }
+ else {
+ mask_idx[b] = 0;
+ }
+
+ for (b = 1; b < gdl->npart - 1; b++) {
+ a = avg[b - 1] + avg[b] + avg[b + 1];
+ assert(a >= 0);
+ if (a > 0.0f) {
+ m = max[b - 1];
+ if (m < max[b])
+ m = max[b];
+ if (m < max[b + 1])
+ m = max[b + 1];
+ assert((gdl->numlines[b - 1] + gdl->numlines[b] + gdl->numlines[b + 1] - 1) > 0);
+ a = 20.0f * (m * 3.0f - a)
+ / (a * (gdl->numlines[b - 1] + gdl->numlines[b] + gdl->numlines[b + 1] - 1));
+ k = (int) a;
+ if (k > last_tab_entry)
+ k = last_tab_entry;
+ mask_idx[b] = k;
+ }
+ else {
+ mask_idx[b] = 0;
+ }
+ }
+ assert(b > 0);
+ assert(b == gdl->npart - 1);
+
+ a = avg[b - 1] + avg[b];
+ assert(a >= 0);
+ if (a > 0.0f) {
+ m = max[b - 1];
+ if (m < max[b])
+ m = max[b];
+ assert((gdl->numlines[b - 1] + gdl->numlines[b] - 1) > 0);
+ a = 20.0f * (m * 2.0f - a)
+ / (a * (gdl->numlines[b - 1] + gdl->numlines[b] - 1));
+ k = (int) a;
+ if (k > last_tab_entry)
+ k = last_tab_entry;
+ mask_idx[b] = k;
+ }
+ else {
+ mask_idx[b] = 0;
+ }
+ assert(b == (gdl->npart - 1));
+}
+
+
+static void
+vbrpsy_compute_fft_l(lame_internal_flags * gfc, const sample_t * const buffer[2], int chn,
+ int gr_out, FLOAT fftenergy[HBLKSIZE], FLOAT(*wsamp_l)[BLKSIZE])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ PsyStateVar_t *psv = &gfc->sv_psy;
+ plotting_data *plt = cfg->analysis ? gfc->pinfo : 0;
+ int j;
+
+ if (chn < 2) {
+ fft_long(gfc, *wsamp_l, chn, buffer);
+ }
+ else if (chn == 2) {
+ FLOAT const sqrt2_half = SQRT2 * 0.5f;
+ /* FFT data for mid and side channel is derived from L & R */
+ for (j = BLKSIZE - 1; j >= 0; --j) {
+ FLOAT const l = wsamp_l[0][j];
+ FLOAT const r = wsamp_l[1][j];
+ wsamp_l[0][j] = (l + r) * sqrt2_half;
+ wsamp_l[1][j] = (l - r) * sqrt2_half;
+ }
+ }
+
+ /*********************************************************************
+ * compute energies
+ *********************************************************************/
+ fftenergy[0] = wsamp_l[0][0];
+ fftenergy[0] *= fftenergy[0];
+
+ for (j = BLKSIZE / 2 - 1; j >= 0; --j) {
+ FLOAT const re = (*wsamp_l)[BLKSIZE / 2 - j];
+ FLOAT const im = (*wsamp_l)[BLKSIZE / 2 + j];
+ fftenergy[BLKSIZE / 2 - j] = (re * re + im * im) * 0.5f;
+ }
+ /* total energy */
+ {
+ FLOAT totalenergy = 0.0f;
+ for (j = 11; j < HBLKSIZE; j++)
+ totalenergy += fftenergy[j];
+
+ psv->tot_ener[chn] = totalenergy;
+ }
+
+ if (plt) {
+ for (j = 0; j < HBLKSIZE; j++) {
+ plt->energy[gr_out][chn][j] = plt->energy_save[chn][j];
+ plt->energy_save[chn][j] = fftenergy[j];
+ }
+ }
+}
+
+
+static void
+vbrpsy_compute_fft_s(lame_internal_flags const *gfc, const sample_t * const buffer[2], int chn,
+ int sblock, FLOAT(*fftenergy_s)[HBLKSIZE_s], FLOAT(*wsamp_s)[3][BLKSIZE_s])
+{
+ int j;
+
+ if (sblock == 0 && chn < 2) {
+ fft_short(gfc, *wsamp_s, chn, buffer);
+ }
+ if (chn == 2) {
+ FLOAT const sqrt2_half = SQRT2 * 0.5f;
+ /* FFT data for mid and side channel is derived from L & R */
+ for (j = BLKSIZE_s - 1; j >= 0; --j) {
+ FLOAT const l = wsamp_s[0][sblock][j];
+ FLOAT const r = wsamp_s[1][sblock][j];
+ wsamp_s[0][sblock][j] = (l + r) * sqrt2_half;
+ wsamp_s[1][sblock][j] = (l - r) * sqrt2_half;
+ }
+ }
+
+ /*********************************************************************
+ * compute energies
+ *********************************************************************/
+ fftenergy_s[sblock][0] = (*wsamp_s)[sblock][0];
+ fftenergy_s[sblock][0] *= fftenergy_s[sblock][0];
+ for (j = BLKSIZE_s / 2 - 1; j >= 0; --j) {
+ FLOAT const re = (*wsamp_s)[sblock][BLKSIZE_s / 2 - j];
+ FLOAT const im = (*wsamp_s)[sblock][BLKSIZE_s / 2 + j];
+ fftenergy_s[sblock][BLKSIZE_s / 2 - j] = (re * re + im * im) * 0.5f;
+ }
+}
+
+
+ /*********************************************************************
+ * compute loudness approximation (used for ATH auto-level adjustment)
+ *********************************************************************/
+static void
+vbrpsy_compute_loudness_approximation_l(lame_internal_flags * gfc, int gr_out, int chn,
+ const FLOAT fftenergy[HBLKSIZE])
+{
+ PsyStateVar_t *psv = &gfc->sv_psy;
+ if (chn < 2) { /*no loudness for mid/side ch */
+ gfc->ov_psy.loudness_sq[gr_out][chn] = psv->loudness_sq_save[chn];
+ psv->loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc->ATH->eql_w);
+ }
+}
+
+
+ /**********************************************************************
+ * Apply HPF of fs/4 to the input signal.
+ * This is used for attack detection / handling.
+ **********************************************************************/
+static void
+vbrpsy_attack_detection(lame_internal_flags * gfc, const sample_t * const buffer[2], int gr_out,
+ III_psy_ratio masking_ratio[2][2], III_psy_ratio masking_MS_ratio[2][2],
+ FLOAT energy[4], FLOAT sub_short_factor[4][3], int ns_attacks[4][4],
+ int uselongblock[2])
+{
+ FLOAT ns_hpfsmpl[2][576];
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ plotting_data *plt = cfg->analysis ? gfc->pinfo : 0;
+ int const n_chn_out = cfg->channels_out;
+ /* chn=2 and 3 = Mid and Side channels */
+ int const n_chn_psy = (cfg->mode == JOINT_STEREO) ? 4 : n_chn_out;
+ int chn, i, j;
+
+ memset(&ns_hpfsmpl[0][0], 0, sizeof(ns_hpfsmpl));
+ /* Don't copy the input buffer into a temporary buffer */
+ /* unroll the loop 2 times */
+ for (chn = 0; chn < n_chn_out; chn++) {
+ static const FLOAT fircoef[] = {
+ -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,
+ -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2,
+ -5.52212e-17 * 2, -0.313819 * 2
+ };
+ /* apply high pass filter of fs/4 */
+ const sample_t *const firbuf = &buffer[chn][576 - 350 - NSFIRLEN + 192];
+ assert(dimension_of(fircoef) == ((NSFIRLEN - 1) / 2));
+ for (i = 0; i < 576; i++) {
+ FLOAT sum1, sum2;
+ sum1 = firbuf[i + 10];
+ sum2 = 0.0;
+ for (j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) {
+ sum1 += fircoef[j] * (firbuf[i + j] + firbuf[i + NSFIRLEN - j]);
+ sum2 += fircoef[j + 1] * (firbuf[i + j + 1] + firbuf[i + NSFIRLEN - j - 1]);
+ }
+ ns_hpfsmpl[chn][i] = sum1 + sum2;
+ }
+ masking_ratio[gr_out][chn].en = psv->en[chn];
+ masking_ratio[gr_out][chn].thm = psv->thm[chn];
+ if (n_chn_psy > 2) {
+ /* MS maskings */
+ /*percep_MS_entropy [chn-2] = gfc -> pe [chn]; */
+ masking_MS_ratio[gr_out][chn].en = psv->en[chn + 2];
+ masking_MS_ratio[gr_out][chn].thm = psv->thm[chn + 2];
+ }
+ }
+ for (chn = 0; chn < n_chn_psy; chn++) {
+ FLOAT attack_intensity[12];
+ FLOAT en_subshort[12];
+ FLOAT en_short[4] = { 0, 0, 0, 0 };
+ FLOAT const *pf = ns_hpfsmpl[chn & 1];
+ int ns_uselongblock = 1;
+
+ if (chn == 2) {
+ for (i = 0, j = 576; j > 0; ++i, --j) {
+ FLOAT const l = ns_hpfsmpl[0][i];
+ FLOAT const r = ns_hpfsmpl[1][i];
+ ns_hpfsmpl[0][i] = l + r;
+ ns_hpfsmpl[1][i] = l - r;
+ }
+ }
+ /***************************************************************
+ * determine the block type (window type)
+ ***************************************************************/
+ /* calculate energies of each sub-shortblocks */
+ for (i = 0; i < 3; i++) {
+ en_subshort[i] = psv->last_en_subshort[chn][i + 6];
+ assert(psv->last_en_subshort[chn][i + 4] > 0);
+ attack_intensity[i] = en_subshort[i] / psv->last_en_subshort[chn][i + 4];
+ en_short[0] += en_subshort[i];
+ }
+
+ for (i = 0; i < 9; i++) {
+ FLOAT const *const pfe = pf + 576 / 9;
+ FLOAT p = 1.;
+ for (; pf < pfe; pf++)
+ if (p < fabs(*pf))
+ p = fabs(*pf);
+ psv->last_en_subshort[chn][i] = en_subshort[i + 3] = p;
+ en_short[1 + i / 3] += p;
+ if (p > en_subshort[i + 3 - 2]) {
+ assert(en_subshort[i + 3 - 2] > 0);
+ p = p / en_subshort[i + 3 - 2];
+ }
+ else if (en_subshort[i + 3 - 2] > p * 10.0f) {
+ assert(p > 0);
+ p = en_subshort[i + 3 - 2] / (p * 10.0f);
+ }
+ else {
+ p = 0.0;
+ }
+ attack_intensity[i + 3] = p;
+ }
+
+ /* pulse like signal detection for fatboy.wav and so on */
+ for (i = 0; i < 3; ++i) {
+ FLOAT const enn =
+ en_subshort[i * 3 + 3] + en_subshort[i * 3 + 4] + en_subshort[i * 3 + 5];
+ FLOAT factor = 1.f;
+ if (en_subshort[i * 3 + 5] * 6 < enn) {
+ factor *= 0.5f;
+ if (en_subshort[i * 3 + 4] * 6 < enn) {
+ factor *= 0.5f;
+ }
+ }
+ sub_short_factor[chn][i] = factor;
+ }
+
+ if (plt) {
+ FLOAT x = attack_intensity[0];
+ for (i = 1; i < 12; i++) {
+ if (x < attack_intensity[i]) {
+ x = attack_intensity[i];
+ }
+ }
+ plt->ers[gr_out][chn] = plt->ers_save[chn];
+ plt->ers_save[chn] = x;
+ }
+
+ /* compare energies between sub-shortblocks */
+ {
+ FLOAT x = gfc->cd_psy->attack_threshold[chn];
+ for (i = 0; i < 12; i++) {
+ if (ns_attacks[chn][i / 3] == 0) {
+ if (attack_intensity[i] > x) {
+ ns_attacks[chn][i / 3] = (i % 3) + 1;
+ }
+ }
+ }
+ }
+ /* should have energy change between short blocks, in order to avoid periodic signals */
+ /* Good samples to show the effect are Trumpet test songs */
+ /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */
+ /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */
+ for (i = 1; i < 4; i++) {
+ FLOAT const u = en_short[i - 1];
+ FLOAT const v = en_short[i];
+ FLOAT const m = Max(u, v);
+ if (m < 40000) { /* (2) */
+ if (u < 1.7f * v && v < 1.7f * u) { /* (1) */
+ if (i == 1 && ns_attacks[chn][0] <= ns_attacks[chn][i]) {
+ ns_attacks[chn][0] = 0;
+ }
+ ns_attacks[chn][i] = 0;
+ }
+ }
+ }
+
+ if (ns_attacks[chn][0] <= psv->last_attacks[chn]) {
+ ns_attacks[chn][0] = 0;
+ }
+
+ if (psv->last_attacks[chn] == 3 ||
+ ns_attacks[chn][0] + ns_attacks[chn][1] + ns_attacks[chn][2] + ns_attacks[chn][3]) {
+ ns_uselongblock = 0;
+
+ if (ns_attacks[chn][1] && ns_attacks[chn][0]) {
+ ns_attacks[chn][1] = 0;
+ }
+ if (ns_attacks[chn][2] && ns_attacks[chn][1]) {
+ ns_attacks[chn][2] = 0;
+ }
+ if (ns_attacks[chn][3] && ns_attacks[chn][2]) {
+ ns_attacks[chn][3] = 0;
+ }
+ }
+
+ if (chn < 2) {
+ uselongblock[chn] = ns_uselongblock;
+ }
+ else {
+ if (ns_uselongblock == 0) {
+ uselongblock[0] = uselongblock[1] = 0;
+ }
+ }
+
+ /* there is a one granule delay. Copy maskings computed last call
+ * into masking_ratio to return to calling program.
+ */
+ energy[chn] = psv->tot_ener[chn];
+ }
+}
+
+
+static void
+vbrpsy_skip_masking_s(lame_internal_flags * gfc, int chn, int sblock)
+{
+ if (sblock == 0) {
+ FLOAT *nbs2 = &gfc->sv_psy.nb_s2[chn][0];
+ FLOAT *nbs1 = &gfc->sv_psy.nb_s1[chn][0];
+ int const n = gfc->cd_psy->s.npart;
+ int b;
+ for (b = 0; b < n; b++) {
+ nbs2[b] = nbs1[b];
+ }
+ }
+}
+
+
+static void
+vbrpsy_calc_mask_index_s(lame_internal_flags const *gfc, FLOAT const *max,
+ FLOAT const *avg, unsigned char *mask_idx)
+{
+ PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;
+ FLOAT m, a;
+ int b, k;
+ int const last_tab_entry = dimension_of(tab) - 1;
+ b = 0;
+ a = avg[b] + avg[b + 1];
+ assert(a >= 0);
+ if (a > 0.0f) {
+ m = max[b];
+ if (m < max[b + 1])
+ m = max[b + 1];
+ assert((gds->numlines[b] + gds->numlines[b + 1] - 1) > 0);
+ a = 20.0f * (m * 2.0f - a)
+ / (a * (gds->numlines[b] + gds->numlines[b + 1] - 1));
+ k = (int) a;
+ if (k > last_tab_entry)
+ k = last_tab_entry;
+ mask_idx[b] = k;
+ }
+ else {
+ mask_idx[b] = 0;
+ }
+
+ for (b = 1; b < gds->npart - 1; b++) {
+ a = avg[b - 1] + avg[b] + avg[b + 1];
+ assert(b + 1 < gds->npart);
+ assert(a >= 0);
+ if (a > 0.0) {
+ m = max[b - 1];
+ if (m < max[b])
+ m = max[b];
+ if (m < max[b + 1])
+ m = max[b + 1];
+ assert((gds->numlines[b - 1] + gds->numlines[b] + gds->numlines[b + 1] - 1) > 0);
+ a = 20.0f * (m * 3.0f - a)
+ / (a * (gds->numlines[b - 1] + gds->numlines[b] + gds->numlines[b + 1] - 1));
+ k = (int) a;
+ if (k > last_tab_entry)
+ k = last_tab_entry;
+ mask_idx[b] = k;
+ }
+ else {
+ mask_idx[b] = 0;
+ }
+ }
+ assert(b > 0);
+ assert(b == gds->npart - 1);
+
+ a = avg[b - 1] + avg[b];
+ assert(a >= 0);
+ if (a > 0.0f) {
+ m = max[b - 1];
+ if (m < max[b])
+ m = max[b];
+ assert((gds->numlines[b - 1] + gds->numlines[b] - 1) > 0);
+ a = 20.0f * (m * 2.0f - a)
+ / (a * (gds->numlines[b - 1] + gds->numlines[b] - 1));
+ k = (int) a;
+ if (k > last_tab_entry)
+ k = last_tab_entry;
+ mask_idx[b] = k;
+ }
+ else {
+ mask_idx[b] = 0;
+ }
+ assert(b == (gds->npart - 1));
+}
+
+
+static void
+vbrpsy_compute_masking_s(lame_internal_flags * gfc, const FLOAT(*fftenergy_s)[HBLKSIZE_s],
+ FLOAT * eb, FLOAT * thr, int chn, int sblock)
+{
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;
+ FLOAT max[CBANDS], avg[CBANDS];
+ int i, j, b;
+ unsigned char mask_idx_s[CBANDS];
+
+ memset(max, 0, sizeof(max));
+ memset(avg, 0, sizeof(avg));
+
+ for (b = j = 0; b < gds->npart; ++b) {
+ FLOAT ebb = 0, m = 0;
+ int const n = gds->numlines[b];
+ for (i = 0; i < n; ++i, ++j) {
+ FLOAT const el = fftenergy_s[sblock][j];
+ ebb += el;
+ if (m < el)
+ m = el;
+ }
+ eb[b] = ebb;
+ assert(ebb >= 0);
+ max[b] = m;
+ assert(n > 0);
+ avg[b] = ebb * gds->rnumlines[b];
+ assert(avg[b] >= 0);
+ }
+ assert(b == gds->npart);
+ assert(j == 129);
+ vbrpsy_calc_mask_index_s(gfc, max, avg, mask_idx_s);
+ for (j = b = 0; b < gds->npart; b++) {
+ int kk = gds->s3ind[b][0];
+ int const last = gds->s3ind[b][1];
+ int const delta = mask_add_delta(mask_idx_s[b]);
+ int dd, dd_n;
+ FLOAT x, ecb, avg_mask;
+ FLOAT const masking_lower = gds->masking_lower[b] * gfc->sv_qnt.masking_lower;
+
+ dd = mask_idx_s[kk];
+ dd_n = 1;
+ ecb = gds->s3[j] * eb[kk] * tab[mask_idx_s[kk]];
+ ++j, ++kk;
+ while (kk <= last) {
+ dd += mask_idx_s[kk];
+ dd_n += 1;
+ x = gds->s3[j] * eb[kk] * tab[mask_idx_s[kk]];
+ ecb = vbrpsy_mask_add(ecb, x, kk - b, delta);
+ ++j, ++kk;
+ }
+ dd = (1 + 2 * dd) / (2 * dd_n);
+ avg_mask = tab[dd] * 0.5f;
+ ecb *= avg_mask;
+#if 0 /* we can do PRE ECHO control now here, or do it later */
+ if (psv->blocktype_old[chn & 0x01] == SHORT_TYPE) {
+ /* limit calculated threshold by even older granule */
+ FLOAT const t1 = rpelev_s * psv->nb_s1[chn][b];
+ FLOAT const t2 = rpelev2_s * psv->nb_s2[chn][b];
+ FLOAT const tm = (t2 > 0) ? Min(ecb, t2) : ecb;
+ thr[b] = (t1 > 0) ? NS_INTERP(Min(tm, t1), ecb, 0.6) : ecb;
+ }
+ else {
+ /* limit calculated threshold by older granule */
+ FLOAT const t1 = rpelev_s * psv->nb_s1[chn][b];
+ thr[b] = (t1 > 0) ? NS_INTERP(Min(ecb, t1), ecb, 0.6) : ecb;
+ }
+#else /* we do it later */
+ thr[b] = ecb;
+#endif
+ psv->nb_s2[chn][b] = psv->nb_s1[chn][b];
+ psv->nb_s1[chn][b] = ecb;
+ {
+ /* if THR exceeds EB, the quantization routines will take the difference
+ * from other bands. in case of strong tonal samples (tonaltest.wav)
+ * this leads to heavy distortions. that's why we limit THR here.
+ */
+ x = max[b];
+ x *= gds->minval[b];
+ x *= avg_mask;
+ if (thr[b] > x) {
+ thr[b] = x;
+ }
+ }
+ if (masking_lower > 1) {
+ thr[b] *= masking_lower;
+ }
+ if (thr[b] > eb[b]) {
+ thr[b] = eb[b];
+ }
+ if (masking_lower < 1) {
+ thr[b] *= masking_lower;
+ }
+
+ assert(thr[b] >= 0);
+ }
+ for (; b < CBANDS; ++b) {
+ eb[b] = 0;
+ thr[b] = 0;
+ }
+}
+
+
+static void
+vbrpsy_compute_masking_l(lame_internal_flags * gfc, const FLOAT fftenergy[HBLKSIZE],
+ FLOAT eb_l[CBANDS], FLOAT thr[CBANDS], int chn)
+{
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;
+ FLOAT max[CBANDS], avg[CBANDS];
+ unsigned char mask_idx_l[CBANDS + 2];
+ int k, b;
+
+ /*********************************************************************
+ * Calculate the energy and the tonality of each partition.
+ *********************************************************************/
+ calc_energy(gdl, fftenergy, eb_l, max, avg);
+ calc_mask_index_l(gfc, max, avg, mask_idx_l);
+
+ /*********************************************************************
+ * convolve the partitioned energy and unpredictability
+ * with the spreading function, s3_l[b][k]
+ ********************************************************************/
+ k = 0;
+ for (b = 0; b < gdl->npart; b++) {
+ FLOAT x, ecb, avg_mask, t;
+ FLOAT const masking_lower = gdl->masking_lower[b] * gfc->sv_qnt.masking_lower;
+ /* convolve the partitioned energy with the spreading function */
+ int kk = gdl->s3ind[b][0];
+ int const last = gdl->s3ind[b][1];
+ int const delta = mask_add_delta(mask_idx_l[b]);
+ int dd = 0, dd_n = 0;
+
+ dd = mask_idx_l[kk];
+ dd_n += 1;
+ ecb = gdl->s3[k] * eb_l[kk] * tab[mask_idx_l[kk]];
+ ++k, ++kk;
+ while (kk <= last) {
+ dd += mask_idx_l[kk];
+ dd_n += 1;
+ x = gdl->s3[k] * eb_l[kk] * tab[mask_idx_l[kk]];
+ t = vbrpsy_mask_add(ecb, x, kk - b, delta);
+#if 0
+ ecb += eb_l[kk];
+ if (ecb > t) {
+ ecb = t;
+ }
+#else
+ ecb = t;
+#endif
+ ++k, ++kk;
+ }
+ dd = (1 + 2 * dd) / (2 * dd_n);
+ avg_mask = tab[dd] * 0.5f;
+ ecb *= avg_mask;
+
+ /**** long block pre-echo control ****/
+ /* dont use long block pre-echo control if previous granule was
+ * a short block. This is to avoid the situation:
+ * frame0: quiet (very low masking)
+ * frame1: surge (triggers short blocks)
+ * frame2: regular frame. looks like pre-echo when compared to
+ * frame0, but all pre-echo was in frame1.
+ */
+ /* chn=0,1 L and R channels
+ chn=2,3 S and M channels.
+ */
+ if (psv->blocktype_old[chn & 0x01] == SHORT_TYPE) {
+ FLOAT const ecb_limit = rpelev * psv->nb_l1[chn][b];
+ if (ecb_limit > 0) {
+ thr[b] = Min(ecb, ecb_limit);
+ }
+ else {
+ /* Robert 071209:
+ Because we don't calculate long block psy when we know a granule
+ should be of short blocks, we don't have any clue how the granule
+ before would have looked like as a long block. So we have to guess
+ a little bit for this END_TYPE block.
+ Most of the time we get away with this sloppyness. (fingers crossed :)
+ The speed increase is worth it.
+ */
+ thr[b] = Min(ecb, eb_l[b] * NS_PREECHO_ATT2);
+ }
+ }
+ else {
+ FLOAT ecb_limit_2 = rpelev2 * psv->nb_l2[chn][b];
+ FLOAT ecb_limit_1 = rpelev * psv->nb_l1[chn][b];
+ FLOAT ecb_limit;
+ if (ecb_limit_2 <= 0) {
+ ecb_limit_2 = ecb;
+ }
+ if (ecb_limit_1 <= 0) {
+ ecb_limit_1 = ecb;
+ }
+ if (psv->blocktype_old[chn & 0x01] == NORM_TYPE) {
+ ecb_limit = Min(ecb_limit_1, ecb_limit_2);
+ }
+ else {
+ ecb_limit = ecb_limit_1;
+ }
+ thr[b] = Min(ecb, ecb_limit);
+ }
+ psv->nb_l2[chn][b] = psv->nb_l1[chn][b];
+ psv->nb_l1[chn][b] = ecb;
+ {
+ /* if THR exceeds EB, the quantization routines will take the difference
+ * from other bands. in case of strong tonal samples (tonaltest.wav)
+ * this leads to heavy distortions. that's why we limit THR here.
+ */
+ x = max[b];
+ x *= gdl->minval[b];
+ x *= avg_mask;
+ if (thr[b] > x) {
+ thr[b] = x;
+ }
+ }
+ if (masking_lower > 1) {
+ thr[b] *= masking_lower;
+ }
+ if (thr[b] > eb_l[b]) {
+ thr[b] = eb_l[b];
+ }
+ if (masking_lower < 1) {
+ thr[b] *= masking_lower;
+ }
+ assert(thr[b] >= 0);
+ }
+ for (; b < CBANDS; ++b) {
+ eb_l[b] = 0;
+ thr[b] = 0;
+ }
+}
+
+
+static void
+vbrpsy_compute_block_type(SessionConfig_t const *cfg, int *uselongblock)
+{
+ int chn;
+
+ if (cfg->short_blocks == short_block_coupled
+ /* force both channels to use the same block type */
+ /* this is necessary if the frame is to be encoded in ms_stereo. */
+ /* But even without ms_stereo, FhG does this */
+ && !(uselongblock[0] && uselongblock[1]))
+ uselongblock[0] = uselongblock[1] = 0;
+
+ for (chn = 0; chn < cfg->channels_out; chn++) {
+ /* disable short blocks */
+ if (cfg->short_blocks == short_block_dispensed) {
+ uselongblock[chn] = 1;
+ }
+ if (cfg->short_blocks == short_block_forced) {
+ uselongblock[chn] = 0;
+ }
+ }
+}
+
+
+static void
+vbrpsy_apply_block_type(PsyStateVar_t * psv, int nch, int const *uselongblock, int *blocktype_d)
+{
+ int chn;
+
+ /* update the blocktype of the previous granule, since it depends on what
+ * happend in this granule */
+ for (chn = 0; chn < nch; chn++) {
+ int blocktype = NORM_TYPE;
+ /* disable short blocks */
+
+ if (uselongblock[chn]) {
+ /* no attack : use long blocks */
+ assert(psv->blocktype_old[chn] != START_TYPE);
+ if (psv->blocktype_old[chn] == SHORT_TYPE)
+ blocktype = STOP_TYPE;
+ }
+ else {
+ /* attack : use short blocks */
+ blocktype = SHORT_TYPE;
+ if (psv->blocktype_old[chn] == NORM_TYPE) {
+ psv->blocktype_old[chn] = START_TYPE;
+ }
+ if (psv->blocktype_old[chn] == STOP_TYPE)
+ psv->blocktype_old[chn] = SHORT_TYPE;
+ }
+
+ blocktype_d[chn] = psv->blocktype_old[chn]; /* value returned to calling program */
+ psv->blocktype_old[chn] = blocktype; /* save for next call to l3psy_anal */
+ }
+}
+
+
+/***************************************************************
+ * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper
+ ***************************************************************/
+
+static void
+vbrpsy_compute_MS_thresholds(const FLOAT eb[4][CBANDS], FLOAT thr[4][CBANDS],
+ const FLOAT cb_mld[CBANDS], const FLOAT ath_cb[CBANDS], FLOAT athlower,
+ FLOAT msfix, int n)
+{
+ FLOAT const msfix2 = msfix * 2.f;
+ FLOAT rside, rmid;
+ int b;
+ for (b = 0; b < n; ++b) {
+ FLOAT const ebM = eb[2][b];
+ FLOAT const ebS = eb[3][b];
+ FLOAT const thmL = thr[0][b];
+ FLOAT const thmR = thr[1][b];
+ FLOAT thmM = thr[2][b];
+ FLOAT thmS = thr[3][b];
+
+ /* use this fix if L & R masking differs by 2db or less */
+ /* if db = 10*log10(x2/x1) < 2 */
+ /* if (x2 < 1.58*x1) { */
+ if (thmL <= 1.58f * thmR && thmR <= 1.58f * thmL) {
+ FLOAT const mld_m = cb_mld[b] * ebS;
+ FLOAT const mld_s = cb_mld[b] * ebM;
+ FLOAT const tmp_m = Min(thmS, mld_m);
+ FLOAT const tmp_s = Min(thmM, mld_s);
+ rmid = Max(thmM, tmp_m);
+ rside = Max(thmS, tmp_s);
+ }
+ else {
+ rmid = thmM;
+ rside = thmS;
+ }
+ if (msfix > 0.f) {
+ /***************************************************************/
+ /* Adjust M/S maskings if user set "msfix" */
+ /***************************************************************/
+ /* Naoki Shibata 2000 */
+ FLOAT thmLR, thmMS;
+ FLOAT const ath = ath_cb[b] * athlower;
+ FLOAT const tmp_l = Max(thmL, ath);
+ FLOAT const tmp_r = Max(thmR, ath);
+ thmLR = Min(tmp_l, tmp_r);
+ thmM = Max(rmid, ath);
+ thmS = Max(rside, ath);
+ thmMS = thmM + thmS;
+ if (thmMS > 0.f && (thmLR * msfix2) < thmMS) {
+ FLOAT const f = thmLR * msfix2 / thmMS;
+ thmM *= f;
+ thmS *= f;
+ assert(thmMS > 0.f);
+ }
+ rmid = Min(thmM, rmid);
+ rside = Min(thmS, rside);
+ }
+ if (rmid > ebM) {
+ rmid = ebM;
+ }
+ if (rside > ebS) {
+ rside = ebS;
+ }
+ thr[2][b] = rmid;
+ thr[3][b] = rside;
+ }
+}
+
+
+/*
+ * NOTE: the bitrate reduction from the inter-channel masking effect is low
+ * compared to the chance of getting annyoing artefacts. L3psycho_anal_vbr does
+ * not use this feature. (Robert 071216)
+*/
+
+int
+L3psycho_anal_vbr(lame_internal_flags * gfc,
+ const sample_t * const buffer[2], int gr_out,
+ III_psy_ratio masking_ratio[2][2],
+ III_psy_ratio masking_MS_ratio[2][2],
+ FLOAT percep_entropy[2], FLOAT percep_MS_entropy[2],
+ FLOAT energy[4], int blocktype_d[2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;
+ PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;
+ plotting_data *plt = cfg->analysis ? gfc->pinfo : 0;
+
+ III_psy_xmin last_thm[4];
+
+ /* fft and energy calculation */
+ FLOAT(*wsamp_l)[BLKSIZE];
+ FLOAT(*wsamp_s)[3][BLKSIZE_s];
+ FLOAT fftenergy[HBLKSIZE];
+ FLOAT fftenergy_s[3][HBLKSIZE_s];
+ FLOAT wsamp_L[2][BLKSIZE];
+ FLOAT wsamp_S[2][3][BLKSIZE_s];
+ FLOAT eb[4][CBANDS], thr[4][CBANDS];
+
+ FLOAT sub_short_factor[4][3];
+ FLOAT thmm;
+ FLOAT const pcfact = 0.6f;
+ FLOAT const ath_factor =
+ (cfg->msfix > 0.f) ? (cfg->ATH_offset_factor * gfc->ATH->adjust_factor) : 1.f;
+
+ const FLOAT(*const_eb)[CBANDS] = (const FLOAT(*)[CBANDS]) eb;
+ const FLOAT(*const_fftenergy_s)[HBLKSIZE_s] = (const FLOAT(*)[HBLKSIZE_s]) fftenergy_s;
+
+ /* block type */
+ int ns_attacks[4][4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} };
+ int uselongblock[2];
+
+ /* usual variables like loop indices, etc.. */
+ int chn, sb, sblock;
+
+ /* chn=2 and 3 = Mid and Side channels */
+ int const n_chn_psy = (cfg->mode == JOINT_STEREO) ? 4 : cfg->channels_out;
+
+ memcpy(&last_thm[0], &psv->thm[0], sizeof(last_thm));
+
+ vbrpsy_attack_detection(gfc, buffer, gr_out, masking_ratio, masking_MS_ratio, energy,
+ sub_short_factor, ns_attacks, uselongblock);
+
+ vbrpsy_compute_block_type(cfg, uselongblock);
+
+ /* LONG BLOCK CASE */
+ {
+ for (chn = 0; chn < n_chn_psy; chn++) {
+ int const ch01 = chn & 0x01;
+
+ wsamp_l = wsamp_L + ch01;
+ vbrpsy_compute_fft_l(gfc, buffer, chn, gr_out, fftenergy, wsamp_l);
+ vbrpsy_compute_loudness_approximation_l(gfc, gr_out, chn, fftenergy);
+ vbrpsy_compute_masking_l(gfc, fftenergy, eb[chn], thr[chn], chn);
+ }
+ if (cfg->mode == JOINT_STEREO) {
+ if ((uselongblock[0] + uselongblock[1]) == 2) {
+ vbrpsy_compute_MS_thresholds(const_eb, thr, gdl->mld_cb, gfc->ATH->cb_l,
+ ath_factor, cfg->msfix, gdl->npart);
+ }
+ }
+ /* TODO: apply adaptive ATH masking here ?? */
+ for (chn = 0; chn < n_chn_psy; chn++) {
+ convert_partition2scalefac_l(gfc, eb[chn], thr[chn], chn);
+ convert_partition2scalefac_l_to_s(gfc, eb[chn], thr[chn], chn);
+ }
+ }
+ /* SHORT BLOCKS CASE */
+ {
+ int const force_short_block_calc = gfc->cd_psy->force_short_block_calc;
+ for (sblock = 0; sblock < 3; sblock++) {
+ for (chn = 0; chn < n_chn_psy; ++chn) {
+ int const ch01 = chn & 0x01;
+ if (uselongblock[ch01] && !force_short_block_calc) {
+ vbrpsy_skip_masking_s(gfc, chn, sblock);
+ }
+ else {
+ /* compute masking thresholds for short blocks */
+ wsamp_s = wsamp_S + ch01;
+ vbrpsy_compute_fft_s(gfc, buffer, chn, sblock, fftenergy_s, wsamp_s);
+ vbrpsy_compute_masking_s(gfc, const_fftenergy_s, eb[chn], thr[chn], chn,
+ sblock);
+ }
+ }
+ if (cfg->mode == JOINT_STEREO) {
+ if ((uselongblock[0] + uselongblock[1]) == 0) {
+ vbrpsy_compute_MS_thresholds(const_eb, thr, gds->mld_cb, gfc->ATH->cb_s,
+ ath_factor, cfg->msfix, gds->npart);
+ }
+ }
+ /* TODO: apply adaptive ATH masking here ?? */
+ for (chn = 0; chn < n_chn_psy; ++chn) {
+ int const ch01 = chn & 0x01;
+ if (!uselongblock[ch01] || force_short_block_calc) {
+ convert_partition2scalefac_s(gfc, eb[chn], thr[chn], chn, sblock);
+ }
+ }
+ }
+
+ /**** short block pre-echo control ****/
+ for (chn = 0; chn < n_chn_psy; chn++) {
+ for (sb = 0; sb < SBMAX_s; sb++) {
+ FLOAT new_thmm[3], prev_thm, t1, t2;
+ for (sblock = 0; sblock < 3; sblock++) {
+ thmm = psv->thm[chn].s[sb][sblock];
+ thmm *= NS_PREECHO_ATT0;
+
+ t1 = t2 = thmm;
+
+ if (sblock > 0) {
+ prev_thm = new_thmm[sblock - 1];
+ }
+ else {
+ prev_thm = last_thm[chn].s[sb][2];
+ }
+ if (ns_attacks[chn][sblock] >= 2 || ns_attacks[chn][sblock + 1] == 1) {
+ t1 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT1 * pcfact);
+ }
+ thmm = Min(t1, thmm);
+ if (ns_attacks[chn][sblock] == 1) {
+ t2 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT2 * pcfact);
+ }
+ else if ((sblock == 0 && psv->last_attacks[chn] == 3)
+ || (sblock > 0 && ns_attacks[chn][sblock - 1] == 3)) { /* 2nd preceeding block */
+ switch (sblock) {
+ case 0:
+ prev_thm = last_thm[chn].s[sb][1];
+ break;
+ case 1:
+ prev_thm = last_thm[chn].s[sb][2];
+ break;
+ case 2:
+ prev_thm = new_thmm[0];
+ break;
+ }
+ t2 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT2 * pcfact);
+ }
+
+ thmm = Min(t1, thmm);
+ thmm = Min(t2, thmm);
+
+ /* pulse like signal detection for fatboy.wav and so on */
+ thmm *= sub_short_factor[chn][sblock];
+
+ new_thmm[sblock] = thmm;
+ }
+ for (sblock = 0; sblock < 3; sblock++) {
+ psv->thm[chn].s[sb][sblock] = new_thmm[sblock];
+ }
+ }
+ }
+ }
+ for (chn = 0; chn < n_chn_psy; chn++) {
+ psv->last_attacks[chn] = ns_attacks[chn][2];
+ }
+
+
+ /***************************************************************
+ * determine final block type
+ ***************************************************************/
+ vbrpsy_apply_block_type(psv, cfg->channels_out, uselongblock, blocktype_d);
+
+ /*********************************************************************
+ * compute the value of PE to return ... no delay and advance
+ *********************************************************************/
+ for (chn = 0; chn < n_chn_psy; chn++) {
+ FLOAT *ppe;
+ int type;
+ III_psy_ratio const *mr;
+
+ if (chn > 1) {
+ ppe = percep_MS_entropy - 2;
+ type = NORM_TYPE;
+ if (blocktype_d[0] == SHORT_TYPE || blocktype_d[1] == SHORT_TYPE)
+ type = SHORT_TYPE;
+ mr = &masking_MS_ratio[gr_out][chn - 2];
+ }
+ else {
+ ppe = percep_entropy;
+ type = blocktype_d[chn];
+ mr = &masking_ratio[gr_out][chn];
+ }
+ if (type == SHORT_TYPE) {
+ ppe[chn] = pecalc_s(mr, gfc->sv_qnt.masking_lower);
+ }
+ else {
+ ppe[chn] = pecalc_l(mr, gfc->sv_qnt.masking_lower);
+ }
+
+ if (plt) {
+ plt->pe[gr_out][chn] = ppe[chn];
+ }
+ }
+ return 0;
+}
+
+
+
+
+/*
+ * The spreading function. Values returned in units of energy
+ */
+static FLOAT
+s3_func(FLOAT bark)
+{
+ FLOAT tempx, x, tempy, temp;
+ tempx = bark;
+ if (tempx >= 0)
+ tempx *= 3;
+ else
+ tempx *= 1.5;
+
+ if (tempx >= 0.5 && tempx <= 2.5) {
+ temp = tempx - 0.5;
+ x = 8.0 * (temp * temp - 2.0 * temp);
+ }
+ else
+ x = 0.0;
+ tempx += 0.474;
+ tempy = 15.811389 + 7.5 * tempx - 17.5 * sqrt(1.0 + tempx * tempx);
+
+ if (tempy <= -60.0)
+ return 0.0;
+
+ tempx = exp((x + tempy) * LN_TO_LOG10);
+
+ /* Normalization. The spreading function should be normalized so that:
+ +inf
+ /
+ | s3 [ bark ] d(bark) = 1
+ /
+ -inf
+ */
+ tempx /= .6609193;
+ return tempx;
+}
+
+#if 0
+static FLOAT
+norm_s3_func(void)
+{
+ double lim_a = 0, lim_b = 0;
+ double x = 0, l, h;
+ for (x = 0; s3_func(x) > 1e-20; x -= 1);
+ l = x;
+ h = 0;
+ while (fabs(h - l) > 1e-12) {
+ x = (h + l) / 2;
+ if (s3_func(x) > 0) {
+ h = x;
+ }
+ else {
+ l = x;
+ }
+ }
+ lim_a = l;
+ for (x = 0; s3_func(x) > 1e-20; x += 1);
+ l = 0;
+ h = x;
+ while (fabs(h - l) > 1e-12) {
+ x = (h + l) / 2;
+ if (s3_func(x) > 0) {
+ l = x;
+ }
+ else {
+ h = x;
+ }
+ }
+ lim_b = h;
+ {
+ double sum = 0;
+ int const m = 1000;
+ int i;
+ for (i = 0; i <= m; ++i) {
+ double x = lim_a + i * (lim_b - lim_a) / m;
+ double y = s3_func(x);
+ sum += y;
+ }
+ {
+ double norm = (m + 1) / (sum * (lim_b - lim_a));
+ /*printf( "norm = %lf\n",norm); */
+ return norm;
+ }
+ }
+}
+#endif
+
+static FLOAT
+stereo_demask(double f)
+{
+ /* setup stereo demasking thresholds */
+ /* formula reverse enginerred from plot in paper */
+ double arg = freq2bark(f);
+ arg = (Min(arg, 15.5) / 15.5);
+
+ return pow(10.0, 1.25 * (1 - cos(PI * arg)) - 2.5);
+}
+
+static void
+init_numline(PsyConst_CB2SB_t * gd, FLOAT sfreq, int fft_size,
+ int mdct_size, int sbmax, int const *scalepos)
+{
+ FLOAT b_frq[CBANDS + 1];
+ FLOAT const mdct_freq_frac = sfreq / (2.0f * mdct_size);
+ FLOAT const deltafreq = fft_size / (2.0f * mdct_size);
+ int partition[HBLKSIZE] = { 0 };
+ int i, j, ni;
+ int sfb;
+ sfreq /= fft_size;
+ j = 0;
+ ni = 0;
+ /* compute numlines, the number of spectral lines in each partition band */
+ /* each partition band should be about DELBARK wide. */
+ for (i = 0; i < CBANDS; i++) {
+ FLOAT bark1;
+ int j2, nl;
+ bark1 = freq2bark(sfreq * j);
+
+ b_frq[i] = sfreq * j;
+
+ for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK && j2 <= fft_size / 2; j2++);
+
+ nl = j2 - j;
+ gd->numlines[i] = nl;
+ gd->rnumlines[i] = (nl > 0) ? (1.0f / nl) : 0;
+
+ ni = i + 1;
+
+ while (j < j2) {
+ assert(j < HBLKSIZE);
+ partition[j++] = i;
+ }
+ if (j > fft_size / 2) {
+ j = fft_size / 2;
+ ++i;
+ break;
+ }
+ }
+ assert(i < CBANDS);
+ b_frq[i] = sfreq * j;
+
+ gd->n_sb = sbmax;
+ gd->npart = ni;
+
+ {
+ j = 0;
+ for (i = 0; i < gd->npart; i++) {
+ int const nl = gd->numlines[i];
+ FLOAT const freq = sfreq * (j + nl / 2);
+ gd->mld_cb[i] = stereo_demask(freq);
+ j += nl;
+ }
+ for (; i < CBANDS; ++i) {
+ gd->mld_cb[i] = 1;
+ }
+ }
+ for (sfb = 0; sfb < sbmax; sfb++) {
+ int i1, i2, bo;
+ int start = scalepos[sfb];
+ int end = scalepos[sfb + 1];
+
+ i1 = floor(.5 + deltafreq * (start - .5));
+ if (i1 < 0)
+ i1 = 0;
+ i2 = floor(.5 + deltafreq * (end - .5));
+
+ if (i2 > fft_size / 2)
+ i2 = fft_size / 2;
+
+ bo = partition[i2];
+ gd->bm[sfb] = (partition[i1] + partition[i2]) / 2;
+ gd->bo[sfb] = bo;
+
+ /* calculate how much of this band belongs to current scalefactor band */
+ {
+ FLOAT const f_tmp = mdct_freq_frac * end;
+ FLOAT bo_w = (f_tmp - b_frq[bo]) / (b_frq[bo + 1] - b_frq[bo]);
+ if (bo_w < 0) {
+ bo_w = 0;
+ }
+ else {
+ if (bo_w > 1) {
+ bo_w = 1;
+ }
+ }
+ gd->bo_weight[sfb] = bo_w;
+ }
+ gd->mld[sfb] = stereo_demask(mdct_freq_frac * start);
+ }
+}
+
+static void
+compute_bark_values(PsyConst_CB2SB_t const *gd, FLOAT sfreq, int fft_size,
+ FLOAT * bval, FLOAT * bval_width)
+{
+ /* compute bark values of each critical band */
+ int k, j = 0, ni = gd->npart;
+ sfreq /= fft_size;
+ for (k = 0; k < ni; k++) {
+ int const w = gd->numlines[k];
+ FLOAT bark1, bark2;
+
+ bark1 = freq2bark(sfreq * (j));
+ bark2 = freq2bark(sfreq * (j + w - 1));
+ bval[k] = .5 * (bark1 + bark2);
+
+ bark1 = freq2bark(sfreq * (j - .5));
+ bark2 = freq2bark(sfreq * (j + w - .5));
+ bval_width[k] = bark2 - bark1;
+ j += w;
+ }
+}
+
+static int
+init_s3_values(FLOAT ** p, int (*s3ind)[2], int npart,
+ FLOAT const *bval, FLOAT const *bval_width, FLOAT const *norm)
+{
+ FLOAT s3[CBANDS][CBANDS];
+ /* The s3 array is not linear in the bark scale.
+ * bval[x] should be used to get the bark value.
+ */
+ int i, j, k;
+ int numberOfNoneZero = 0;
+
+ memset(&s3[0][0], 0, sizeof(s3));
+
+ /* s[i][j], the value of the spreading function,
+ * centered at band j (masker), for band i (maskee)
+ *
+ * i.e.: sum over j to spread into signal barkval=i
+ * NOTE: i and j are used opposite as in the ISO docs
+ */
+ for (i = 0; i < npart; i++) {
+ for (j = 0; j < npart; j++) {
+ FLOAT v = s3_func(bval[i] - bval[j]) * bval_width[j];
+ s3[i][j] = v * norm[i];
+ }
+ }
+ for (i = 0; i < npart; i++) {
+ for (j = 0; j < npart; j++) {
+ if (s3[i][j] > 0.0f)
+ break;
+ }
+ s3ind[i][0] = j;
+
+ for (j = npart - 1; j > 0; j--) {
+ if (s3[i][j] > 0.0f)
+ break;
+ }
+ s3ind[i][1] = j;
+ numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1);
+ }
+ *p = lame_calloc(FLOAT, numberOfNoneZero);
+ if (!*p)
+ return -1;
+
+ k = 0;
+ for (i = 0; i < npart; i++)
+ for (j = s3ind[i][0]; j <= s3ind[i][1]; j++)
+ (*p)[k++] = s3[i][j];
+
+ return 0;
+}
+
+int
+psymodel_init(lame_global_flags const *gfp)
+{
+ lame_internal_flags *const gfc = gfp->internal_flags;
+ SessionConfig_t *const cfg = &gfc->cfg;
+ PsyStateVar_t *const psv = &gfc->sv_psy;
+ PsyConst_t *gd;
+ int i, j, b, sb, k;
+ FLOAT bvl_a = 13, bvl_b = 24;
+ FLOAT snr_l_a = 0, snr_l_b = 0;
+ FLOAT snr_s_a = -8.25, snr_s_b = -4.5;
+
+ FLOAT bval[CBANDS];
+ FLOAT bval_width[CBANDS];
+ FLOAT norm[CBANDS];
+ FLOAT const sfreq = cfg->samplerate_out;
+
+ FLOAT xav = 10, xbv = 12;
+ FLOAT const minval_low = (0.f - cfg->minval);
+
+ if (gfc->cd_psy != 0) {
+ return 0;
+ }
+ memset(norm, 0, sizeof(norm));
+
+ gd = lame_calloc(PsyConst_t, 1);
+ gfc->cd_psy = gd;
+
+ gd->force_short_block_calc = gfp->experimentalZ;
+
+ psv->blocktype_old[0] = psv->blocktype_old[1] = NORM_TYPE; /* the vbr header is long blocks */
+
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < CBANDS; ++j) {
+ psv->nb_l1[i][j] = 1e20;
+ psv->nb_l2[i][j] = 1e20;
+ psv->nb_s1[i][j] = psv->nb_s2[i][j] = 1.0;
+ }
+ for (sb = 0; sb < SBMAX_l; sb++) {
+ psv->en[i].l[sb] = 1e20;
+ psv->thm[i].l[sb] = 1e20;
+ }
+ for (j = 0; j < 3; ++j) {
+ for (sb = 0; sb < SBMAX_s; sb++) {
+ psv->en[i].s[sb][j] = 1e20;
+ psv->thm[i].s[sb][j] = 1e20;
+ }
+ psv->last_attacks[i] = 0;
+ }
+ for (j = 0; j < 9; j++)
+ psv->last_en_subshort[i][j] = 10.;
+ }
+
+
+ /* init. for loudness approx. -jd 2001 mar 27 */
+ psv->loudness_sq_save[0] = psv->loudness_sq_save[1] = 0.0;
+
+
+
+ /*************************************************************************
+ * now compute the psychoacoustic model specific constants
+ ************************************************************************/
+ /* compute numlines, bo, bm, bval, bval_width, mld */
+ init_numline(&gd->l, sfreq, BLKSIZE, 576, SBMAX_l, gfc->scalefac_band.l);
+ assert(gd->l.npart < CBANDS);
+ compute_bark_values(&gd->l, sfreq, BLKSIZE, bval, bval_width);
+
+ /* compute the spreading function */
+ for (i = 0; i < gd->l.npart; i++) {
+ double snr = snr_l_a;
+ if (bval[i] >= bvl_a) {
+ snr = snr_l_b * (bval[i] - bvl_a) / (bvl_b - bvl_a)
+ + snr_l_a * (bvl_b - bval[i]) / (bvl_b - bvl_a);
+ }
+ norm[i] = pow(10.0, snr / 10.0);
+ }
+ i = init_s3_values(&gd->l.s3, gd->l.s3ind, gd->l.npart, bval, bval_width, norm);
+ if (i)
+ return i;
+
+ /* compute long block specific values, ATH and MINVAL */
+ j = 0;
+ for (i = 0; i < gd->l.npart; i++) {
+ double x;
+
+ /* ATH */
+ x = FLOAT_MAX;
+ for (k = 0; k < gd->l.numlines[i]; k++, j++) {
+ FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE);
+ FLOAT level;
+ /* freq = Min(.1,freq); *//* ATH below 100 Hz constant, not further climbing */
+ level = ATHformula(cfg, freq * 1000) - 20; /* scale to FFT units; returned value is in dB */
+ level = pow(10., 0.1 * level); /* convert from dB -> energy */
+ level *= gd->l.numlines[i];
+ if (x > level)
+ x = level;
+ }
+ gfc->ATH->cb_l[i] = x;
+
+ /* MINVAL.
+ For low freq, the strength of the masking is limited by minval
+ this is an ISO MPEG1 thing, dont know if it is really needed */
+ /* FIXME: it does work to reduce low-freq problems in S53-Wind-Sax
+ and lead-voice samples, but introduces some 3 kbps bit bloat too.
+ TODO: Further refinement of the shape of this hack.
+ */
+ x = 20.0 * (bval[i] / xav - 1.0);
+ if (x > 6) {
+ x = 30;
+ }
+ if (x < minval_low) {
+ x = minval_low;
+ }
+ if (cfg->samplerate_out < 44000) {
+ x = 30;
+ }
+ x -= 8.;
+ gd->l.minval[i] = pow(10.0, x / 10.) * gd->l.numlines[i];
+ }
+
+ /************************************************************************
+ * do the same things for short blocks
+ ************************************************************************/
+ init_numline(&gd->s, sfreq, BLKSIZE_s, 192, SBMAX_s, gfc->scalefac_band.s);
+ assert(gd->s.npart < CBANDS);
+ compute_bark_values(&gd->s, sfreq, BLKSIZE_s, bval, bval_width);
+
+ /* SNR formula. short block is normalized by SNR. is it still right ? */
+ j = 0;
+ for (i = 0; i < gd->s.npart; i++) {
+ double x;
+ double snr = snr_s_a;
+ if (bval[i] >= bvl_a) {
+ snr = snr_s_b * (bval[i] - bvl_a) / (bvl_b - bvl_a)
+ + snr_s_a * (bvl_b - bval[i]) / (bvl_b - bvl_a);
+ }
+ norm[i] = pow(10.0, snr / 10.0);
+
+ /* ATH */
+ x = FLOAT_MAX;
+ for (k = 0; k < gd->s.numlines[i]; k++, j++) {
+ FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE_s);
+ FLOAT level;
+ /* freq = Min(.1,freq); *//* ATH below 100 Hz constant, not further climbing */
+ level = ATHformula(cfg, freq * 1000) - 20; /* scale to FFT units; returned value is in dB */
+ level = pow(10., 0.1 * level); /* convert from dB -> energy */
+ level *= gd->s.numlines[i];
+ if (x > level)
+ x = level;
+ }
+ gfc->ATH->cb_s[i] = x;
+
+ /* MINVAL.
+ For low freq, the strength of the masking is limited by minval
+ this is an ISO MPEG1 thing, dont know if it is really needed */
+ x = 7.0 * (bval[i] / xbv - 1.0);
+ if (bval[i] > xbv) {
+ x *= 1 + log(1 + x) * 3.1;
+ }
+ if (bval[i] < xbv) {
+ x *= 1 + log(1 - x) * 2.3;
+ }
+ if (x > 6) {
+ x = 30;
+ }
+ if (x < minval_low) {
+ x = minval_low;
+ }
+ if (cfg->samplerate_out < 44000) {
+ x = 30;
+ }
+ x -= 8;
+ gd->s.minval[i] = pow(10.0, x / 10) * gd->s.numlines[i];
+ }
+
+ i = init_s3_values(&gd->s.s3, gd->s.s3ind, gd->s.npart, bval, bval_width, norm);
+ if (i)
+ return i;
+
+
+ init_mask_add_max_values();
+ init_fft(gfc);
+
+ /* setup temporal masking */
+ gd->decay = exp(-1.0 * LOG10 / (temporalmask_sustain_sec * sfreq / 192.0));
+
+ {
+ FLOAT msfix;
+ msfix = NS_MSFIX;
+ if (cfg->use_safe_joint_stereo)
+ msfix = 1.0;
+ if (fabs(cfg->msfix) > 0.0)
+ msfix = cfg->msfix;
+ cfg->msfix = msfix;
+
+ /* spread only from npart_l bands. Normally, we use the spreading
+ * function to convolve from npart_l down to npart_l bands
+ */
+ for (b = 0; b < gd->l.npart; b++)
+ if (gd->l.s3ind[b][1] > gd->l.npart - 1)
+ gd->l.s3ind[b][1] = gd->l.npart - 1;
+ }
+
+ /* prepare for ATH auto adjustment:
+ * we want to decrease the ATH by 12 dB per second
+ */
+#define frame_duration (576. * cfg->mode_gr / sfreq)
+ gfc->ATH->decay = pow(10., -12. / 10. * frame_duration);
+ gfc->ATH->adjust_factor = 0.01; /* minimum, for leading low loudness */
+ gfc->ATH->adjust_limit = 1.0; /* on lead, allow adjust up to maximum */
+#undef frame_duration
+
+ assert(gd->l.bo[SBMAX_l - 1] <= gd->l.npart);
+ assert(gd->s.bo[SBMAX_s - 1] <= gd->s.npart);
+
+ if (cfg->ATHtype != -1) {
+ /* compute equal loudness weights (eql_w) */
+ FLOAT freq;
+ FLOAT const freq_inc = (FLOAT) cfg->samplerate_out / (FLOAT) (BLKSIZE);
+ FLOAT eql_balance = 0.0;
+ freq = 0.0;
+ for (i = 0; i < BLKSIZE / 2; ++i) {
+ /* convert ATH dB to relative power (not dB) */
+ /* to determine eql_w */
+ freq += freq_inc;
+ gfc->ATH->eql_w[i] = 1. / pow(10, ATHformula(cfg, freq) / 10);
+ eql_balance += gfc->ATH->eql_w[i];
+ }
+ eql_balance = 1.0 / eql_balance;
+ for (i = BLKSIZE / 2; --i >= 0;) { /* scale weights */
+ gfc->ATH->eql_w[i] *= eql_balance;
+ }
+ }
+ {
+ for (b = j = 0; b < gd->s.npart; ++b) {
+ for (i = 0; i < gd->s.numlines[b]; ++i) {
+ ++j;
+ }
+ }
+ assert(j == 129);
+ for (b = j = 0; b < gd->l.npart; ++b) {
+ for (i = 0; i < gd->l.numlines[b]; ++i) {
+ ++j;
+ }
+ }
+ assert(j == 513);
+ }
+ /* short block attack threshold */
+ {
+ float x = gfp->attackthre;
+ float y = gfp->attackthre_s;
+ if (x < 0) {
+ x = NSATTACKTHRE;
+ }
+ if (y < 0) {
+ y = NSATTACKTHRE_S;
+ }
+ gd->attack_threshold[0] = gd->attack_threshold[1] = gd->attack_threshold[2] = x;
+ gd->attack_threshold[3] = y;
+ }
+ {
+ float sk_s = -10.f, sk_l = -4.7f;
+ static float const sk[] =
+ { -7.4, -7.4, -7.4, -9.5, -7.4, -6.1, -5.5, -4.7, -4.7, -4.7, -4.7 };
+ if (gfp->VBR_q < 4) {
+ sk_l = sk_s = sk[0];
+ }
+ else {
+ sk_l = sk_s = sk[gfp->VBR_q] + gfp->VBR_q_frac * (sk[gfp->VBR_q] - sk[gfp->VBR_q + 1]);
+ }
+ b = 0;
+ for (; b < gd->s.npart; b++) {
+ float m = (float) (gd->s.npart - b) / gd->s.npart;
+ gd->s.masking_lower[b] = powf(10.f, sk_s * m * 0.1f);
+ }
+ for (; b < CBANDS; ++b) {
+ gd->s.masking_lower[b] = 1.f;
+ }
+ b = 0;
+ for (; b < gd->l.npart; b++) {
+ float m = (float) (gd->l.npart - b) / gd->l.npart;
+ gd->l.masking_lower[b] = powf(10.f, sk_l * m * 0.1f);
+ }
+ for (; b < CBANDS; ++b) {
+ gd->l.masking_lower[b] = 1.f;
+ }
+ }
+ memcpy(&gd->l_to_s, &gd->l, sizeof(gd->l_to_s));
+ init_numline(&gd->l_to_s, sfreq, BLKSIZE, 192, SBMAX_s, gfc->scalefac_band.s);
+ return 0;
+}
diff --git a/pkg/lame/clame/psymodel.h b/pkg/lame/clame/psymodel.h
new file mode 100644
index 0000000..f46083c
--- /dev/null
+++ b/pkg/lame/clame/psymodel.h
@@ -0,0 +1,64 @@
+/*
+ * psymodel.h
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_PSYMODEL_H
+#define LAME_PSYMODEL_H
+
+
+int L3psycho_anal_ns(lame_internal_flags * gfc,
+ const sample_t *const buffer[2], int gr,
+ III_psy_ratio ratio[2][2],
+ III_psy_ratio MS_ratio[2][2],
+ FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]);
+
+int L3psycho_anal_vbr(lame_internal_flags * gfc,
+ const sample_t *const buffer[2], int gr,
+ III_psy_ratio ratio[2][2],
+ III_psy_ratio MS_ratio[2][2],
+ FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]);
+
+
+int psymodel_init(lame_global_flags const* gfp);
+
+
+#define rpelev 2
+#define rpelev2 16
+#define rpelev_s 2
+#define rpelev2_s 16
+
+/* size of each partition band, in barks: */
+#define DELBARK .34
+
+
+/* tuned for output level (sensitive to energy scale) */
+#define VO_SCALE (1./( 14752*14752 )/(BLKSIZE/2))
+
+#define temporalmask_sustain_sec 0.01
+
+#define NS_PREECHO_ATT0 0.8
+#define NS_PREECHO_ATT1 0.6
+#define NS_PREECHO_ATT2 0.3
+
+#define NS_MSFIX 3.5
+#define NSATTACKTHRE 4.4
+#define NSATTACKTHRE_S 25
+
+#endif /* LAME_PSYMODEL_H */
diff --git a/pkg/lame/clame/quantize.c b/pkg/lame/clame/quantize.c
new file mode 100644
index 0000000..9ba9c16
--- /dev/null
+++ b/pkg/lame/clame/quantize.c
@@ -0,0 +1,2050 @@
+/*
+ * MP3 quantization
+ *
+ * Copyright (c) 1999-2000 Mark Taylor
+ * Copyright (c) 1999-2003 Takehiro Tominaga
+ * Copyright (c) 2000-2011 Robert Hegemann
+ * Copyright (c) 2001-2005 Gabriel Bouvigne
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: quantize.c,v 1.219 2017/08/02 19:48:05 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "quantize_pvt.h"
+#include "reservoir.h"
+#include "bitstream.h"
+#include "vbrquantize.h"
+#include "quantize.h"
+#ifdef HAVE_XMMINTRIN_H
+#include "vector/lame_intrin.h"
+#endif
+
+
+
+
+/* convert from L/R <-> Mid/Side */
+static void
+ms_convert(III_side_info_t * l3_side, int gr)
+{
+ int i;
+ for (i = 0; i < 576; ++i) {
+ FLOAT l, r;
+ l = l3_side->tt[gr][0].xr[i];
+ r = l3_side->tt[gr][1].xr[i];
+ l3_side->tt[gr][0].xr[i] = (l + r) * (FLOAT) (SQRT2 * 0.5);
+ l3_side->tt[gr][1].xr[i] = (l - r) * (FLOAT) (SQRT2 * 0.5);
+ }
+}
+
+/************************************************************************
+ *
+ * init_outer_loop()
+ * mt 6/99
+ *
+ * initializes cod_info, scalefac and xrpow
+ *
+ * returns 0 if all energies in xr are zero, else 1
+ *
+ ************************************************************************/
+
+static void
+init_xrpow_core_c(gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum)
+{
+ int i;
+ FLOAT tmp;
+ *sum = 0;
+ for (i = 0; i <= upper; ++i) {
+ tmp = fabs(cod_info->xr[i]);
+ *sum += tmp;
+ xrpow[i] = sqrt(tmp * sqrt(tmp));
+
+ if (xrpow[i] > cod_info->xrpow_max)
+ cod_info->xrpow_max = xrpow[i];
+ }
+}
+
+
+
+
+
+void
+init_xrpow_core_init(lame_internal_flags * const gfc)
+{
+ gfc->init_xrpow_core = init_xrpow_core_c;
+
+#if defined(HAVE_XMMINTRIN_H)
+ if (gfc->CPU_features.SSE)
+ gfc->init_xrpow_core = init_xrpow_core_sse;
+#endif
+#ifndef HAVE_NASM
+#ifdef MIN_ARCH_SSE
+ gfc->init_xrpow_core = init_xrpow_core_sse;
+#endif
+#endif
+}
+
+
+
+static int
+init_xrpow(lame_internal_flags * gfc, gr_info * const cod_info, FLOAT xrpow[576])
+{
+ FLOAT sum = 0;
+ int i;
+ int const upper = cod_info->max_nonzero_coeff;
+
+ assert(xrpow != NULL);
+ cod_info->xrpow_max = 0;
+
+ /* check if there is some energy we have to quantize
+ * and calculate xrpow matching our fresh scalefactors
+ */
+ assert(0 <= upper && upper <= 575);
+ memset(&(xrpow[upper]), 0, (576 - upper) * sizeof(xrpow[0]));
+
+
+ gfc->init_xrpow_core(cod_info, xrpow, upper, &sum);
+
+ /* return 1 if we have something to quantize, else 0
+ */
+ if (sum > (FLOAT) 1E-20) {
+ int j = 0;
+ if (gfc->sv_qnt.substep_shaping & 2)
+ j = 1;
+
+ for (i = 0; i < cod_info->psymax; i++)
+ gfc->sv_qnt.pseudohalf[i] = j;
+
+ return 1;
+ }
+
+ memset(&cod_info->l3_enc[0], 0, sizeof(int) * 576);
+ return 0;
+}
+
+
+
+
+
+/*
+Gabriel Bouvigne feb/apr 2003
+Analog silence detection in partitionned sfb21
+or sfb12 for short blocks
+
+From top to bottom of sfb, changes to 0
+coeffs which are below ath. It stops on the first
+coeff higher than ath.
+*/
+static void
+psfb21_analogsilence(lame_internal_flags const *gfc, gr_info * const cod_info)
+{
+ ATH_t const *const ATH = gfc->ATH;
+ FLOAT *const xr = cod_info->xr;
+
+ if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT blocks */
+ int gsfb;
+ int stop = 0;
+ for (gsfb = PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) {
+ int const start = gfc->scalefac_band.psfb21[gsfb];
+ int const end = gfc->scalefac_band.psfb21[gsfb + 1];
+ int j;
+ FLOAT ath21;
+ ath21 = athAdjust(ATH->adjust_factor, ATH->psfb21[gsfb], ATH->floor, 0);
+
+ if (gfc->sv_qnt.longfact[21] > 1e-12f)
+ ath21 *= gfc->sv_qnt.longfact[21];
+
+ for (j = end - 1; j >= start; j--) {
+ if (fabs(xr[j]) < ath21)
+ xr[j] = 0;
+ else {
+ stop = 1;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ /*note: short blocks coeffs are reordered */
+ int block;
+ for (block = 0; block < 3; block++) {
+
+ int gsfb;
+ int stop = 0;
+ for (gsfb = PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) {
+ int const start = gfc->scalefac_band.s[12] * 3 +
+ (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]) * block +
+ (gfc->scalefac_band.psfb12[gsfb] - gfc->scalefac_band.psfb12[0]);
+ int const end =
+ start + (gfc->scalefac_band.psfb12[gsfb + 1] - gfc->scalefac_band.psfb12[gsfb]);
+ int j;
+ FLOAT ath12;
+ ath12 = athAdjust(ATH->adjust_factor, ATH->psfb12[gsfb], ATH->floor, 0);
+
+ if (gfc->sv_qnt.shortfact[12] > 1e-12f)
+ ath12 *= gfc->sv_qnt.shortfact[12];
+
+ for (j = end - 1; j >= start; j--) {
+ if (fabs(xr[j]) < ath12)
+ xr[j] = 0;
+ else {
+ stop = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+}
+
+
+
+
+
+static void
+init_outer_loop(lame_internal_flags const *gfc, gr_info * const cod_info)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int sfb, j;
+ /* initialize fresh cod_info
+ */
+ cod_info->part2_3_length = 0;
+ cod_info->big_values = 0;
+ cod_info->count1 = 0;
+ cod_info->global_gain = 210;
+ cod_info->scalefac_compress = 0;
+ /* mixed_block_flag, block_type was set in psymodel.c */
+ cod_info->table_select[0] = 0;
+ cod_info->table_select[1] = 0;
+ cod_info->table_select[2] = 0;
+ cod_info->subblock_gain[0] = 0;
+ cod_info->subblock_gain[1] = 0;
+ cod_info->subblock_gain[2] = 0;
+ cod_info->subblock_gain[3] = 0; /* this one is always 0 */
+ cod_info->region0_count = 0;
+ cod_info->region1_count = 0;
+ cod_info->preflag = 0;
+ cod_info->scalefac_scale = 0;
+ cod_info->count1table_select = 0;
+ cod_info->part2_length = 0;
+ if (cfg->samplerate_out <= 8000) {
+ cod_info->sfb_lmax = 17;
+ cod_info->sfb_smin = 9;
+ cod_info->psy_lmax = 17;
+ }
+ else {
+ cod_info->sfb_lmax = SBPSY_l;
+ cod_info->sfb_smin = SBPSY_s;
+ cod_info->psy_lmax = gfc->sv_qnt.sfb21_extra ? SBMAX_l : SBPSY_l;
+ }
+ cod_info->psymax = cod_info->psy_lmax;
+ cod_info->sfbmax = cod_info->sfb_lmax;
+ cod_info->sfbdivide = 11;
+ for (sfb = 0; sfb < SBMAX_l; sfb++) {
+ cod_info->width[sfb]
+ = gfc->scalefac_band.l[sfb + 1] - gfc->scalefac_band.l[sfb];
+ cod_info->window[sfb] = 3; /* which is always 0. */
+ }
+ if (cod_info->block_type == SHORT_TYPE) {
+ FLOAT ixwork[576];
+ FLOAT *ix;
+
+ cod_info->sfb_smin = 0;
+ cod_info->sfb_lmax = 0;
+ if (cod_info->mixed_block_flag) {
+ /*
+ * MPEG-1: sfbs 0-7 long block, 3-12 short blocks
+ * MPEG-2(.5): sfbs 0-5 long block, 3-12 short blocks
+ */
+ cod_info->sfb_smin = 3;
+ cod_info->sfb_lmax = cfg->mode_gr * 2 + 4;
+ }
+ if (cfg->samplerate_out <= 8000) {
+ cod_info->psymax
+ = cod_info->sfb_lmax
+ + 3 * (9 - cod_info->sfb_smin);
+ cod_info->sfbmax = cod_info->sfb_lmax + 3 * (9 - cod_info->sfb_smin);
+ }
+ else {
+ cod_info->psymax
+ = cod_info->sfb_lmax
+ + 3 * ((gfc->sv_qnt.sfb21_extra ? SBMAX_s : SBPSY_s) - cod_info->sfb_smin);
+ cod_info->sfbmax = cod_info->sfb_lmax + 3 * (SBPSY_s - cod_info->sfb_smin);
+ }
+ cod_info->sfbdivide = cod_info->sfbmax - 18;
+ cod_info->psy_lmax = cod_info->sfb_lmax;
+ /* re-order the short blocks, for more efficient encoding below */
+ /* By Takehiro TOMINAGA */
+ /*
+ Within each scalefactor band, data is given for successive
+ time windows, beginning with window 0 and ending with window 2.
+ Within each window, the quantized values are then arranged in
+ order of increasing frequency...
+ */
+ ix = &cod_info->xr[gfc->scalefac_band.l[cod_info->sfb_lmax]];
+ memcpy(ixwork, cod_info->xr, 576 * sizeof(FLOAT));
+ for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {
+ int const start = gfc->scalefac_band.s[sfb];
+ int const end = gfc->scalefac_band.s[sfb + 1];
+ int window, l;
+ for (window = 0; window < 3; window++) {
+ for (l = start; l < end; l++) {
+ *ix++ = ixwork[3 * l + window];
+ }
+ }
+ }
+
+ j = cod_info->sfb_lmax;
+ for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {
+ cod_info->width[j] = cod_info->width[j + 1] = cod_info->width[j + 2]
+ = gfc->scalefac_band.s[sfb + 1] - gfc->scalefac_band.s[sfb];
+ cod_info->window[j] = 0;
+ cod_info->window[j + 1] = 1;
+ cod_info->window[j + 2] = 2;
+ j += 3;
+ }
+ }
+
+ cod_info->count1bits = 0;
+ cod_info->sfb_partition_table = nr_of_sfb_block[0][0];
+ cod_info->slen[0] = 0;
+ cod_info->slen[1] = 0;
+ cod_info->slen[2] = 0;
+ cod_info->slen[3] = 0;
+
+ cod_info->max_nonzero_coeff = 575;
+
+ /* fresh scalefactors are all zero
+ */
+ memset(cod_info->scalefac, 0, sizeof(cod_info->scalefac));
+
+ if (cfg->vbr != vbr_mt && cfg->vbr != vbr_mtrh && cfg->vbr != vbr_abr && cfg->vbr != vbr_off) {
+ psfb21_analogsilence(gfc, cod_info);
+ }
+}
+
+
+
+/************************************************************************
+ *
+ * bin_search_StepSize()
+ *
+ * author/date??
+ *
+ * binary step size search
+ * used by outer_loop to get a quantizer step size to start with
+ *
+ ************************************************************************/
+
+typedef enum {
+ BINSEARCH_NONE,
+ BINSEARCH_UP,
+ BINSEARCH_DOWN
+} binsearchDirection_t;
+
+static int
+bin_search_StepSize(lame_internal_flags * const gfc, gr_info * const cod_info,
+ int desired_rate, const int ch, const FLOAT xrpow[576])
+{
+ int nBits;
+ int CurrentStep = gfc->sv_qnt.CurrentStep[ch];
+ int flag_GoneOver = 0;
+ int const start = gfc->sv_qnt.OldValue[ch];
+ binsearchDirection_t Direction = BINSEARCH_NONE;
+ cod_info->global_gain = start;
+ desired_rate -= cod_info->part2_length;
+
+ assert(CurrentStep);
+ for (;;) {
+ int step;
+ nBits = count_bits(gfc, xrpow, cod_info, 0);
+
+ if (CurrentStep == 1 || nBits == desired_rate)
+ break; /* nothing to adjust anymore */
+
+ if (nBits > desired_rate) {
+ /* increase Quantize_StepSize */
+ if (Direction == BINSEARCH_DOWN)
+ flag_GoneOver = 1;
+
+ if (flag_GoneOver)
+ CurrentStep /= 2;
+ Direction = BINSEARCH_UP;
+ step = CurrentStep;
+ }
+ else {
+ /* decrease Quantize_StepSize */
+ if (Direction == BINSEARCH_UP)
+ flag_GoneOver = 1;
+
+ if (flag_GoneOver)
+ CurrentStep /= 2;
+ Direction = BINSEARCH_DOWN;
+ step = -CurrentStep;
+ }
+ cod_info->global_gain += step;
+ if (cod_info->global_gain < 0) {
+ cod_info->global_gain = 0;
+ flag_GoneOver = 1;
+ }
+ if (cod_info->global_gain > 255) {
+ cod_info->global_gain = 255;
+ flag_GoneOver = 1;
+ }
+ }
+
+ assert(cod_info->global_gain >= 0);
+ assert(cod_info->global_gain < 256);
+
+ while (nBits > desired_rate && cod_info->global_gain < 255) {
+ cod_info->global_gain++;
+ nBits = count_bits(gfc, xrpow, cod_info, 0);
+ }
+ gfc->sv_qnt.CurrentStep[ch] = (start - cod_info->global_gain >= 4) ? 4 : 2;
+ gfc->sv_qnt.OldValue[ch] = cod_info->global_gain;
+ cod_info->part2_3_length = nBits;
+ return nBits;
+}
+
+
+
+
+/************************************************************************
+ *
+ * trancate_smallspectrums()
+ *
+ * Takehiro TOMINAGA 2002-07-21
+ *
+ * trancate smaller nubmers into 0 as long as the noise threshold is allowed.
+ *
+ ************************************************************************/
+static int
+floatcompare(const void *v1, const void *v2)
+{
+ const FLOAT *const a = v1, *const b = v2;
+ if (*a > *b)
+ return 1;
+ if (*a < *b)
+ return -1;
+ return 0;
+}
+
+static void
+trancate_smallspectrums(lame_internal_flags const *gfc,
+ gr_info * const gi, const FLOAT * const l3_xmin, FLOAT * const work)
+{
+ int sfb, j, width;
+ FLOAT distort[SFBMAX];
+ calc_noise_result dummy;
+
+ if ((!(gfc->sv_qnt.substep_shaping & 4) && gi->block_type == SHORT_TYPE)
+ || gfc->sv_qnt.substep_shaping & 0x80)
+ return;
+ (void) calc_noise(gi, l3_xmin, distort, &dummy, 0);
+ for (j = 0; j < 576; j++) {
+ FLOAT xr = 0.0;
+ if (gi->l3_enc[j] != 0)
+ xr = fabs(gi->xr[j]);
+ work[j] = xr;
+ }
+
+ j = 0;
+ sfb = 8;
+ if (gi->block_type == SHORT_TYPE)
+ sfb = 6;
+ do {
+ FLOAT allowedNoise, trancateThreshold;
+ int nsame, start;
+
+ width = gi->width[sfb];
+ j += width;
+ if (distort[sfb] >= 1.0)
+ continue;
+
+ qsort(&work[j - width], width, sizeof(FLOAT), floatcompare);
+ if (EQ(work[j - 1], 0.0))
+ continue; /* all zero sfb */
+
+ allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb];
+ trancateThreshold = 0.0;
+ start = 0;
+ do {
+ FLOAT noise;
+ for (nsame = 1; start + nsame < width; nsame++)
+ if (NEQ(work[start + j - width], work[start + j + nsame - width]))
+ break;
+
+ noise = work[start + j - width] * work[start + j - width] * nsame;
+ if (allowedNoise < noise) {
+ if (start != 0)
+ trancateThreshold = work[start + j - width - 1];
+ break;
+ }
+ allowedNoise -= noise;
+ start += nsame;
+ } while (start < width);
+ if (EQ(trancateThreshold, 0.0))
+ continue;
+
+/* printf("%e %e %e\n", */
+/* trancateThreshold/l3_xmin[sfb], */
+/* trancateThreshold/(l3_xmin[sfb]*start), */
+/* trancateThreshold/(l3_xmin[sfb]*(start+width)) */
+/* ); */
+/* if (trancateThreshold > 1000*l3_xmin[sfb]*start) */
+/* trancateThreshold = 1000*l3_xmin[sfb]*start; */
+
+ do {
+ if (fabs(gi->xr[j - width]) <= trancateThreshold)
+ gi->l3_enc[j - width] = 0;
+ } while (--width > 0);
+ } while (++sfb < gi->psymax);
+
+ gi->part2_3_length = noquant_count_bits(gfc, gi, 0);
+}
+
+
+/*************************************************************************
+ *
+ * loop_break()
+ *
+ * author/date??
+ *
+ * Function: Returns zero if there is a scalefac which has not been
+ * amplified. Otherwise it returns one.
+ *
+ *************************************************************************/
+
+inline static int
+loop_break(const gr_info * const cod_info)
+{
+ int sfb;
+
+ for (sfb = 0; sfb < cod_info->sfbmax; sfb++)
+ if (cod_info->scalefac[sfb]
+ + cod_info->subblock_gain[cod_info->window[sfb]] == 0)
+ return 0;
+
+ return 1;
+}
+
+
+
+
+/* mt 5/99: Function: Improved calc_noise for a single channel */
+
+/*************************************************************************
+ *
+ * quant_compare()
+ *
+ * author/date??
+ *
+ * several different codes to decide which quantization is better
+ *
+ *************************************************************************/
+
+static double
+penalties(double noise)
+{
+ return FAST_LOG10(0.368 + 0.632 * noise * noise * noise);
+}
+
+static double
+get_klemm_noise(const FLOAT * distort, const gr_info * const gi)
+{
+ int sfb;
+ double klemm_noise = 1E-37;
+ for (sfb = 0; sfb < gi->psymax; sfb++)
+ klemm_noise += penalties(distort[sfb]);
+
+ return Max(1e-20, klemm_noise);
+}
+
+inline static int
+quant_compare(const int quant_comp,
+ const calc_noise_result * const best,
+ calc_noise_result * const calc, const gr_info * const gi, const FLOAT * distort)
+{
+ /*
+ noise is given in decibels (dB) relative to masking thesholds.
+
+ over_noise: ??? (the previous comment is fully wrong)
+ tot_noise: ??? (the previous comment is fully wrong)
+ max_noise: max quantization noise
+
+ */
+ int better;
+
+ switch (quant_comp) {
+ default:
+ case 9:{
+ if (best->over_count > 0) {
+ /* there are distorted sfb */
+ better = calc->over_SSD <= best->over_SSD;
+ if (calc->over_SSD == best->over_SSD)
+ better = calc->bits < best->bits;
+ }
+ else {
+ /* no distorted sfb */
+ better = ((calc->max_noise < 0) &&
+ ((calc->max_noise * 10 + calc->bits) <=
+ (best->max_noise * 10 + best->bits)));
+ }
+ break;
+ }
+
+ case 0:
+ better = calc->over_count < best->over_count
+ || (calc->over_count == best->over_count && calc->over_noise < best->over_noise)
+ || (calc->over_count == best->over_count &&
+ EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise);
+ break;
+
+ case 8:
+ calc->max_noise = get_klemm_noise(distort, gi);
+ /*lint --fallthrough */
+ case 1:
+ better = calc->max_noise < best->max_noise;
+ break;
+ case 2:
+ better = calc->tot_noise < best->tot_noise;
+ break;
+ case 3:
+ better = (calc->tot_noise < best->tot_noise)
+ && (calc->max_noise < best->max_noise);
+ break;
+ case 4:
+ better = (calc->max_noise <= 0.0 && best->max_noise > 0.2)
+ || (calc->max_noise <= 0.0 &&
+ best->max_noise < 0.0 &&
+ best->max_noise > calc->max_noise - 0.2 && calc->tot_noise < best->tot_noise)
+ || (calc->max_noise <= 0.0 &&
+ best->max_noise > 0.0 &&
+ best->max_noise > calc->max_noise - 0.2 &&
+ calc->tot_noise < best->tot_noise + best->over_noise)
+ || (calc->max_noise > 0.0 &&
+ best->max_noise > -0.05 &&
+ best->max_noise > calc->max_noise - 0.1 &&
+ calc->tot_noise + calc->over_noise < best->tot_noise + best->over_noise)
+ || (calc->max_noise > 0.0 &&
+ best->max_noise > -0.1 &&
+ best->max_noise > calc->max_noise - 0.15 &&
+ calc->tot_noise + calc->over_noise + calc->over_noise <
+ best->tot_noise + best->over_noise + best->over_noise);
+ break;
+ case 5:
+ better = calc->over_noise < best->over_noise
+ || (EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise);
+ break;
+ case 6:
+ better = calc->over_noise < best->over_noise
+ || (EQ(calc->over_noise, best->over_noise) &&
+ (calc->max_noise < best->max_noise
+ || (EQ(calc->max_noise, best->max_noise) && calc->tot_noise <= best->tot_noise)
+ ));
+ break;
+ case 7:
+ better = calc->over_count < best->over_count || calc->over_noise < best->over_noise;
+ break;
+ }
+
+
+ if (best->over_count == 0) {
+ /*
+ If no distorted bands, only use this quantization
+ if it is better, and if it uses less bits.
+ Unfortunately, part2_3_length is sometimes a poor
+ estimator of the final size at low bitrates.
+ */
+ better = better && calc->bits < best->bits;
+ }
+
+
+ return better;
+}
+
+
+
+/*************************************************************************
+ *
+ * amp_scalefac_bands()
+ *
+ * author/date??
+ *
+ * Amplify the scalefactor bands that violate the masking threshold.
+ * See ISO 11172-3 Section C.1.5.4.3.5
+ *
+ * distort[] = noise/masking
+ * distort[] > 1 ==> noise is not masked
+ * distort[] < 1 ==> noise is masked
+ * max_dist = maximum value of distort[]
+ *
+ * Three algorithms:
+ * noise_shaping_amp
+ * 0 Amplify all bands with distort[]>1.
+ *
+ * 1 Amplify all bands with distort[] >= max_dist^(.5);
+ * ( 50% in the db scale)
+ *
+ * 2 Amplify first band with distort[] >= max_dist;
+ *
+ *
+ * For algorithms 0 and 1, if max_dist < 1, then amplify all bands
+ * with distort[] >= .95*max_dist. This is to make sure we always
+ * amplify at least one band.
+ *
+ *
+ *************************************************************************/
+static void
+amp_scalefac_bands(lame_internal_flags * gfc,
+ gr_info * const cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int j, sfb;
+ FLOAT ifqstep34, trigger;
+ int noise_shaping_amp;
+
+ if (cod_info->scalefac_scale == 0) {
+ ifqstep34 = 1.29683955465100964055; /* 2**(.75*.5) */
+ }
+ else {
+ ifqstep34 = 1.68179283050742922612; /* 2**(.75*1) */
+ }
+
+ /* compute maximum value of distort[] */
+ trigger = 0;
+ for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {
+ if (trigger < distort[sfb])
+ trigger = distort[sfb];
+ }
+
+ noise_shaping_amp = cfg->noise_shaping_amp;
+ if (noise_shaping_amp == 3) {
+ if (bRefine == 1)
+ noise_shaping_amp = 2;
+ else
+ noise_shaping_amp = 1;
+ }
+ switch (noise_shaping_amp) {
+ case 2:
+ /* amplify exactly 1 band */
+ break;
+
+ case 1:
+ /* amplify bands within 50% of max (on db scale) */
+ if (trigger > 1.0)
+ trigger = pow(trigger, .5);
+ else
+ trigger *= .95;
+ break;
+
+ case 0:
+ default:
+ /* ISO algorithm. amplify all bands with distort>1 */
+ if (trigger > 1.0)
+ trigger = 1.0;
+ else
+ trigger *= .95;
+ break;
+ }
+
+ j = 0;
+ for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {
+ int const width = cod_info->width[sfb];
+ int l;
+ j += width;
+ if (distort[sfb] < trigger)
+ continue;
+
+ if (gfc->sv_qnt.substep_shaping & 2) {
+ gfc->sv_qnt.pseudohalf[sfb] = !gfc->sv_qnt.pseudohalf[sfb];
+ if (!gfc->sv_qnt.pseudohalf[sfb] && cfg->noise_shaping_amp == 2)
+ return;
+ }
+ cod_info->scalefac[sfb]++;
+ for (l = -width; l < 0; l++) {
+ xrpow[j + l] *= ifqstep34;
+ if (xrpow[j + l] > cod_info->xrpow_max)
+ cod_info->xrpow_max = xrpow[j + l];
+ }
+
+ if (cfg->noise_shaping_amp == 2)
+ return;
+ }
+}
+
+/*************************************************************************
+ *
+ * inc_scalefac_scale()
+ *
+ * Takehiro Tominaga 2000-xx-xx
+ *
+ * turns on scalefac scale and adjusts scalefactors
+ *
+ *************************************************************************/
+
+static void
+inc_scalefac_scale(gr_info * const cod_info, FLOAT xrpow[576])
+{
+ int l, j, sfb;
+ const FLOAT ifqstep34 = 1.29683955465100964055;
+
+ j = 0;
+ for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {
+ int const width = cod_info->width[sfb];
+ int s = cod_info->scalefac[sfb];
+ if (cod_info->preflag)
+ s += pretab[sfb];
+ j += width;
+ if (s & 1) {
+ s++;
+ for (l = -width; l < 0; l++) {
+ xrpow[j + l] *= ifqstep34;
+ if (xrpow[j + l] > cod_info->xrpow_max)
+ cod_info->xrpow_max = xrpow[j + l];
+ }
+ }
+ cod_info->scalefac[sfb] = s >> 1;
+ }
+ cod_info->preflag = 0;
+ cod_info->scalefac_scale = 1;
+}
+
+
+
+/*************************************************************************
+ *
+ * inc_subblock_gain()
+ *
+ * Takehiro Tominaga 2000-xx-xx
+ *
+ * increases the subblock gain and adjusts scalefactors
+ *
+ *************************************************************************/
+
+static int
+inc_subblock_gain(const lame_internal_flags * const gfc, gr_info * const cod_info, FLOAT xrpow[576])
+{
+ int sfb, window;
+ int *const scalefac = cod_info->scalefac;
+
+ /* subbloc_gain can't do anything in the long block region */
+ for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) {
+ if (scalefac[sfb] >= 16)
+ return 1;
+ }
+
+ for (window = 0; window < 3; window++) {
+ int s1, s2, l, j;
+ s1 = s2 = 0;
+
+ for (sfb = cod_info->sfb_lmax + window; sfb < cod_info->sfbdivide; sfb += 3) {
+ if (s1 < scalefac[sfb])
+ s1 = scalefac[sfb];
+ }
+ for (; sfb < cod_info->sfbmax; sfb += 3) {
+ if (s2 < scalefac[sfb])
+ s2 = scalefac[sfb];
+ }
+
+ if (s1 < 16 && s2 < 8)
+ continue;
+
+ if (cod_info->subblock_gain[window] >= 7)
+ return 1;
+
+ /* even though there is no scalefactor for sfb12
+ * subblock gain affects upper frequencies too, that's why
+ * we have to go up to SBMAX_s
+ */
+ cod_info->subblock_gain[window]++;
+ j = gfc->scalefac_band.l[cod_info->sfb_lmax];
+ for (sfb = cod_info->sfb_lmax + window; sfb < cod_info->sfbmax; sfb += 3) {
+ FLOAT amp;
+ int const width = cod_info->width[sfb];
+ int s = scalefac[sfb];
+ assert(s >= 0);
+ s = s - (4 >> cod_info->scalefac_scale);
+ if (s >= 0) {
+ scalefac[sfb] = s;
+ j += width * 3;
+ continue;
+ }
+
+ scalefac[sfb] = 0;
+ {
+ int const gain = 210 + (s << (cod_info->scalefac_scale + 1));
+ amp = IPOW20(gain);
+ }
+ j += width * (window + 1);
+ for (l = -width; l < 0; l++) {
+ xrpow[j + l] *= amp;
+ if (xrpow[j + l] > cod_info->xrpow_max)
+ cod_info->xrpow_max = xrpow[j + l];
+ }
+ j += width * (3 - window - 1);
+ }
+
+ {
+ FLOAT const amp = IPOW20(202);
+ j += cod_info->width[sfb] * (window + 1);
+ for (l = -cod_info->width[sfb]; l < 0; l++) {
+ xrpow[j + l] *= amp;
+ if (xrpow[j + l] > cod_info->xrpow_max)
+ cod_info->xrpow_max = xrpow[j + l];
+ }
+ }
+ }
+ return 0;
+}
+
+
+
+/********************************************************************
+ *
+ * balance_noise()
+ *
+ * Takehiro Tominaga /date??
+ * Robert Hegemann 2000-09-06: made a function of it
+ *
+ * amplifies scalefactor bands,
+ * - if all are already amplified returns 0
+ * - if some bands are amplified too much:
+ * * try to increase scalefac_scale
+ * * if already scalefac_scale was set
+ * try on short blocks to increase subblock gain
+ *
+ ********************************************************************/
+inline static int
+balance_noise(lame_internal_flags * gfc,
+ gr_info * const cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int status;
+
+ amp_scalefac_bands(gfc, cod_info, distort, xrpow, bRefine);
+
+ /* check to make sure we have not amplified too much
+ * loop_break returns 0 if there is an unamplified scalefac
+ * scale_bitcount returns 0 if no scalefactors are too large
+ */
+
+ status = loop_break(cod_info);
+
+ if (status)
+ return 0; /* all bands amplified */
+
+ /* not all scalefactors have been amplified. so these
+ * scalefacs are possibly valid. encode them:
+ */
+ status = scale_bitcount(gfc, cod_info);
+
+ if (!status)
+ return 1; /* amplified some bands not exceeding limits */
+
+ /* some scalefactors are too large.
+ * lets try setting scalefac_scale=1
+ */
+ if (cfg->noise_shaping > 1) {
+ memset(&gfc->sv_qnt.pseudohalf[0], 0, sizeof(gfc->sv_qnt.pseudohalf));
+ if (!cod_info->scalefac_scale) {
+ inc_scalefac_scale(cod_info, xrpow);
+ status = 0;
+ }
+ else {
+ if (cod_info->block_type == SHORT_TYPE && cfg->subblock_gain > 0) {
+ status = inc_subblock_gain(gfc, cod_info, xrpow)
+ || loop_break(cod_info);
+ }
+ }
+ }
+
+ if (!status) {
+ status = scale_bitcount(gfc, cod_info);
+ }
+ return !status;
+}
+
+
+
+/************************************************************************
+ *
+ * outer_loop ()
+ *
+ * Function: The outer iteration loop controls the masking conditions
+ * of all scalefactorbands. It computes the best scalefac and
+ * global gain. This module calls the inner iteration loop
+ *
+ * mt 5/99 completely rewritten to allow for bit reservoir control,
+ * mid/side channels with L/R or mid/side masking thresholds,
+ * and chooses best quantization instead of last quantization when
+ * no distortion free quantization can be found.
+ *
+ * added VBR support mt 5/99
+ *
+ * some code shuffle rh 9/00
+ ************************************************************************/
+
+static int
+outer_loop(lame_internal_flags * gfc, gr_info * const cod_info, const FLOAT * const l3_xmin, /* allowed distortion */
+ FLOAT xrpow[576], /* coloured magnitudes of spectral */
+ const int ch, const int targ_bits)
+{ /* maximum allowed bits */
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ gr_info cod_info_w;
+ FLOAT save_xrpow[576];
+ FLOAT distort[SFBMAX];
+ calc_noise_result best_noise_info;
+ int huff_bits;
+ int better;
+ int age;
+ calc_noise_data prev_noise;
+ int best_part2_3_length = 9999999;
+ int bEndOfSearch = 0;
+ int bRefine = 0;
+ int best_ggain_pass1 = 0;
+
+ (void) bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow);
+
+ if (!cfg->noise_shaping)
+ /* fast mode, no noise shaping, we are ready */
+ return 100; /* default noise_info.over_count */
+
+ memset(&prev_noise, 0, sizeof(calc_noise_data));
+
+
+ /* compute the distortion in this quantization */
+ /* coefficients and thresholds both l/r (or both mid/side) */
+ (void) calc_noise(cod_info, l3_xmin, distort, &best_noise_info, &prev_noise);
+ best_noise_info.bits = cod_info->part2_3_length;
+
+ cod_info_w = *cod_info;
+ age = 0;
+ /* if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh) */
+ memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576);
+
+ while (!bEndOfSearch) {
+ /* BEGIN MAIN LOOP */
+ do {
+ calc_noise_result noise_info;
+ int search_limit;
+ int maxggain = 255;
+
+ /* When quantization with no distorted bands is found,
+ * allow up to X new unsuccesful tries in serial. This
+ * gives us more possibilities for different quant_compare modes.
+ * Much more than 3 makes not a big difference, it is only slower.
+ */
+
+ if (gfc->sv_qnt.substep_shaping & 2) {
+ search_limit = 20;
+ }
+ else {
+ search_limit = 3;
+ }
+
+
+
+ /* Check if the last scalefactor band is distorted.
+ * in VBR mode we can't get rid of the distortion, so quit now
+ * and VBR mode will try again with more bits.
+ * (makes a 10% speed increase, the files I tested were
+ * binary identical, 2000/05/20 Robert Hegemann)
+ * distort[] > 1 means noise > allowed noise
+ */
+ if (gfc->sv_qnt.sfb21_extra) {
+ if (distort[cod_info_w.sfbmax] > 1.0)
+ break;
+ if (cod_info_w.block_type == SHORT_TYPE
+ && (distort[cod_info_w.sfbmax + 1] > 1.0
+ || distort[cod_info_w.sfbmax + 2] > 1.0))
+ break;
+ }
+
+ /* try a new scalefactor conbination on cod_info_w */
+ if (balance_noise(gfc, &cod_info_w, distort, xrpow, bRefine) == 0)
+ break;
+ if (cod_info_w.scalefac_scale)
+ maxggain = 254;
+
+ /* inner_loop starts with the initial quantization step computed above
+ * and slowly increases until the bits < huff_bits.
+ * Thus it is important not to start with too large of an inital
+ * quantization step. Too small is ok, but inner_loop will take longer
+ */
+ huff_bits = targ_bits - cod_info_w.part2_length;
+ if (huff_bits <= 0)
+ break;
+
+ /* increase quantizer stepsize until needed bits are below maximum
+ */
+ while ((cod_info_w.part2_3_length
+ = count_bits(gfc, xrpow, &cod_info_w, &prev_noise)) > huff_bits
+ && cod_info_w.global_gain <= maxggain)
+ cod_info_w.global_gain++;
+
+ if (cod_info_w.global_gain > maxggain)
+ break;
+
+ if (best_noise_info.over_count == 0) {
+
+ while ((cod_info_w.part2_3_length
+ = count_bits(gfc, xrpow, &cod_info_w, &prev_noise)) > best_part2_3_length
+ && cod_info_w.global_gain <= maxggain)
+ cod_info_w.global_gain++;
+
+ if (cod_info_w.global_gain > maxggain)
+ break;
+ }
+
+ /* compute the distortion in this quantization */
+ (void) calc_noise(&cod_info_w, l3_xmin, distort, &noise_info, &prev_noise);
+ noise_info.bits = cod_info_w.part2_3_length;
+
+ /* check if this quantization is better
+ * than our saved quantization */
+ if (cod_info->block_type != SHORT_TYPE) /* NORM, START or STOP type */
+ better = cfg->quant_comp;
+ else
+ better = cfg->quant_comp_short;
+
+
+ better = quant_compare(better, &best_noise_info, &noise_info, &cod_info_w, distort);
+
+
+ /* save data so we can restore this quantization later */
+ if (better) {
+ best_part2_3_length = cod_info->part2_3_length;
+ best_noise_info = noise_info;
+ *cod_info = cod_info_w;
+ age = 0;
+ /* save data so we can restore this quantization later */
+ /*if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh) */ {
+ /* store for later reuse */
+ memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576);
+ }
+ }
+ else {
+ /* early stop? */
+ if (cfg->full_outer_loop == 0) {
+ if (++age > search_limit && best_noise_info.over_count == 0)
+ break;
+ if ((cfg->noise_shaping_amp == 3) && bRefine && age > 30)
+ break;
+ if ((cfg->noise_shaping_amp == 3) && bRefine &&
+ (cod_info_w.global_gain - best_ggain_pass1) > 15)
+ break;
+ }
+ }
+ }
+ while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255);
+
+ if (cfg->noise_shaping_amp == 3) {
+ if (!bRefine) {
+ /* refine search */
+ cod_info_w = *cod_info;
+ memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576);
+ age = 0;
+ best_ggain_pass1 = cod_info_w.global_gain;
+
+ bRefine = 1;
+ }
+ else {
+ /* search already refined, stop */
+ bEndOfSearch = 1;
+ }
+
+ }
+ else {
+ bEndOfSearch = 1;
+ }
+ }
+
+ assert((cod_info->global_gain + cod_info->scalefac_scale) <= 255);
+ /* finish up
+ */
+ if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh || cfg->vbr == vbr_mt)
+ /* restore for reuse on next try */
+ memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576);
+ /* do the 'substep shaping'
+ */
+ else if (gfc->sv_qnt.substep_shaping & 1)
+ trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow);
+
+ return best_noise_info.over_count;
+}
+
+
+
+
+
+/************************************************************************
+ *
+ * iteration_finish_one()
+ *
+ * Robert Hegemann 2000-09-06
+ *
+ * update reservoir status after FINAL quantization/bitrate
+ *
+ ************************************************************************/
+
+static void
+iteration_finish_one(lame_internal_flags * gfc, int gr, int ch)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+ gr_info *const cod_info = &l3_side->tt[gr][ch];
+
+ /* try some better scalefac storage
+ */
+ best_scalefac_store(gfc, gr, ch, l3_side);
+
+ /* best huffman_divide may save some bits too
+ */
+ if (cfg->use_best_huffman == 1)
+ best_huffman_divide(gfc, cod_info);
+
+ /* update reservoir status after FINAL quantization/bitrate
+ */
+ ResvAdjust(gfc, cod_info);
+}
+
+
+
+/*********************************************************************
+ *
+ * VBR_encode_granule()
+ *
+ * 2000-09-04 Robert Hegemann
+ *
+ *********************************************************************/
+
+static void
+VBR_encode_granule(lame_internal_flags * gfc, gr_info * const cod_info, const FLOAT * const l3_xmin, /* allowed distortion of the scalefactor */
+ FLOAT xrpow[576], /* coloured magnitudes of spectral values */
+ const int ch, int min_bits, int max_bits)
+{
+ gr_info bst_cod_info;
+ FLOAT bst_xrpow[576];
+ int const Max_bits = max_bits;
+ int real_bits = max_bits + 1;
+ int this_bits = (max_bits + min_bits) / 2;
+ int dbits, over, found = 0;
+ int const sfb21_extra = gfc->sv_qnt.sfb21_extra;
+
+ assert(Max_bits <= MAX_BITS_PER_CHANNEL);
+ memset(bst_cod_info.l3_enc, 0, sizeof(bst_cod_info.l3_enc));
+
+ /* search within round about 40 bits of optimal
+ */
+ do {
+ assert(this_bits >= min_bits);
+ assert(this_bits <= max_bits);
+ assert(min_bits <= max_bits);
+
+ if (this_bits > Max_bits - 42)
+ gfc->sv_qnt.sfb21_extra = 0;
+ else
+ gfc->sv_qnt.sfb21_extra = sfb21_extra;
+
+ over = outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, this_bits);
+
+ /* is quantization as good as we are looking for ?
+ * in this case: is no scalefactor band distorted?
+ */
+ if (over <= 0) {
+ found = 1;
+ /* now we know it can be done with "real_bits"
+ * and maybe we can skip some iterations
+ */
+ real_bits = cod_info->part2_3_length;
+
+ /* store best quantization so far
+ */
+ bst_cod_info = *cod_info;
+ memcpy(bst_xrpow, xrpow, sizeof(FLOAT) * 576);
+
+ /* try with fewer bits
+ */
+ max_bits = real_bits - 32;
+ dbits = max_bits - min_bits;
+ this_bits = (max_bits + min_bits) / 2;
+ }
+ else {
+ /* try with more bits
+ */
+ min_bits = this_bits + 32;
+ dbits = max_bits - min_bits;
+ this_bits = (max_bits + min_bits) / 2;
+
+ if (found) {
+ found = 2;
+ /* start again with best quantization so far
+ */
+ *cod_info = bst_cod_info;
+ memcpy(xrpow, bst_xrpow, sizeof(FLOAT) * 576);
+ }
+ }
+ } while (dbits > 12);
+
+ gfc->sv_qnt.sfb21_extra = sfb21_extra;
+
+ /* found=0 => nothing found, use last one
+ * found=1 => we just found the best and left the loop
+ * found=2 => we restored a good one and have now l3_enc to restore too
+ */
+ if (found == 2) {
+ memcpy(cod_info->l3_enc, bst_cod_info.l3_enc, sizeof(int) * 576);
+ }
+ assert(cod_info->part2_3_length <= Max_bits);
+
+}
+
+
+
+/************************************************************************
+ *
+ * get_framebits()
+ *
+ * Robert Hegemann 2000-09-05
+ *
+ * calculates
+ * * how many bits are available for analog silent granules
+ * * how many bits to use for the lowest allowed bitrate
+ * * how many bits each bitrate would provide
+ *
+ ************************************************************************/
+
+static void
+get_framebits(lame_internal_flags * gfc, int frameBits[15])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *const eov = &gfc->ov_enc;
+ int bitsPerFrame, i;
+
+ /* always use at least this many bits per granule per channel
+ * unless we detect analog silence, see below
+ */
+ eov->bitrate_index = cfg->vbr_min_bitrate_index;
+ bitsPerFrame = getframebits(gfc);
+
+ /* bits for analog silence
+ */
+ eov->bitrate_index = 1;
+ bitsPerFrame = getframebits(gfc);
+
+ for (i = 1; i <= cfg->vbr_max_bitrate_index; i++) {
+ eov->bitrate_index = i;
+ frameBits[i] = ResvFrameBegin(gfc, &bitsPerFrame);
+ }
+}
+
+
+
+/*********************************************************************
+ *
+ * VBR_prepare()
+ *
+ * 2000-09-04 Robert Hegemann
+ *
+ * * converts LR to MS coding when necessary
+ * * calculates allowed/adjusted quantization noise amounts
+ * * detects analog silent frames
+ *
+ * some remarks:
+ * - lower masking depending on Quality setting
+ * - quality control together with adjusted ATH MDCT scaling
+ * on lower quality setting allocate more noise from
+ * ATH masking, and on higher quality setting allocate
+ * less noise from ATH masking.
+ * - experiments show that going more than 2dB over GPSYCHO's
+ * limits ends up in very annoying artefacts
+ *
+ *********************************************************************/
+
+/* RH: this one needs to be overhauled sometime */
+
+static int
+VBR_old_prepare(lame_internal_flags * gfc,
+ const FLOAT pe[2][2], FLOAT const ms_ener_ratio[2],
+ const III_psy_ratio ratio[2][2],
+ FLOAT l3_xmin[2][2][SFBMAX],
+ int frameBits[16], int min_bits[2][2], int max_bits[2][2], int bands[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *const eov = &gfc->ov_enc;
+
+ FLOAT masking_lower_db, adjust = 0.0;
+ int gr, ch;
+ int analog_silence = 1;
+ int avg, mxb, bits = 0;
+
+ eov->bitrate_index = cfg->vbr_max_bitrate_index;
+ avg = ResvFrameBegin(gfc, &avg) / cfg->mode_gr;
+
+ get_framebits(gfc, frameBits);
+
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ mxb = on_pe(gfc, pe, max_bits[gr], avg, gr, 0);
+ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
+ ms_convert(&gfc->l3_side, gr);
+ reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb);
+ }
+ for (ch = 0; ch < cfg->channels_out; ++ch) {
+ gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
+
+ if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */
+ adjust = 1.28 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.05;
+ masking_lower_db = gfc->sv_qnt.mask_adjust - adjust;
+ }
+ else {
+ adjust = 2.56 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.14;
+ masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust;
+ }
+ gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);
+
+ init_outer_loop(gfc, cod_info);
+ bands[gr][ch] = calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin[gr][ch]);
+ if (bands[gr][ch])
+ analog_silence = 0;
+
+ min_bits[gr][ch] = 126;
+
+ bits += max_bits[gr][ch];
+ }
+ }
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ if (bits > frameBits[cfg->vbr_max_bitrate_index] && bits > 0) {
+ max_bits[gr][ch] *= frameBits[cfg->vbr_max_bitrate_index];
+ max_bits[gr][ch] /= bits;
+ }
+ if (min_bits[gr][ch] > max_bits[gr][ch])
+ min_bits[gr][ch] = max_bits[gr][ch];
+
+ } /* for ch */
+ } /* for gr */
+
+ return analog_silence;
+}
+
+static void
+bitpressure_strategy(lame_internal_flags const *gfc,
+ FLOAT l3_xmin[2][2][SFBMAX], const int min_bits[2][2], int max_bits[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int gr, ch, sfb;
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info const *const gi = &gfc->l3_side.tt[gr][ch];
+ FLOAT *pxmin = l3_xmin[gr][ch];
+ for (sfb = 0; sfb < gi->psy_lmax; sfb++)
+ *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_l / SBMAX_l;
+
+ if (gi->block_type == SHORT_TYPE) {
+ for (sfb = gi->sfb_smin; sfb < SBMAX_s; sfb++) {
+ *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;
+ *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;
+ *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;
+ }
+ }
+ max_bits[gr][ch] = Max(min_bits[gr][ch], 0.9 * max_bits[gr][ch]);
+ }
+ }
+}
+
+/************************************************************************
+ *
+ * VBR_iteration_loop()
+ *
+ * tries to find out how many bits are needed for each granule and channel
+ * to get an acceptable quantization. An appropriate bitrate will then be
+ * choosed for quantization. rh 8/99
+ *
+ * Robert Hegemann 2000-09-06 rewrite
+ *
+ ************************************************************************/
+
+void
+VBR_old_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *const eov = &gfc->ov_enc;
+ FLOAT l3_xmin[2][2][SFBMAX];
+
+ FLOAT xrpow[576];
+ int bands[2][2];
+ int frameBits[15];
+ int used_bits;
+ int bits;
+ int min_bits[2][2], max_bits[2][2];
+ int mean_bits;
+ int ch, gr, analog_silence;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+
+ analog_silence = VBR_old_prepare(gfc, pe, ms_ener_ratio, ratio,
+ l3_xmin, frameBits, min_bits, max_bits, bands);
+
+ /*---------------------------------*/
+ for (;;) {
+
+ /* quantize granules with lowest possible number of bits
+ */
+
+ used_bits = 0;
+
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ int ret;
+ gr_info *const cod_info = &l3_side->tt[gr][ch];
+
+ /* init_outer_loop sets up cod_info, scalefac and xrpow
+ */
+ ret = init_xrpow(gfc, cod_info, xrpow);
+ if (ret == 0 || max_bits[gr][ch] == 0) {
+ /* xr contains no energy
+ * l3_enc, our encoding data, will be quantized to zero
+ */
+ continue; /* with next channel */
+ }
+
+ VBR_encode_granule(gfc, cod_info, l3_xmin[gr][ch], xrpow,
+ ch, min_bits[gr][ch], max_bits[gr][ch]);
+
+ /* do the 'substep shaping'
+ */
+ if (gfc->sv_qnt.substep_shaping & 1) {
+ trancate_smallspectrums(gfc, &l3_side->tt[gr][ch], l3_xmin[gr][ch], xrpow);
+ }
+
+ ret = cod_info->part2_3_length + cod_info->part2_length;
+ used_bits += ret;
+ } /* for ch */
+ } /* for gr */
+
+ /* find lowest bitrate able to hold used bits
+ */
+ if (analog_silence && !cfg->enforce_min_bitrate)
+ /* we detected analog silence and the user did not specify
+ * any hard framesize limit, so start with smallest possible frame
+ */
+ eov->bitrate_index = 1;
+ else
+ eov->bitrate_index = cfg->vbr_min_bitrate_index;
+
+ for (; eov->bitrate_index < cfg->vbr_max_bitrate_index; eov->bitrate_index++) {
+ if (used_bits <= frameBits[eov->bitrate_index])
+ break;
+ }
+ bits = ResvFrameBegin(gfc, &mean_bits);
+
+ if (used_bits <= bits)
+ break;
+
+ bitpressure_strategy(gfc, l3_xmin, (const int (*)[2])min_bits, max_bits);
+
+ } /* breaks adjusted */
+ /*--------------------------------------*/
+
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ iteration_finish_one(gfc, gr, ch);
+ } /* for ch */
+ } /* for gr */
+ ResvFrameEnd(gfc, mean_bits);
+}
+
+
+
+static int
+VBR_new_prepare(lame_internal_flags * gfc,
+ const FLOAT pe[2][2], const III_psy_ratio ratio[2][2],
+ FLOAT l3_xmin[2][2][SFBMAX], int frameBits[16], int max_bits[2][2],
+ int* max_resv)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *const eov = &gfc->ov_enc;
+
+ int gr, ch;
+ int analog_silence = 1;
+ int avg, bits = 0;
+ int maximum_framebits;
+
+ if (!cfg->free_format) {
+ eov->bitrate_index = cfg->vbr_max_bitrate_index;
+ (void) ResvFrameBegin(gfc, &avg);
+ *max_resv = gfc->sv_enc.ResvMax;
+
+ get_framebits(gfc, frameBits);
+ maximum_framebits = frameBits[cfg->vbr_max_bitrate_index];
+ }
+ else {
+ eov->bitrate_index = 0;
+ maximum_framebits = ResvFrameBegin(gfc, &avg);
+ frameBits[0] = maximum_framebits;
+ *max_resv = gfc->sv_enc.ResvMax;
+ }
+
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ (void) on_pe(gfc, pe, max_bits[gr], avg, gr, 0);
+ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
+ ms_convert(&gfc->l3_side, gr);
+ }
+ for (ch = 0; ch < cfg->channels_out; ++ch) {
+ gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
+
+ gfc->sv_qnt.masking_lower = pow(10.0, gfc->sv_qnt.mask_adjust * 0.1);
+
+ init_outer_loop(gfc, cod_info);
+ if (0 != calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin[gr][ch]))
+ analog_silence = 0;
+
+ bits += max_bits[gr][ch];
+ }
+ }
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ if (bits > maximum_framebits && bits > 0) {
+ max_bits[gr][ch] *= maximum_framebits;
+ max_bits[gr][ch] /= bits;
+ }
+
+ } /* for ch */
+ } /* for gr */
+ if (analog_silence) {
+ *max_resv = 0;
+ }
+ return analog_silence;
+}
+
+
+
+void
+VBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *const eov = &gfc->ov_enc;
+ FLOAT l3_xmin[2][2][SFBMAX];
+
+ FLOAT xrpow[2][2][576];
+ int frameBits[15];
+ int used_bits;
+ int max_bits[2][2];
+ int ch, gr, analog_silence, pad;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+
+ const FLOAT (*const_l3_xmin)[2][SFBMAX] = (const FLOAT (*)[2][SFBMAX])l3_xmin;
+ const FLOAT (*const_xrpow)[2][576] = (const FLOAT (*)[2][576])xrpow;
+ const int (*const_max_bits)[2] = (const int (*)[2])max_bits;
+
+ (void) ms_ener_ratio; /* not used */
+
+ memset(xrpow, 0, sizeof(xrpow));
+
+ analog_silence = VBR_new_prepare(gfc, pe, ratio, l3_xmin, frameBits, max_bits, &pad);
+
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info *const cod_info = &l3_side->tt[gr][ch];
+
+ /* init_outer_loop sets up cod_info, scalefac and xrpow
+ */
+ if (0 == init_xrpow(gfc, cod_info, xrpow[gr][ch])) {
+ max_bits[gr][ch] = 0; /* silent granule needs no bits */
+ }
+ } /* for ch */
+ } /* for gr */
+
+ /* quantize granules with lowest possible number of bits
+ */
+
+ used_bits = VBR_encode_frame(gfc, const_xrpow, const_l3_xmin, const_max_bits);
+
+ if (!cfg->free_format) {
+ int i, j;
+
+ /* find lowest bitrate able to hold used bits
+ */
+ if (analog_silence && !cfg->enforce_min_bitrate) {
+ /* we detected analog silence and the user did not specify
+ * any hard framesize limit, so start with smallest possible frame
+ */
+ i = 1;
+ }
+ else {
+ i = cfg->vbr_min_bitrate_index;
+ }
+
+ for (; i < cfg->vbr_max_bitrate_index; i++) {
+ if (used_bits <= frameBits[i])
+ break;
+ }
+ if (i > cfg->vbr_max_bitrate_index) {
+ i = cfg->vbr_max_bitrate_index;
+ }
+ if (pad > 0) {
+ for (j = cfg->vbr_max_bitrate_index; j > i; --j) {
+ int const unused = frameBits[j] - used_bits;
+ if (unused <= pad)
+ break;
+ }
+ eov->bitrate_index = j;
+ }
+ else {
+ eov->bitrate_index = i;
+ }
+ }
+ else {
+#if 0
+ static int mmm = 0;
+ int fff = getFramesize_kbps(gfc, used_bits);
+ int hhh = getFramesize_kbps(gfc, MAX_BITS_PER_GRANULE * cfg->mode_gr);
+ if (mmm < fff)
+ mmm = fff;
+ printf("demand=%3d kbps max=%3d kbps limit=%3d kbps\n", fff, mmm, hhh);
+#endif
+ eov->bitrate_index = 0;
+ }
+ if (used_bits <= frameBits[eov->bitrate_index]) {
+ /* update Reservoire status */
+ int mean_bits, fullframebits;
+ fullframebits = ResvFrameBegin(gfc, &mean_bits);
+ assert(used_bits <= fullframebits);
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info const *const cod_info = &l3_side->tt[gr][ch];
+ ResvAdjust(gfc, cod_info);
+ }
+ }
+ ResvFrameEnd(gfc, mean_bits);
+ }
+ else {
+ /* SHOULD NOT HAPPEN INTERNAL ERROR
+ */
+ ERRORF(gfc, "INTERNAL ERROR IN VBR NEW CODE, please send bug report\n");
+ exit(-1);
+ }
+}
+
+
+
+
+
+/********************************************************************
+ *
+ * calc_target_bits()
+ *
+ * calculates target bits for ABR encoding
+ *
+ * mt 2000/05/31
+ *
+ ********************************************************************/
+
+static void
+calc_target_bits(lame_internal_flags * gfc,
+ const FLOAT pe[2][2],
+ FLOAT const ms_ener_ratio[2],
+ int targ_bits[2][2], int *analog_silence_bits, int *max_frame_bits)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *const eov = &gfc->ov_enc;
+ III_side_info_t const *const l3_side = &gfc->l3_side;
+ FLOAT res_factor;
+ int gr, ch, totbits, mean_bits;
+ int framesize = 576 * cfg->mode_gr;
+
+ eov->bitrate_index = cfg->vbr_max_bitrate_index;
+ *max_frame_bits = ResvFrameBegin(gfc, &mean_bits);
+
+ eov->bitrate_index = 1;
+ mean_bits = getframebits(gfc) - cfg->sideinfo_len * 8;
+ *analog_silence_bits = mean_bits / (cfg->mode_gr * cfg->channels_out);
+
+ mean_bits = cfg->vbr_avg_bitrate_kbps * framesize * 1000;
+ if (gfc->sv_qnt.substep_shaping & 1)
+ mean_bits *= 1.09;
+ mean_bits /= cfg->samplerate_out;
+ mean_bits -= cfg->sideinfo_len * 8;
+ mean_bits /= (cfg->mode_gr * cfg->channels_out);
+
+ /*
+ res_factor is the percentage of the target bitrate that should
+ be used on average. the remaining bits are added to the
+ bitreservoir and used for difficult to encode frames.
+
+ Since we are tracking the average bitrate, we should adjust
+ res_factor "on the fly", increasing it if the average bitrate
+ is greater than the requested bitrate, and decreasing it
+ otherwise. Reasonable ranges are from .9 to 1.0
+
+ Until we get the above suggestion working, we use the following
+ tuning:
+ compression ratio res_factor
+ 5.5 (256kbps) 1.0 no need for bitreservoir
+ 11 (128kbps) .93 7% held for reservoir
+
+ with linear interpolation for other values.
+
+ */
+ res_factor = .93 + .07 * (11.0 - cfg->compression_ratio) / (11.0 - 5.5);
+ if (res_factor < .90)
+ res_factor = .90;
+ if (res_factor > 1.00)
+ res_factor = 1.00;
+
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ int sum = 0;
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ targ_bits[gr][ch] = res_factor * mean_bits;
+
+ if (pe[gr][ch] > 700) {
+ int add_bits = (pe[gr][ch] - 700) / 1.4;
+
+ gr_info const *const cod_info = &l3_side->tt[gr][ch];
+ targ_bits[gr][ch] = res_factor * mean_bits;
+
+ /* short blocks use a little extra, no matter what the pe */
+ if (cod_info->block_type == SHORT_TYPE) {
+ if (add_bits < mean_bits / 2)
+ add_bits = mean_bits / 2;
+ }
+ /* at most increase bits by 1.5*average */
+ if (add_bits > mean_bits * 3 / 2)
+ add_bits = mean_bits * 3 / 2;
+ else if (add_bits < 0)
+ add_bits = 0;
+
+ targ_bits[gr][ch] += add_bits;
+ }
+ if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL) {
+ targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL;
+ }
+ sum += targ_bits[gr][ch];
+ } /* for ch */
+ if (sum > MAX_BITS_PER_GRANULE) {
+ for (ch = 0; ch < cfg->channels_out; ++ch) {
+ targ_bits[gr][ch] *= MAX_BITS_PER_GRANULE;
+ targ_bits[gr][ch] /= sum;
+ }
+ }
+ } /* for gr */
+
+ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR)
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits * cfg->channels_out,
+ MAX_BITS_PER_GRANULE);
+ }
+
+ /* sum target bits
+ */
+ totbits = 0;
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL)
+ targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL;
+ totbits += targ_bits[gr][ch];
+ }
+ }
+
+ /* repartion target bits if needed
+ */
+ if (totbits > *max_frame_bits && totbits > 0) {
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ targ_bits[gr][ch] *= *max_frame_bits;
+ targ_bits[gr][ch] /= totbits;
+ }
+ }
+ }
+}
+
+
+
+
+
+
+/********************************************************************
+ *
+ * ABR_iteration_loop()
+ *
+ * encode a frame with a disired average bitrate
+ *
+ * mt 2000/05/31
+ *
+ ********************************************************************/
+
+void
+ABR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncResult_t *const eov = &gfc->ov_enc;
+ FLOAT l3_xmin[SFBMAX];
+ FLOAT xrpow[576];
+ int targ_bits[2][2];
+ int mean_bits, max_frame_bits;
+ int ch, gr, ath_over;
+ int analog_silence_bits;
+ gr_info *cod_info;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+
+ mean_bits = 0;
+
+ calc_target_bits(gfc, pe, ms_ener_ratio, targ_bits, &analog_silence_bits, &max_frame_bits);
+
+ /* encode granules
+ */
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+
+ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
+ ms_convert(&gfc->l3_side, gr);
+ }
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ FLOAT adjust, masking_lower_db;
+ cod_info = &l3_side->tt[gr][ch];
+
+ if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */
+ /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */
+ adjust = 0;
+ masking_lower_db = gfc->sv_qnt.mask_adjust - adjust;
+ }
+ else {
+ /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */
+ adjust = 0;
+ masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust;
+ }
+ gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);
+
+
+ /* cod_info, scalefac and xrpow get initialized in init_outer_loop
+ */
+ init_outer_loop(gfc, cod_info);
+ if (init_xrpow(gfc, cod_info, xrpow)) {
+ /* xr contains energy we will have to encode
+ * calculate the masking abilities
+ * find some good quantization in outer_loop
+ */
+ ath_over = calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin);
+ if (0 == ath_over) /* analog silence */
+ targ_bits[gr][ch] = analog_silence_bits;
+
+ (void) outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, targ_bits[gr][ch]);
+ }
+ iteration_finish_one(gfc, gr, ch);
+ } /* ch */
+ } /* gr */
+
+ /* find a bitrate which can refill the resevoir to positive size.
+ */
+ for (eov->bitrate_index = cfg->vbr_min_bitrate_index;
+ eov->bitrate_index <= cfg->vbr_max_bitrate_index; eov->bitrate_index++) {
+ if (ResvFrameBegin(gfc, &mean_bits) >= 0)
+ break;
+ }
+ assert(eov->bitrate_index <= cfg->vbr_max_bitrate_index);
+
+ ResvFrameEnd(gfc, mean_bits);
+}
+
+
+
+
+
+
+/************************************************************************
+ *
+ * CBR_iteration_loop()
+ *
+ * author/date??
+ *
+ * encodes one frame of MP3 data with constant bitrate
+ *
+ ************************************************************************/
+
+void
+CBR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ FLOAT l3_xmin[SFBMAX];
+ FLOAT xrpow[576];
+ int targ_bits[2];
+ int mean_bits, max_bits;
+ int gr, ch;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+ gr_info *cod_info;
+
+ (void) ResvFrameBegin(gfc, &mean_bits);
+
+ /* quantize! */
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+
+ /* calculate needed bits
+ */
+ max_bits = on_pe(gfc, pe, targ_bits, mean_bits, gr, gr);
+
+ if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
+ ms_convert(&gfc->l3_side, gr);
+ reduce_side(targ_bits, ms_ener_ratio[gr], mean_bits, max_bits);
+ }
+
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ FLOAT adjust, masking_lower_db;
+ cod_info = &l3_side->tt[gr][ch];
+
+ if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */
+ /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */
+ adjust = 0;
+ masking_lower_db = gfc->sv_qnt.mask_adjust - adjust;
+ }
+ else {
+ /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */
+ adjust = 0;
+ masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust;
+ }
+ gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);
+
+ /* init_outer_loop sets up cod_info, scalefac and xrpow
+ */
+ init_outer_loop(gfc, cod_info);
+ if (init_xrpow(gfc, cod_info, xrpow)) {
+ /* xr contains energy we will have to encode
+ * calculate the masking abilities
+ * find some good quantization in outer_loop
+ */
+ (void) calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin);
+ (void) outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, targ_bits[ch]);
+ }
+
+ iteration_finish_one(gfc, gr, ch);
+ assert(cod_info->part2_3_length <= MAX_BITS_PER_CHANNEL);
+ assert(cod_info->part2_3_length <= targ_bits[ch]);
+ } /* for ch */
+ } /* for gr */
+
+ ResvFrameEnd(gfc, mean_bits);
+}
diff --git a/pkg/lame/clame/quantize.h b/pkg/lame/clame/quantize.h
new file mode 100644
index 0000000..56edcc7
--- /dev/null
+++ b/pkg/lame/clame/quantize.h
@@ -0,0 +1,38 @@
+/*
+ * MP3 quantization
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_QUANTIZE_H
+#define LAME_QUANTIZE_H
+
+void CBR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);
+
+void VBR_old_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);
+
+void VBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);
+
+void ABR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);
+
+
+#endif /* LAME_QUANTIZE_H */
diff --git a/pkg/lame/clame/quantize_pvt.c b/pkg/lame/clame/quantize_pvt.c
new file mode 100644
index 0000000..d8d6447
--- /dev/null
+++ b/pkg/lame/clame/quantize_pvt.c
@@ -0,0 +1,1074 @@
+/*
+ * quantize_pvt source file
+ *
+ * Copyright (c) 1999-2002 Takehiro Tominaga
+ * Copyright (c) 2000-2012 Robert Hegemann
+ * Copyright (c) 2001 Naoki Shibata
+ * Copyright (c) 2002-2005 Gabriel Bouvigne
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: quantize_pvt.c,v 1.175 2017/09/06 15:07:30 robert Exp $ */
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "quantize_pvt.h"
+#include "reservoir.h"
+#include "lame-analysis.h"
+#include
+
+
+#define NSATHSCALE 100 /* Assuming dynamic range=96dB, this value should be 92 */
+
+/*
+ The following table is used to implement the scalefactor
+ partitioning for MPEG2 as described in section
+ 2.4.3.2 of the IS. The indexing corresponds to the
+ way the tables are presented in the IS:
+
+ [table_number][row_in_table][column of nr_of_sfb]
+*/
+const int nr_of_sfb_block[6][3][4] = {
+ {
+ {6, 5, 5, 5},
+ {9, 9, 9, 9},
+ {6, 9, 9, 9}
+ },
+ {
+ {6, 5, 7, 3},
+ {9, 9, 12, 6},
+ {6, 9, 12, 6}
+ },
+ {
+ {11, 10, 0, 0},
+ {18, 18, 0, 0},
+ {15, 18, 0, 0}
+ },
+ {
+ {7, 7, 7, 0},
+ {12, 12, 12, 0},
+ {6, 15, 12, 0}
+ },
+ {
+ {6, 6, 6, 3},
+ {12, 9, 9, 6},
+ {6, 12, 9, 6}
+ },
+ {
+ {8, 8, 5, 0},
+ {15, 12, 9, 0},
+ {6, 18, 9, 0}
+ }
+};
+
+
+/* Table B.6: layer3 preemphasis */
+const int pretab[SBMAX_l] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0
+};
+
+/*
+ Here are MPEG1 Table B.8 and MPEG2 Table B.1
+ -- Layer III scalefactor bands.
+ Index into this using a method such as:
+ idx = fr_ps->header->sampling_frequency
+ + (fr_ps->header->version * 3)
+*/
+
+
+const scalefac_struct sfBandIndex[9] = {
+ { /* Table B.2.b: 22.05 kHz */
+ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
+ 522, 576},
+ {0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */
+ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464,
+ 540, 576},
+ {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* Table B.2.a: 16 kHz */
+ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
+ 522, 576},
+ {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* Table B.8.b: 44.1 kHz */
+ {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418,
+ 576},
+ {0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* Table B.8.c: 48 kHz */
+ {0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384,
+ 576},
+ {0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* Table B.8.a: 32 kHz */
+ {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550,
+ 576},
+ {0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* MPEG-2.5 11.025 kHz */
+ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
+ 522, 576},
+ {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3,
+ 402 / 3, 522 / 3, 576 / 3}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* MPEG-2.5 12 kHz */
+ {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,
+ 522, 576},
+ {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3,
+ 402 / 3, 522 / 3, 576 / 3}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ },
+ { /* MPEG-2.5 8 kHz */
+ {0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570,
+ 572, 574, 576},
+ {0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3,
+ 492 / 3, 498 / 3, 576 / 3}
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */
+ , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */
+ }
+};
+
+
+/* FIXME: move global variables in some struct */
+
+FLOAT pow20[Q_MAX + Q_MAX2 + 1];
+FLOAT ipow20[Q_MAX];
+FLOAT pow43[PRECALC_SIZE];
+/* initialized in first call to iteration_init */
+#ifdef TAKEHIRO_IEEE754_HACK
+FLOAT adj43asm[PRECALC_SIZE];
+#else
+FLOAT adj43[PRECALC_SIZE];
+#endif
+
+/*
+compute the ATH for each scalefactor band
+cd range: 0..96db
+
+Input: 3.3kHz signal 32767 amplitude (3.3kHz is where ATH is smallest = -5db)
+longblocks: sfb=12 en0/bw=-11db max_en0 = 1.3db
+shortblocks: sfb=5 -9db 0db
+
+Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated)
+longblocks: amp=1 sfb=12 en0/bw=-103 db max_en0 = -92db
+ amp=32767 sfb=12 -12 db -1.4db
+
+Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated)
+shortblocks: amp=1 sfb=5 en0/bw= -99 -86
+ amp=32767 sfb=5 -9 db 4db
+
+
+MAX energy of largest wave at 3.3kHz = 1db
+AVE energy of largest wave at 3.3kHz = -11db
+Let's take AVE: -11db = maximum signal in sfb=12.
+Dynamic range of CD: 96db. Therefor energy of smallest audible wave
+in sfb=12 = -11 - 96 = -107db = ATH at 3.3kHz.
+
+ATH formula for this wave: -5db. To adjust to LAME scaling, we need
+ATH = ATH_formula - 103 (db)
+ATH = ATH * 2.5e-10 (ener)
+
+*/
+
+static FLOAT
+ATHmdct(SessionConfig_t const *cfg, FLOAT f)
+{
+ FLOAT ath;
+
+ ath = ATHformula(cfg, f);
+
+ if (cfg->ATHfixpoint > 0) {
+ ath -= cfg->ATHfixpoint;
+ }
+ else {
+ ath -= NSATHSCALE;
+ }
+ ath += cfg->ATH_offset_db;
+
+ /* modify the MDCT scaling for the ATH and convert to energy */
+ ath = powf(10.0f, ath * 0.1f);
+ return ath;
+}
+
+static void
+compute_ath(lame_internal_flags const* gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ FLOAT *const ATH_l = gfc->ATH->l;
+ FLOAT *const ATH_psfb21 = gfc->ATH->psfb21;
+ FLOAT *const ATH_s = gfc->ATH->s;
+ FLOAT *const ATH_psfb12 = gfc->ATH->psfb12;
+ int sfb, i, start, end;
+ FLOAT ATH_f;
+ FLOAT const samp_freq = cfg->samplerate_out;
+
+ for (sfb = 0; sfb < SBMAX_l; sfb++) {
+ start = gfc->scalefac_band.l[sfb];
+ end = gfc->scalefac_band.l[sfb + 1];
+ ATH_l[sfb] = FLOAT_MAX;
+ for (i = start; i < end; i++) {
+ FLOAT const freq = i * samp_freq / (2 * 576);
+ ATH_f = ATHmdct(cfg, freq); /* freq in kHz */
+ ATH_l[sfb] = Min(ATH_l[sfb], ATH_f);
+ }
+ }
+
+ for (sfb = 0; sfb < PSFB21; sfb++) {
+ start = gfc->scalefac_band.psfb21[sfb];
+ end = gfc->scalefac_band.psfb21[sfb + 1];
+ ATH_psfb21[sfb] = FLOAT_MAX;
+ for (i = start; i < end; i++) {
+ FLOAT const freq = i * samp_freq / (2 * 576);
+ ATH_f = ATHmdct(cfg, freq); /* freq in kHz */
+ ATH_psfb21[sfb] = Min(ATH_psfb21[sfb], ATH_f);
+ }
+ }
+
+ for (sfb = 0; sfb < SBMAX_s; sfb++) {
+ start = gfc->scalefac_band.s[sfb];
+ end = gfc->scalefac_band.s[sfb + 1];
+ ATH_s[sfb] = FLOAT_MAX;
+ for (i = start; i < end; i++) {
+ FLOAT const freq = i * samp_freq / (2 * 192);
+ ATH_f = ATHmdct(cfg, freq); /* freq in kHz */
+ ATH_s[sfb] = Min(ATH_s[sfb], ATH_f);
+ }
+ ATH_s[sfb] *= (gfc->scalefac_band.s[sfb + 1] - gfc->scalefac_band.s[sfb]);
+ }
+
+ for (sfb = 0; sfb < PSFB12; sfb++) {
+ start = gfc->scalefac_band.psfb12[sfb];
+ end = gfc->scalefac_band.psfb12[sfb + 1];
+ ATH_psfb12[sfb] = FLOAT_MAX;
+ for (i = start; i < end; i++) {
+ FLOAT const freq = i * samp_freq / (2 * 192);
+ ATH_f = ATHmdct(cfg, freq); /* freq in kHz */
+ ATH_psfb12[sfb] = Min(ATH_psfb12[sfb], ATH_f);
+ }
+ /*not sure about the following */
+ ATH_psfb12[sfb] *= (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]);
+ }
+
+
+ /* no-ATH mode:
+ * reduce ATH to -200 dB
+ */
+
+ if (cfg->noATH) {
+ for (sfb = 0; sfb < SBMAX_l; sfb++) {
+ ATH_l[sfb] = 1E-20;
+ }
+ for (sfb = 0; sfb < PSFB21; sfb++) {
+ ATH_psfb21[sfb] = 1E-20;
+ }
+ for (sfb = 0; sfb < SBMAX_s; sfb++) {
+ ATH_s[sfb] = 1E-20;
+ }
+ for (sfb = 0; sfb < PSFB12; sfb++) {
+ ATH_psfb12[sfb] = 1E-20;
+ }
+ }
+
+ /* work in progress, don't rely on it too much
+ */
+ gfc->ATH->floor = 10. * log10(ATHmdct(cfg, -1.));
+
+ /*
+ { FLOAT g=10000, t=1e30, x;
+ for ( f = 100; f < 10000; f++ ) {
+ x = ATHmdct( cfg, f );
+ if ( t > x ) t = x, g = f;
+ }
+ printf("min=%g\n", g);
+ } */
+}
+
+
+static float const payload_long[2][4] =
+{ {-0.000f, -0.000f, -0.000f, +0.000f}
+, {-0.500f, -0.250f, -0.025f, +0.500f}
+};
+static float const payload_short[2][4] =
+{ {-0.000f, -0.000f, -0.000f, +0.000f}
+, {-2.000f, -1.000f, -0.050f, +0.500f}
+};
+
+/************************************************************************/
+/* initialization for iteration_loop */
+/************************************************************************/
+void
+iteration_init(lame_internal_flags * gfc)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+ FLOAT adjust, db;
+ int i, sel;
+
+ if (gfc->iteration_init_init == 0) {
+ gfc->iteration_init_init = 1;
+
+ l3_side->main_data_begin = 0;
+ compute_ath(gfc);
+
+ pow43[0] = 0.0;
+ for (i = 1; i < PRECALC_SIZE; i++)
+ pow43[i] = pow((FLOAT) i, 4.0 / 3.0);
+
+#ifdef TAKEHIRO_IEEE754_HACK
+ adj43asm[0] = 0.0;
+ for (i = 1; i < PRECALC_SIZE; i++)
+ adj43asm[i] = i - 0.5 - pow(0.5 * (pow43[i - 1] + pow43[i]), 0.75);
+#else
+ for (i = 0; i < PRECALC_SIZE - 1; i++)
+ adj43[i] = (i + 1) - pow(0.5 * (pow43[i] + pow43[i + 1]), 0.75);
+ adj43[i] = 0.5;
+#endif
+ for (i = 0; i < Q_MAX; i++)
+ ipow20[i] = pow(2.0, (double) (i - 210) * -0.1875);
+ for (i = 0; i <= Q_MAX + Q_MAX2; i++)
+ pow20[i] = pow(2.0, (double) (i - 210 - Q_MAX2) * 0.25);
+
+ huffman_init(gfc);
+ init_xrpow_core_init(gfc);
+
+ sel = 1;/* RH: all modes like vbr-new (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) ? 1 : 0;*/
+
+ /* long */
+ db = cfg->adjust_bass_db + payload_long[sel][0];
+ adjust = powf(10.f, db * 0.1f);
+ for (i = 0; i <= 6; ++i) {
+ gfc->sv_qnt.longfact[i] = adjust;
+ }
+ db = cfg->adjust_alto_db + payload_long[sel][1];
+ adjust = powf(10.f, db * 0.1f);
+ for (; i <= 13; ++i) {
+ gfc->sv_qnt.longfact[i] = adjust;
+ }
+ db = cfg->adjust_treble_db + payload_long[sel][2];
+ adjust = powf(10.f, db * 0.1f);
+ for (; i <= 20; ++i) {
+ gfc->sv_qnt.longfact[i] = adjust;
+ }
+ db = cfg->adjust_sfb21_db + payload_long[sel][3];
+ adjust = powf(10.f, db * 0.1f);
+ for (; i < SBMAX_l; ++i) {
+ gfc->sv_qnt.longfact[i] = adjust;
+ }
+
+ /* short */
+ db = cfg->adjust_bass_db + payload_short[sel][0];
+ adjust = powf(10.f, db * 0.1f);
+ for (i = 0; i <= 2; ++i) {
+ gfc->sv_qnt.shortfact[i] = adjust;
+ }
+ db = cfg->adjust_alto_db + payload_short[sel][1];
+ adjust = powf(10.f, db * 0.1f);
+ for (; i <= 6; ++i) {
+ gfc->sv_qnt.shortfact[i] = adjust;
+ }
+ db = cfg->adjust_treble_db + payload_short[sel][2];
+ adjust = powf(10.f, db * 0.1f);
+ for (; i <= 11; ++i) {
+ gfc->sv_qnt.shortfact[i] = adjust;
+ }
+ db = cfg->adjust_sfb21_db + payload_short[sel][3];
+ adjust = powf(10.f, db * 0.1f);
+ for (; i < SBMAX_s; ++i) {
+ gfc->sv_qnt.shortfact[i] = adjust;
+ }
+ }
+}
+
+
+
+
+
+/************************************************************************
+ * allocate bits among 2 channels based on PE
+ * mt 6/99
+ * bugfixes rh 8/01: often allocated more than the allowed 4095 bits
+ ************************************************************************/
+int
+on_pe(lame_internal_flags * gfc, const FLOAT pe[][2], int targ_bits[2], int mean_bits, int gr, int cbr)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int extra_bits = 0, tbits, bits;
+ int add_bits[2] = {0, 0};
+ int max_bits; /* maximum allowed bits for this granule */
+ int ch;
+
+ /* allocate targ_bits for granule */
+ ResvMaxBits(gfc, mean_bits, &tbits, &extra_bits, cbr);
+ max_bits = tbits + extra_bits;
+ if (max_bits > MAX_BITS_PER_GRANULE) /* hard limit per granule */
+ max_bits = MAX_BITS_PER_GRANULE;
+
+ for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) {
+ /******************************************************************
+ * allocate bits for each channel
+ ******************************************************************/
+ targ_bits[ch] = Min(MAX_BITS_PER_CHANNEL, tbits / cfg->channels_out);
+
+ add_bits[ch] = targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch];
+
+ /* at most increase bits by 1.5*average */
+ if (add_bits[ch] > mean_bits * 3 / 4)
+ add_bits[ch] = mean_bits * 3 / 4;
+ if (add_bits[ch] < 0)
+ add_bits[ch] = 0;
+
+ if (add_bits[ch] + targ_bits[ch] > MAX_BITS_PER_CHANNEL)
+ add_bits[ch] = Max(0, MAX_BITS_PER_CHANNEL - targ_bits[ch]);
+
+ bits += add_bits[ch];
+ }
+ if (bits > extra_bits && bits > 0) {
+ for (ch = 0; ch < cfg->channels_out; ++ch) {
+ add_bits[ch] = extra_bits * add_bits[ch] / bits;
+ }
+ }
+
+ for (ch = 0; ch < cfg->channels_out; ++ch) {
+ targ_bits[ch] += add_bits[ch];
+ extra_bits -= add_bits[ch];
+ }
+
+ for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) {
+ bits += targ_bits[ch];
+ }
+ if (bits > MAX_BITS_PER_GRANULE) {
+ int sum = 0;
+ for (ch = 0; ch < cfg->channels_out; ++ch) {
+ targ_bits[ch] *= MAX_BITS_PER_GRANULE;
+ targ_bits[ch] /= bits;
+ sum += targ_bits[ch];
+ }
+ assert(sum <= MAX_BITS_PER_GRANULE);
+ }
+
+ return max_bits;
+}
+
+
+
+
+void
+reduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits)
+{
+ int move_bits;
+ FLOAT fac;
+
+ assert(max_bits <= MAX_BITS_PER_GRANULE);
+ assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE);
+
+ /* ms_ener_ratio = 0: allocate 66/33 mid/side fac=.33
+ * ms_ener_ratio =.5: allocate 50/50 mid/side fac= 0 */
+ /* 75/25 split is fac=.5 */
+ /* float fac = .50*(.5-ms_ener_ratio[gr])/.5; */
+ fac = .33 * (.5 - ms_ener_ratio) / .5;
+ if (fac < 0)
+ fac = 0;
+ if (fac > .5)
+ fac = .5;
+
+ /* number of bits to move from side channel to mid channel */
+ /* move_bits = fac*targ_bits[1]; */
+ move_bits = fac * .5 * (targ_bits[0] + targ_bits[1]);
+
+ if (move_bits > MAX_BITS_PER_CHANNEL - targ_bits[0]) {
+ move_bits = MAX_BITS_PER_CHANNEL - targ_bits[0];
+ }
+ if (move_bits < 0)
+ move_bits = 0;
+
+ if (targ_bits[1] >= 125) {
+ /* dont reduce side channel below 125 bits */
+ if (targ_bits[1] - move_bits > 125) {
+
+ /* if mid channel already has 2x more than average, dont bother */
+ /* mean_bits = bits per granule (for both channels) */
+ if (targ_bits[0] < mean_bits)
+ targ_bits[0] += move_bits;
+ targ_bits[1] -= move_bits;
+ }
+ else {
+ targ_bits[0] += targ_bits[1] - 125;
+ targ_bits[1] = 125;
+ }
+ }
+
+ move_bits = targ_bits[0] + targ_bits[1];
+ if (move_bits > max_bits) {
+ targ_bits[0] = (max_bits * targ_bits[0]) / move_bits;
+ targ_bits[1] = (max_bits * targ_bits[1]) / move_bits;
+ }
+ assert(targ_bits[0] <= MAX_BITS_PER_CHANNEL);
+ assert(targ_bits[1] <= MAX_BITS_PER_CHANNEL);
+ assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE);
+}
+
+
+/**
+ * Robert Hegemann 2001-04-27:
+ * this adjusts the ATH, keeping the original noise floor
+ * affects the higher frequencies more than the lower ones
+ */
+
+FLOAT
+athAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint)
+{
+ /* work in progress
+ */
+ FLOAT const o = 90.30873362f;
+ FLOAT const p = (ATHfixpoint < 1.f) ? 94.82444863f : ATHfixpoint;
+ FLOAT u = FAST_LOG10_X(x, 10.0f);
+ FLOAT const v = a * a;
+ FLOAT w = 0.0f;
+ u -= athFloor; /* undo scaling */
+ if (v > 1E-20f)
+ w = 1.f + FAST_LOG10_X(v, 10.0f / o);
+ if (w < 0)
+ w = 0.f;
+ u *= w;
+ u += athFloor + o - p; /* redo scaling */
+
+ return powf(10.f, 0.1f * u);
+}
+
+
+
+/*************************************************************************/
+/* calc_xmin */
+/*************************************************************************/
+
+/*
+ Calculate the allowed distortion for each scalefactor band,
+ as determined by the psychoacoustic model.
+ xmin(sb) = ratio(sb) * en(sb) / bw(sb)
+
+ returns number of sfb's with energy > ATH
+*/
+
+int
+calc_xmin(lame_internal_flags const *gfc,
+ III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * pxmin)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int sfb, gsfb, j = 0, ath_over = 0, k;
+ ATH_t const *const ATH = gfc->ATH;
+ const FLOAT *const xr = cod_info->xr;
+ int max_nonzero;
+
+ for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) {
+ FLOAT en0, xmin;
+ FLOAT rh1, rh2, rh3;
+ int width, l;
+
+ xmin = athAdjust(ATH->adjust_factor, ATH->l[gsfb], ATH->floor, cfg->ATHfixpoint);
+ xmin *= gfc->sv_qnt.longfact[gsfb];
+
+ width = cod_info->width[gsfb];
+ rh1 = xmin / width;
+#ifdef DBL_EPSILON
+ rh2 = DBL_EPSILON;
+#else
+ rh2 = 2.2204460492503131e-016;
+#endif
+ en0 = 0.0;
+ for (l = 0; l < width; ++l) {
+ FLOAT const xa = xr[j++];
+ FLOAT const x2 = xa * xa;
+ en0 += x2;
+ rh2 += (x2 < rh1) ? x2 : rh1;
+ }
+ if (en0 > xmin)
+ ath_over++;
+
+ if (en0 < xmin) {
+ rh3 = en0;
+ }
+ else if (rh2 < xmin) {
+ rh3 = xmin;
+ }
+ else {
+ rh3 = rh2;
+ }
+ xmin = rh3;
+ {
+ FLOAT const e = ratio->en.l[gsfb];
+ if (e > 1e-12f) {
+ FLOAT x;
+ x = en0 * ratio->thm.l[gsfb] / e;
+ x *= gfc->sv_qnt.longfact[gsfb];
+ if (xmin < x)
+ xmin = x;
+ }
+ }
+ xmin = Max(xmin, DBL_EPSILON);
+ cod_info->energy_above_cutoff[gsfb] = (en0 > xmin+1e-14f) ? 1 : 0;
+ *pxmin++ = xmin;
+ } /* end of long block loop */
+
+
+
+
+ /*use this function to determine the highest non-zero coeff */
+ max_nonzero = 0;
+ for (k = 575; k > 0; --k) {
+ if (fabs(xr[k]) > 1e-12f) {
+ max_nonzero = k;
+ break;
+ }
+ }
+ if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */
+ max_nonzero |= 1; /* only odd numbers */
+ }
+ else {
+ max_nonzero /= 6; /* 3 short blocks */
+ max_nonzero *= 6;
+ max_nonzero += 5;
+ }
+
+ if (gfc->sv_qnt.sfb21_extra == 0 && cfg->samplerate_out < 44000) {
+ int const sfb_l = (cfg->samplerate_out <= 8000) ? 17 : 21;
+ int const sfb_s = (cfg->samplerate_out <= 8000) ? 9 : 12;
+ int limit = 575;
+ if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */
+ limit = gfc->scalefac_band.l[sfb_l]-1;
+ }
+ else {
+ limit = 3*gfc->scalefac_band.s[sfb_s]-1;
+ }
+ if (max_nonzero > limit) {
+ max_nonzero = limit;
+ }
+ }
+ cod_info->max_nonzero_coeff = max_nonzero;
+
+
+
+ for (sfb = cod_info->sfb_smin; gsfb < cod_info->psymax; sfb++, gsfb += 3) {
+ int width, b, l;
+ FLOAT tmpATH;
+
+ tmpATH = athAdjust(ATH->adjust_factor, ATH->s[sfb], ATH->floor, cfg->ATHfixpoint);
+ tmpATH *= gfc->sv_qnt.shortfact[sfb];
+
+ width = cod_info->width[gsfb];
+ for (b = 0; b < 3; b++) {
+ FLOAT en0 = 0.0, xmin = tmpATH;
+ FLOAT rh1, rh2, rh3;
+
+ rh1 = tmpATH / width;
+#ifdef DBL_EPSILON
+ rh2 = DBL_EPSILON;
+#else
+ rh2 = 2.2204460492503131e-016;
+#endif
+ for (l = 0; l < width; ++l) {
+ FLOAT const xa = xr[j++];
+ FLOAT const x2 = xa * xa;
+ en0 += x2;
+ rh2 += (x2 < rh1) ? x2 : rh1;
+ }
+ if (en0 > tmpATH)
+ ath_over++;
+
+ if (en0 < tmpATH) {
+ rh3 = en0;
+ }
+ else if (rh2 < tmpATH) {
+ rh3 = tmpATH;
+ }
+ else {
+ rh3 = rh2;
+ }
+ xmin = rh3;
+ {
+ FLOAT const e = ratio->en.s[sfb][b];
+ if (e > 1e-12f) {
+ FLOAT x;
+ x = en0 * ratio->thm.s[sfb][b] / e;
+ x *= gfc->sv_qnt.shortfact[sfb];
+ if (xmin < x)
+ xmin = x;
+ }
+ }
+ xmin = Max(xmin, DBL_EPSILON);
+ cod_info->energy_above_cutoff[gsfb+b] = (en0 > xmin+1e-14f) ? 1 : 0;
+ *pxmin++ = xmin;
+ } /* b */
+ if (cfg->use_temporal_masking_effect) {
+ if (pxmin[-3] > pxmin[-3 + 1])
+ pxmin[-3 + 1] += (pxmin[-3] - pxmin[-3 + 1]) * gfc->cd_psy->decay;
+ if (pxmin[-3 + 1] > pxmin[-3 + 2])
+ pxmin[-3 + 2] += (pxmin[-3 + 1] - pxmin[-3 + 2]) * gfc->cd_psy->decay;
+ }
+ } /* end of short block sfb loop */
+
+ return ath_over;
+}
+
+
+static FLOAT
+calc_noise_core_c(const gr_info * const cod_info, int *startline, int l, FLOAT step)
+{
+ FLOAT noise = 0;
+ int j = *startline;
+ const int *const ix = cod_info->l3_enc;
+
+ if (j > cod_info->count1) {
+ while (l--) {
+ FLOAT temp;
+ temp = cod_info->xr[j];
+ j++;
+ noise += temp * temp;
+ temp = cod_info->xr[j];
+ j++;
+ noise += temp * temp;
+ }
+ }
+ else if (j > cod_info->big_values) {
+ FLOAT ix01[2];
+ ix01[0] = 0;
+ ix01[1] = step;
+ while (l--) {
+ FLOAT temp;
+ temp = fabs(cod_info->xr[j]) - ix01[ix[j]];
+ j++;
+ noise += temp * temp;
+ temp = fabs(cod_info->xr[j]) - ix01[ix[j]];
+ j++;
+ noise += temp * temp;
+ }
+ }
+ else {
+ while (l--) {
+ FLOAT temp;
+ temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step;
+ j++;
+ noise += temp * temp;
+ temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step;
+ j++;
+ noise += temp * temp;
+ }
+ }
+
+ *startline = j;
+ return noise;
+}
+
+
+/*************************************************************************/
+/* calc_noise */
+/*************************************************************************/
+
+/* -oo dB => -1.00 */
+/* - 6 dB => -0.97 */
+/* - 3 dB => -0.80 */
+/* - 2 dB => -0.64 */
+/* - 1 dB => -0.38 */
+/* 0 dB => 0.00 */
+/* + 1 dB => +0.49 */
+/* + 2 dB => +1.06 */
+/* + 3 dB => +1.68 */
+/* + 6 dB => +3.69 */
+/* +10 dB => +6.45 */
+
+int
+calc_noise(gr_info const *const cod_info,
+ FLOAT const *l3_xmin,
+ FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise)
+{
+ int sfb, l, over = 0;
+ FLOAT over_noise_db = 0;
+ FLOAT tot_noise_db = 0; /* 0 dB relative to masking */
+ FLOAT max_noise = -20.0; /* -200 dB relative to masking */
+ int j = 0;
+ const int *scalefac = cod_info->scalefac;
+
+ res->over_SSD = 0;
+
+
+ for (sfb = 0; sfb < cod_info->psymax; sfb++) {
+ int const s =
+ cod_info->global_gain - (((*scalefac++) + (cod_info->preflag ? pretab[sfb] : 0))
+ << (cod_info->scalefac_scale + 1))
+ - cod_info->subblock_gain[cod_info->window[sfb]] * 8;
+ FLOAT const r_l3_xmin = 1.f / *l3_xmin++;
+ FLOAT distort_ = 0.0f;
+ FLOAT noise = 0.0f;
+
+ if (prev_noise && (prev_noise->step[sfb] == s)) {
+
+ /* use previously computed values */
+ j += cod_info->width[sfb];
+ distort_ = r_l3_xmin * prev_noise->noise[sfb];
+
+ noise = prev_noise->noise_log[sfb];
+
+ }
+ else {
+ FLOAT const step = POW20(s);
+ l = cod_info->width[sfb] >> 1;
+
+ if ((j + cod_info->width[sfb]) > cod_info->max_nonzero_coeff) {
+ int usefullsize;
+ usefullsize = cod_info->max_nonzero_coeff - j + 1;
+
+ if (usefullsize > 0)
+ l = usefullsize >> 1;
+ else
+ l = 0;
+ }
+
+ noise = calc_noise_core_c(cod_info, &j, l, step);
+
+
+ if (prev_noise) {
+ /* save noise values */
+ prev_noise->step[sfb] = s;
+ prev_noise->noise[sfb] = noise;
+ }
+
+ distort_ = r_l3_xmin * noise;
+
+ /* multiplying here is adding in dB, but can overflow */
+ noise = FAST_LOG10(Max(distort_, 1E-20f));
+
+ if (prev_noise) {
+ /* save noise values */
+ prev_noise->noise_log[sfb] = noise;
+ }
+ }
+ *distort++ = distort_;
+
+ if (prev_noise) {
+ /* save noise values */
+ prev_noise->global_gain = cod_info->global_gain;;
+ }
+
+
+ /*tot_noise *= Max(noise, 1E-20); */
+ tot_noise_db += noise;
+
+ if (noise > 0.0) {
+ int tmp;
+
+ tmp = Max((int) (noise * 10 + .5), 1);
+ res->over_SSD += tmp * tmp;
+
+ over++;
+ /* multiplying here is adding in dB -but can overflow */
+ /*over_noise *= noise; */
+ over_noise_db += noise;
+ }
+ max_noise = Max(max_noise, noise);
+
+ }
+
+ res->over_count = over;
+ res->tot_noise = tot_noise_db;
+ res->over_noise = over_noise_db;
+ res->max_noise = max_noise;
+
+ return over;
+}
+
+
+
+
+
+
+
+
+/************************************************************************
+ *
+ * set_pinfo()
+ *
+ * updates plotting data
+ *
+ * Mark Taylor 2000-??-??
+ *
+ * Robert Hegemann: moved noise/distortion calc into it
+ *
+ ************************************************************************/
+
+static void
+set_pinfo(lame_internal_flags const *gfc,
+ gr_info * const cod_info, const III_psy_ratio * const ratio, const int gr, const int ch)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int sfb, sfb2;
+ int j, i, l, start, end, bw;
+ FLOAT en0, en1;
+ FLOAT const ifqstep = (cod_info->scalefac_scale == 0) ? .5 : 1.0;
+ int const *const scalefac = cod_info->scalefac;
+
+ FLOAT l3_xmin[SFBMAX], xfsf[SFBMAX];
+ calc_noise_result noise;
+
+ (void) calc_xmin(gfc, ratio, cod_info, l3_xmin);
+ (void) calc_noise(cod_info, l3_xmin, xfsf, &noise, 0);
+
+ j = 0;
+ sfb2 = cod_info->sfb_lmax;
+ if (cod_info->block_type != SHORT_TYPE && !cod_info->mixed_block_flag)
+ sfb2 = 22;
+ for (sfb = 0; sfb < sfb2; sfb++) {
+ start = gfc->scalefac_band.l[sfb];
+ end = gfc->scalefac_band.l[sfb + 1];
+ bw = end - start;
+ for (en0 = 0.0; j < end; j++)
+ en0 += cod_info->xr[j] * cod_info->xr[j];
+ en0 /= bw;
+ /* convert to MDCT units */
+ en1 = 1e15; /* scaling so it shows up on FFT plot */
+ gfc->pinfo->en[gr][ch][sfb] = en1 * en0;
+ gfc->pinfo->xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw;
+
+ if (ratio->en.l[sfb] > 0 && !cfg->ATHonly)
+ en0 = en0 / ratio->en.l[sfb];
+ else
+ en0 = 0.0;
+
+ gfc->pinfo->thr[gr][ch][sfb] = en1 * Max(en0 * ratio->thm.l[sfb], gfc->ATH->l[sfb]);
+
+ /* there is no scalefactor bands >= SBPSY_l */
+ gfc->pinfo->LAMEsfb[gr][ch][sfb] = 0;
+ if (cod_info->preflag && sfb >= 11)
+ gfc->pinfo->LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb];
+
+ if (sfb < SBPSY_l) {
+ assert(scalefac[sfb] >= 0); /* scfsi should be decoded by caller side */
+ gfc->pinfo->LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb];
+ }
+ } /* for sfb */
+
+ if (cod_info->block_type == SHORT_TYPE) {
+ sfb2 = sfb;
+ for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {
+ start = gfc->scalefac_band.s[sfb];
+ end = gfc->scalefac_band.s[sfb + 1];
+ bw = end - start;
+ for (i = 0; i < 3; i++) {
+ for (en0 = 0.0, l = start; l < end; l++) {
+ en0 += cod_info->xr[j] * cod_info->xr[j];
+ j++;
+ }
+ en0 = Max(en0 / bw, 1e-20);
+ /* convert to MDCT units */
+ en1 = 1e15; /* scaling so it shows up on FFT plot */
+
+ gfc->pinfo->en_s[gr][ch][3 * sfb + i] = en1 * en0;
+ gfc->pinfo->xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2] * xfsf[sfb2] / bw;
+ if (ratio->en.s[sfb][i] > 0)
+ en0 = en0 / ratio->en.s[sfb][i];
+ else
+ en0 = 0.0;
+ if (cfg->ATHonly || cfg->ATHshort)
+ en0 = 0;
+
+ gfc->pinfo->thr_s[gr][ch][3 * sfb + i] =
+ en1 * Max(en0 * ratio->thm.s[sfb][i], gfc->ATH->s[sfb]);
+
+ /* there is no scalefactor bands >= SBPSY_s */
+ gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i]
+ = -2.0 * cod_info->subblock_gain[i];
+ if (sfb < SBPSY_s) {
+ gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep * scalefac[sfb2];
+ }
+ sfb2++;
+ }
+ }
+ } /* block type short */
+ gfc->pinfo->LAMEqss[gr][ch] = cod_info->global_gain;
+ gfc->pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length + cod_info->part2_length;
+ gfc->pinfo->LAMEsfbits[gr][ch] = cod_info->part2_length;
+
+ gfc->pinfo->over[gr][ch] = noise.over_count;
+ gfc->pinfo->max_noise[gr][ch] = noise.max_noise * 10.0;
+ gfc->pinfo->over_noise[gr][ch] = noise.over_noise * 10.0;
+ gfc->pinfo->tot_noise[gr][ch] = noise.tot_noise * 10.0;
+ gfc->pinfo->over_SSD[gr][ch] = noise.over_SSD;
+}
+
+
+/************************************************************************
+ *
+ * set_frame_pinfo()
+ *
+ * updates plotting data for a whole frame
+ *
+ * Robert Hegemann 2000-10-21
+ *
+ ************************************************************************/
+
+void
+set_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int ch;
+ int gr;
+
+ /* for every granule and channel patch l3_enc and set info
+ */
+ for (gr = 0; gr < cfg->mode_gr; gr++) {
+ for (ch = 0; ch < cfg->channels_out; ch++) {
+ gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
+ int scalefac_sav[SFBMAX];
+ memcpy(scalefac_sav, cod_info->scalefac, sizeof(scalefac_sav));
+
+ /* reconstruct the scalefactors in case SCFSI was used
+ */
+ if (gr == 1) {
+ int sfb;
+ for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) {
+ if (cod_info->scalefac[sfb] < 0) /* scfsi */
+ cod_info->scalefac[sfb] = gfc->l3_side.tt[0][ch].scalefac[sfb];
+ }
+ }
+
+ set_pinfo(gfc, cod_info, &ratio[gr][ch], gr, ch);
+ memcpy(cod_info->scalefac, scalefac_sav, sizeof(scalefac_sav));
+ } /* for ch */
+ } /* for gr */
+}
diff --git a/pkg/lame/clame/quantize_pvt.h b/pkg/lame/clame/quantize_pvt.h
new file mode 100644
index 0000000..b8333e7
--- /dev/null
+++ b/pkg/lame/clame/quantize_pvt.h
@@ -0,0 +1,128 @@
+/*
+ * quantize_pvt include file
+ *
+ * Copyright (c) 1999 Takehiro TOMINAGA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_QUANTIZE_PVT_H
+#define LAME_QUANTIZE_PVT_H
+
+#define IXMAX_VAL 8206 /* ix always <= 8191+15. see count_bits() */
+
+/* buggy Winamp decoder cannot handle values > 8191 */
+/* #define IXMAX_VAL 8191 */
+
+#define PRECALC_SIZE (IXMAX_VAL+2)
+
+
+extern const int nr_of_sfb_block[6][3][4];
+extern const int pretab[SBMAX_l];
+extern const int slen1_tab[16];
+extern const int slen2_tab[16];
+
+extern const scalefac_struct sfBandIndex[9];
+
+extern FLOAT pow43[PRECALC_SIZE];
+#ifdef TAKEHIRO_IEEE754_HACK
+extern FLOAT adj43asm[PRECALC_SIZE];
+#else
+extern FLOAT adj43[PRECALC_SIZE];
+#endif
+
+#define Q_MAX (256+1)
+#define Q_MAX2 116 /* minimum possible number of
+ -cod_info->global_gain
+ + ((scalefac[] + (cod_info->preflag ? pretab[sfb] : 0))
+ << (cod_info->scalefac_scale + 1))
+ + cod_info->subblock_gain[cod_info->window[sfb]] * 8;
+
+ for long block, 0+((15+3)<<2) = 18*4 = 72
+ for short block, 0+(15<<2)+7*8 = 15*4+56 = 116
+ */
+
+extern FLOAT pow20[Q_MAX + Q_MAX2 + 1];
+extern FLOAT ipow20[Q_MAX];
+
+typedef struct calc_noise_result_t {
+ FLOAT over_noise; /* sum of quantization noise > masking */
+ FLOAT tot_noise; /* sum of all quantization noise */
+ FLOAT max_noise; /* max quantization noise */
+ int over_count; /* number of quantization noise > masking */
+ int over_SSD; /* SSD-like cost of distorted bands */
+ int bits;
+} calc_noise_result;
+
+
+/**
+* allows re-use of previously
+* computed noise values
+*/
+typedef struct calc_noise_data_t {
+ int global_gain;
+ int sfb_count1;
+ int step[39];
+ FLOAT noise[39];
+ FLOAT noise_log[39];
+} calc_noise_data;
+
+
+int on_pe(lame_internal_flags * gfc, const FLOAT pe[2][2],
+ int targ_bits[2], int mean_bits, int gr, int cbr);
+
+void reduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits);
+
+
+void iteration_init(lame_internal_flags * gfc);
+
+
+int calc_xmin(lame_internal_flags const *gfc,
+ III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * l3_xmin);
+
+int calc_noise(const gr_info * const cod_info,
+ const FLOAT * l3_xmin,
+ FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise);
+
+void set_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2]);
+
+
+
+
+/* takehiro.c */
+
+int count_bits(lame_internal_flags const *const gfc, const FLOAT * const xr,
+ gr_info * const cod_info, calc_noise_data * prev_noise);
+int noquant_count_bits(lame_internal_flags const *const gfc,
+ gr_info * const cod_info, calc_noise_data * prev_noise);
+
+
+void best_huffman_divide(const lame_internal_flags * const gfc, gr_info * const cod_info);
+
+void best_scalefac_store(const lame_internal_flags * gfc, const int gr, const int ch,
+ III_side_info_t * const l3_side);
+
+int scale_bitcount(const lame_internal_flags * gfc, gr_info * cod_info);
+
+void huffman_init(lame_internal_flags * const gfc);
+
+void init_xrpow_core_init(lame_internal_flags * const gfc);
+
+FLOAT athAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint);
+
+#define LARGE_BITS 100000
+
+#endif /* LAME_QUANTIZE_PVT_H */
diff --git a/pkg/lame/clame/reservoir.c b/pkg/lame/clame/reservoir.c
new file mode 100644
index 0000000..4fdaa8d
--- /dev/null
+++ b/pkg/lame/clame/reservoir.c
@@ -0,0 +1,293 @@
+/*
+ * bit reservoir source file
+ *
+ * Copyright (c) 1999-2000 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: reservoir.c,v 1.45 2011/05/07 16:05:17 rbrito Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "reservoir.h"
+
+#include "bitstream.h"
+#include "lame-analysis.h"
+#include "lame_global_flags.h"
+
+
+/*
+ ResvFrameBegin:
+ Called (repeatedly) at the beginning of a frame. Updates the maximum
+ size of the reservoir, and checks to make sure main_data_begin
+ was set properly by the formatter
+*/
+
+/*
+ * Background information:
+ *
+ * This is the original text from the ISO standard. Because of
+ * sooo many bugs and irritations correcting comments are added
+ * in brackets []. A '^W' means you should remove the last word.
+ *
+ * 1) The following rule can be used to calculate the maximum
+ * number of bits used for one granule [^W frame]:
+ * At the highest possible bitrate of Layer III (320 kbps
+ * per stereo signal [^W^W^W], 48 kHz) the frames must be of
+ * [^W^W^W are designed to have] constant length, i.e.
+ * one buffer [^W^W the frame] length is:
+ *
+ * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte
+ *
+ * This value is used as the maximum buffer per channel [^W^W] at
+ * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps
+ * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit
+ * [per granule and channel] at 48 kHz sampling frequency.
+ * This means that there is a maximum deviation (short time buffer
+ * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps.
+ * The actual deviation is equal to the number of bytes [with the
+ * meaning of octets] denoted by the main_data_end offset pointer.
+ * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits
+ * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits].
+ * ... The xchange of buffer bits between the left and right channel
+ * is allowed without restrictions [exception: dual channel].
+ * Because of the [constructed] constraint on the buffer size
+ * main_data_end is always set to 0 in the case of bit_rate_index==14,
+ * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case
+ * all data are allocated between adjacent header [^W sync] words
+ * [, i.e. there is no buffering at all].
+ */
+
+int
+ResvFrameBegin(lame_internal_flags * gfc, int *mean_bits)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int fullFrameBits;
+ int resvLimit;
+ int maxmp3buf;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+ int frameLength;
+ int meanBits;
+
+ frameLength = getframebits(gfc);
+ meanBits = (frameLength - cfg->sideinfo_len * 8) / cfg->mode_gr;
+
+/*
+ * Meaning of the variables:
+ * resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))
+ * Number of bits can be stored in previous frame(s) due to
+ * counter size constaints
+ * maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))
+ * Number of bits allowed to encode one frame (you can take 8*511 bit
+ * from the bit reservoir and at most 8*1440 bit from the current
+ * frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible
+ * value for MPEG-1 and -2)
+ *
+ * maximum allowed granule/channel size times 4 = 8*2047 bits.,
+ * so this is the absolute maximum supported by the format.
+ *
+ *
+ * fullFrameBits: maximum number of bits available for encoding
+ * the current frame.
+ *
+ * mean_bits: target number of bits per granule.
+ *
+ * frameLength:
+ *
+ * gfc->ResvMax: maximum allowed reservoir
+ *
+ * gfc->ResvSize: current reservoir size
+ *
+ * l3_side->resvDrain_pre:
+ * ancillary data to be added to previous frame:
+ * (only usefull in VBR modes if it is possible to have
+ * maxmp3buf < fullFrameBits)). Currently disabled,
+ * see #define NEW_DRAIN
+ * 2010-02-13: RH now enabled, it seems to be needed for CBR too,
+ * as there exists one example, where the FhG decoder
+ * can't decode a -b320 CBR file anymore.
+ *
+ * l3_side->resvDrain_post:
+ * ancillary data to be added to this frame:
+ *
+ */
+
+ /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */
+ resvLimit = (8 * 256) * cfg->mode_gr - 8;
+
+ /* maximum allowed frame size. dont use more than this number of
+ bits, even if the frame has the space for them: */
+ maxmp3buf = cfg->buffer_constraint;
+ esv->ResvMax = maxmp3buf - frameLength;
+ if (esv->ResvMax > resvLimit)
+ esv->ResvMax = resvLimit;
+ if (esv->ResvMax < 0 || cfg->disable_reservoir)
+ esv->ResvMax = 0;
+
+ fullFrameBits = meanBits * cfg->mode_gr + Min(esv->ResvSize, esv->ResvMax);
+
+ if (fullFrameBits > maxmp3buf)
+ fullFrameBits = maxmp3buf;
+
+ assert(0 == esv->ResvMax % 8);
+ assert(esv->ResvMax >= 0);
+
+ l3_side->resvDrain_pre = 0;
+
+ if (gfc->pinfo != NULL) {
+ gfc->pinfo->mean_bits = meanBits / 2; /* expected bits per channel per granule [is this also right for mono/stereo, MPEG-1/2 ?] */
+ gfc->pinfo->resvsize = esv->ResvSize;
+ }
+ *mean_bits = meanBits;
+ return fullFrameBits;
+}
+
+
+/*
+ ResvMaxBits
+ returns targ_bits: target number of bits to use for 1 granule
+ extra_bits: amount extra available from reservoir
+ Mark Taylor 4/99
+*/
+void
+ResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *extra_bits, int cbr)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ int add_bits, targBits, extraBits;
+ int ResvSize = esv->ResvSize, ResvMax = esv->ResvMax;
+
+ /* conpensate the saved bits used in the 1st granule */
+ if (cbr)
+ ResvSize += mean_bits;
+
+ if (gfc->sv_qnt.substep_shaping & 1)
+ ResvMax *= 0.9;
+
+ targBits = mean_bits;
+
+ /* extra bits if the reservoir is almost full */
+ if (ResvSize * 10 > ResvMax * 9) {
+ add_bits = ResvSize - (ResvMax * 9) / 10;
+ targBits += add_bits;
+ gfc->sv_qnt.substep_shaping |= 0x80;
+ }
+ else {
+ add_bits = 0;
+ gfc->sv_qnt.substep_shaping &= 0x7f;
+ /* build up reservoir. this builds the reservoir a little slower
+ * than FhG. It could simple be mean_bits/15, but this was rigged
+ * to always produce 100 (the old value) at 128kbs */
+ /* *targ_bits -= (int) (mean_bits/15.2); */
+ if (!cfg->disable_reservoir && !(gfc->sv_qnt.substep_shaping & 1))
+ targBits -= .1 * mean_bits;
+ }
+
+
+ /* amount from the reservoir we are allowed to use. ISO says 6/10 */
+ extraBits = (ResvSize < (esv->ResvMax * 6) / 10 ? ResvSize : (esv->ResvMax * 6) / 10);
+ extraBits -= add_bits;
+
+ if (extraBits < 0)
+ extraBits = 0;
+
+ *targ_bits = targBits;
+ *extra_bits = extraBits;
+}
+
+/*
+ ResvAdjust:
+ Called after a granule's bit allocation. Readjusts the size of
+ the reservoir to reflect the granule's usage.
+*/
+void
+ResvAdjust(lame_internal_flags * gfc, gr_info const *gi)
+{
+ gfc->sv_enc.ResvSize -= gi->part2_3_length + gi->part2_length;
+}
+
+
+/*
+ ResvFrameEnd:
+ Called after all granules in a frame have been allocated. Makes sure
+ that the reservoir size is within limits, possibly by adding stuffing
+ bits.
+*/
+void
+ResvFrameEnd(lame_internal_flags * gfc, int mean_bits)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *const esv = &gfc->sv_enc;
+ III_side_info_t *const l3_side = &gfc->l3_side;
+ int stuffingBits;
+ int over_bits;
+
+ esv->ResvSize += mean_bits * cfg->mode_gr;
+ stuffingBits = 0;
+ l3_side->resvDrain_post = 0;
+ l3_side->resvDrain_pre = 0;
+
+ /* we must be byte aligned */
+ if ((over_bits = esv->ResvSize % 8) != 0)
+ stuffingBits += over_bits;
+
+
+ over_bits = (esv->ResvSize - stuffingBits) - esv->ResvMax;
+ if (over_bits > 0) {
+ assert(0 == over_bits % 8);
+ assert(over_bits >= 0);
+ stuffingBits += over_bits;
+ }
+
+
+ /* NOTE: enabling the NEW_DRAIN code fixes some problems with FhG decoder
+ shipped with MS Windows operating systems. Using this, it is even
+ possible to use Gabriel's lax buffer consideration again, which
+ assumes, any decoder should have a buffer large enough
+ for a 320 kbps frame at 32 kHz sample rate.
+
+ old drain code:
+ lame -b320 BlackBird.wav ---> does not play with GraphEdit.exe using FhG decoder V1.5 Build 50
+
+ new drain code:
+ lame -b320 BlackBird.wav ---> plays fine with GraphEdit.exe using FhG decoder V1.5 Build 50
+
+ Robert Hegemann, 2010-02-13.
+ */
+ /* drain as many bits as possible into previous frame ancillary data
+ * In particular, in VBR mode ResvMax may have changed, and we have
+ * to make sure main_data_begin does not create a reservoir bigger
+ * than ResvMax mt 4/00*/
+ {
+ int mdb_bytes = Min(l3_side->main_data_begin * 8, stuffingBits) / 8;
+ l3_side->resvDrain_pre += 8 * mdb_bytes;
+ stuffingBits -= 8 * mdb_bytes;
+ esv->ResvSize -= 8 * mdb_bytes;
+ l3_side->main_data_begin -= mdb_bytes;
+ }
+ /* drain the rest into this frames ancillary data */
+ l3_side->resvDrain_post += stuffingBits;
+ esv->ResvSize -= stuffingBits;
+}
diff --git a/pkg/lame/clame/reservoir.h b/pkg/lame/clame/reservoir.h
new file mode 100644
index 0000000..7c58593
--- /dev/null
+++ b/pkg/lame/clame/reservoir.h
@@ -0,0 +1,31 @@
+/*
+ * bit reservoir include file
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_RESERVOIR_H
+#define LAME_RESERVOIR_H
+
+int ResvFrameBegin(lame_internal_flags * gfc, int *mean_bits);
+void ResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *max_bits,
+ int cbr);
+void ResvAdjust(lame_internal_flags * gfc, gr_info const *gi);
+void ResvFrameEnd(lame_internal_flags * gfc, int mean_bits);
+
+#endif /* LAME_RESERVOIR_H */
diff --git a/pkg/lame/clame/set_get.c b/pkg/lame/clame/set_get.c
new file mode 100644
index 0000000..f763900
--- /dev/null
+++ b/pkg/lame/clame/set_get.c
@@ -0,0 +1,2346 @@
+/* -*- mode: C; mode: fold -*- */
+/*
+ * set/get functions for lame_global_flags
+ *
+ * Copyright (c) 2001-2005 Alexander Leidinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: set_get.c,v 1.104 2017/09/06 15:07:30 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "bitstream.h" /* because of compute_flushbits */
+
+#include "set_get.h"
+#include "lame_global_flags.h"
+
+/*
+ * input stream description
+ */
+
+
+/* number of samples */
+/* it's unlikely for this function to return an error */
+int
+lame_set_num_samples(lame_global_flags * gfp, unsigned long num_samples)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 2^32-1 */
+ gfp->num_samples = num_samples;
+ return 0;
+ }
+ return -1;
+}
+
+unsigned long
+lame_get_num_samples(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->num_samples;
+ }
+ return 0;
+}
+
+
+/* input samplerate */
+int
+lame_set_in_samplerate(lame_global_flags * gfp, int in_samplerate)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ if (in_samplerate < 1)
+ return -1;
+ /* input sample rate in Hz, default = 44100 Hz */
+ gfp->samplerate_in = in_samplerate;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_in_samplerate(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->samplerate_in;
+ }
+ return 0;
+}
+
+
+/* number of channels in input stream */
+int
+lame_set_num_channels(lame_global_flags * gfp, int num_channels)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 2 */
+ if (2 < num_channels || 0 >= num_channels) {
+ return -1; /* we don't support more than 2 channels */
+ }
+ gfp->num_channels = num_channels;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_num_channels(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->num_channels;
+ }
+ return 0;
+}
+
+
+/* scale the input by this amount before encoding (not used for decoding) */
+int
+lame_set_scale(lame_global_flags * gfp, float scale)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 1 */
+ gfp->scale = scale;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_scale(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->scale;
+ }
+ return 0;
+}
+
+
+/* scale the channel 0 (left) input by this amount before
+ encoding (not used for decoding) */
+int
+lame_set_scale_left(lame_global_flags * gfp, float scale)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 1 */
+ gfp->scale_left = scale;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_scale_left(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->scale_left;
+ }
+ return 0;
+}
+
+
+/* scale the channel 1 (right) input by this amount before
+ encoding (not used for decoding) */
+int
+lame_set_scale_right(lame_global_flags * gfp, float scale)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 1 */
+ gfp->scale_right = scale;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_scale_right(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->scale_right;
+ }
+ return 0;
+}
+
+
+/* output sample rate in Hz */
+int
+lame_set_out_samplerate(lame_global_flags * gfp, int out_samplerate)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /*
+ * default = 0: LAME picks best value based on the amount
+ * of compression
+ * MPEG only allows:
+ * MPEG1 32, 44.1, 48khz
+ * MPEG2 16, 22.05, 24
+ * MPEG2.5 8, 11.025, 12
+ *
+ * (not used by decoding routines)
+ */
+ if (out_samplerate != 0) {
+ int v=0;
+ if (SmpFrqIndex(out_samplerate, &v) < 0)
+ return -1;
+ }
+ gfp->samplerate_out = out_samplerate;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_out_samplerate(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->samplerate_out;
+ }
+ return 0;
+}
+
+
+
+
+/*
+ * general control parameters
+ */
+
+/* collect data for an MP3 frame analzyer */
+int
+lame_set_analysis(lame_global_flags * gfp, int analysis)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > analysis || 1 < analysis)
+ return -1;
+ gfp->analysis = analysis;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_analysis(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->analysis && 1 >= gfp->analysis);
+ return gfp->analysis;
+ }
+ return 0;
+}
+
+
+/* write a Xing VBR header frame */
+int
+lame_set_bWriteVbrTag(lame_global_flags * gfp, int bWriteVbrTag)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 1 (on) for VBR/ABR modes, 0 (off) for CBR mode */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > bWriteVbrTag || 1 < bWriteVbrTag)
+ return -1;
+ gfp->write_lame_tag = bWriteVbrTag;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_bWriteVbrTag(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->write_lame_tag && 1 >= gfp->write_lame_tag);
+ return gfp->write_lame_tag;
+ }
+ return 0;
+}
+
+
+
+/* decode only, use lame/mpglib to convert mp3 to wav */
+int
+lame_set_decode_only(lame_global_flags * gfp, int decode_only)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > decode_only || 1 < decode_only)
+ return -1;
+ gfp->decode_only = decode_only;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_decode_only(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->decode_only && 1 >= gfp->decode_only);
+ return gfp->decode_only;
+ }
+ return 0;
+}
+
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+/* 1=encode a Vorbis .ogg file. default=0 */
+/* DEPRECATED */
+int CDECL lame_set_ogg(lame_global_flags *, int);
+int CDECL lame_get_ogg(const lame_global_flags *);
+#else
+#endif
+
+/* encode a Vorbis .ogg file */
+/* DEPRECATED */
+int
+lame_set_ogg(lame_global_flags * gfp, int ogg)
+{
+ (void) gfp;
+ (void) ogg;
+ return -1;
+}
+
+int
+lame_get_ogg(const lame_global_flags * gfp)
+{
+ (void) gfp;
+ return 0;
+}
+
+
+/*
+ * Internal algorithm selection.
+ * True quality is determined by the bitrate but this variable will effect
+ * quality by selecting expensive or cheap algorithms.
+ * quality=0..9. 0=best (very slow). 9=worst.
+ * recommended: 3 near-best quality, not too slow
+ * 5 good quality, fast
+ * 7 ok quality, really fast
+ */
+int
+lame_set_quality(lame_global_flags * gfp, int quality)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ if (quality < 0) {
+ gfp->quality = 0;
+ }
+ else if (quality > 9) {
+ gfp->quality = 9;
+ }
+ else {
+ gfp->quality = quality;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_quality(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->quality;
+ }
+ return 0;
+}
+
+
+/* mode = STEREO, JOINT_STEREO, DUAL_CHANNEL (not supported), MONO */
+int
+lame_set_mode(lame_global_flags * gfp, MPEG_mode mode)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ int mpg_mode = mode;
+ /* default: lame chooses based on compression ratio and input channels */
+ if (mpg_mode < 0 || MAX_INDICATOR <= mpg_mode)
+ return -1; /* Unknown MPEG mode! */
+ gfp->mode = mode;
+ return 0;
+ }
+ return -1;
+}
+
+MPEG_mode
+lame_get_mode(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(gfp->mode < MAX_INDICATOR);
+ return gfp->mode;
+ }
+ return NOT_SET;
+}
+
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+/*
+ mode_automs. Use a M/S mode with a switching threshold based on
+ compression ratio
+ DEPRECATED
+*/
+int CDECL lame_set_mode_automs(lame_global_flags *, int);
+int CDECL lame_get_mode_automs(const lame_global_flags *);
+#else
+#endif
+
+/* Us a M/S mode with a switching threshold based on compression ratio */
+/* DEPRECATED */
+int
+lame_set_mode_automs(lame_global_flags * gfp, int mode_automs)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > mode_automs || 1 < mode_automs)
+ return -1;
+ lame_set_mode(gfp, JOINT_STEREO);
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_mode_automs(const lame_global_flags * gfp)
+{
+ (void) gfp;
+ return 1;
+}
+
+
+/*
+ * Force M/S for all frames. For testing only.
+ * Requires mode = 1.
+ */
+int
+lame_set_force_ms(lame_global_flags * gfp, int force_ms)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > force_ms || 1 < force_ms)
+ return -1;
+ gfp->force_ms = force_ms;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_force_ms(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->force_ms && 1 >= gfp->force_ms);
+ return gfp->force_ms;
+ }
+ return 0;
+}
+
+
+/* Use free_format. */
+int
+lame_set_free_format(lame_global_flags * gfp, int free_format)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > free_format || 1 < free_format)
+ return -1;
+ gfp->free_format = free_format;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_free_format(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->free_format && 1 >= gfp->free_format);
+ return gfp->free_format;
+ }
+ return 0;
+}
+
+
+
+/* Perform ReplayGain analysis */
+int
+lame_set_findReplayGain(lame_global_flags * gfp, int findReplayGain)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > findReplayGain || 1 < findReplayGain)
+ return -1;
+ gfp->findReplayGain = findReplayGain;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_findReplayGain(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->findReplayGain && 1 >= gfp->findReplayGain);
+ return gfp->findReplayGain;
+ }
+ return 0;
+}
+
+
+/* Decode on the fly. Find the peak sample. If ReplayGain analysis is
+ enabled then perform it on the decoded data. */
+int
+lame_set_decode_on_the_fly(lame_global_flags * gfp, int decode_on_the_fly)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+#ifndef DECODE_ON_THE_FLY
+ return -1;
+#else
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > decode_on_the_fly || 1 < decode_on_the_fly)
+ return -1;
+
+ gfp->decode_on_the_fly = decode_on_the_fly;
+
+ return 0;
+#endif
+ }
+ return -1;
+}
+
+int
+lame_get_decode_on_the_fly(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->decode_on_the_fly && 1 >= gfp->decode_on_the_fly);
+ return gfp->decode_on_the_fly;
+ }
+ return 0;
+}
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+/* DEPRECATED: now does the same as lame_set_findReplayGain()
+ default = 0 (disabled) */
+int CDECL lame_set_ReplayGain_input(lame_global_flags *, int);
+int CDECL lame_get_ReplayGain_input(const lame_global_flags *);
+
+/* DEPRECATED: now does the same as
+ lame_set_decode_on_the_fly() && lame_set_findReplayGain()
+ default = 0 (disabled) */
+int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int);
+int CDECL lame_get_ReplayGain_decode(const lame_global_flags *);
+
+/* DEPRECATED: now does the same as lame_set_decode_on_the_fly()
+ default = 0 (disabled) */
+int CDECL lame_set_findPeakSample(lame_global_flags *, int);
+int CDECL lame_get_findPeakSample(const lame_global_flags *);
+#else
+#endif
+
+/* DEPRECATED. same as lame_set_decode_on_the_fly() */
+int
+lame_set_findPeakSample(lame_global_flags * gfp, int arg)
+{
+ return lame_set_decode_on_the_fly(gfp, arg);
+}
+
+int
+lame_get_findPeakSample(const lame_global_flags * gfp)
+{
+ return lame_get_decode_on_the_fly(gfp);
+}
+
+/* DEPRECATED. same as lame_set_findReplayGain() */
+int
+lame_set_ReplayGain_input(lame_global_flags * gfp, int arg)
+{
+ return lame_set_findReplayGain(gfp, arg);
+}
+
+int
+lame_get_ReplayGain_input(const lame_global_flags * gfp)
+{
+ return lame_get_findReplayGain(gfp);
+}
+
+/* DEPRECATED. same as lame_set_decode_on_the_fly() &&
+ lame_set_findReplayGain() */
+int
+lame_set_ReplayGain_decode(lame_global_flags * gfp, int arg)
+{
+ if (lame_set_decode_on_the_fly(gfp, arg) < 0 || lame_set_findReplayGain(gfp, arg) < 0)
+ return -1;
+ else
+ return 0;
+}
+
+int
+lame_get_ReplayGain_decode(const lame_global_flags * gfp)
+{
+ if (lame_get_decode_on_the_fly(gfp) > 0 && lame_get_findReplayGain(gfp) > 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+/* set and get some gapless encoding flags */
+
+int
+lame_set_nogap_total(lame_global_flags * gfp, int the_nogap_total)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->nogap_total = the_nogap_total;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_nogap_total(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->nogap_total;
+ }
+ return 0;
+}
+
+int
+lame_set_nogap_currentindex(lame_global_flags * gfp, int the_nogap_index)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->nogap_current = the_nogap_index;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_nogap_currentindex(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->nogap_current;
+ }
+ return 0;
+}
+
+
+/* message handlers */
+int
+lame_set_errorf(lame_global_flags * gfp, void (*func) (const char *, va_list))
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->report.errorf = func;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_set_debugf(lame_global_flags * gfp, void (*func) (const char *, va_list))
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->report.debugf = func;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_set_msgf(lame_global_flags * gfp, void (*func) (const char *, va_list))
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->report.msgf = func;
+ return 0;
+ }
+ return -1;
+}
+
+
+/*
+ * Set one of
+ * - brate
+ * - compression ratio.
+ *
+ * Default is compression ratio of 11.
+ */
+int
+lame_set_brate(lame_global_flags * gfp, int brate)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->brate = brate;
+ if (brate > 320) {
+ gfp->disable_reservoir = 1;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_brate(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->brate;
+ }
+ return 0;
+}
+
+int
+lame_set_compression_ratio(lame_global_flags * gfp, float compression_ratio)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->compression_ratio = compression_ratio;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_compression_ratio(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->compression_ratio;
+ }
+ return 0;
+}
+
+
+
+
+/*
+ * frame parameters
+ */
+
+/* Mark as copyright protected. */
+int
+lame_set_copyright(lame_global_flags * gfp, int copyright)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > copyright || 1 < copyright)
+ return -1;
+ gfp->copyright = copyright;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_copyright(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->copyright && 1 >= gfp->copyright);
+ return gfp->copyright;
+ }
+ return 0;
+}
+
+
+/* Mark as original. */
+int
+lame_set_original(lame_global_flags * gfp, int original)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 1 (enabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > original || 1 < original)
+ return -1;
+ gfp->original = original;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_original(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->original && 1 >= gfp->original);
+ return gfp->original;
+ }
+ return 0;
+}
+
+
+/*
+ * error_protection.
+ * Use 2 bytes from each frame for CRC checksum.
+ */
+int
+lame_set_error_protection(lame_global_flags * gfp, int error_protection)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > error_protection || 1 < error_protection)
+ return -1;
+ gfp->error_protection = error_protection;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_error_protection(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->error_protection && 1 >= gfp->error_protection);
+ return gfp->error_protection;
+ }
+ return 0;
+}
+
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+/* padding_type. 0=pad no frames 1=pad all frames 2=adjust padding(default) */
+int CDECL lame_set_padding_type(lame_global_flags *, Padding_type);
+Padding_type CDECL lame_get_padding_type(const lame_global_flags *);
+#else
+#endif
+
+/*
+ * padding_type.
+ * PAD_NO = pad no frames
+ * PAD_ALL = pad all frames
+ * PAD_ADJUST = adjust padding
+ */
+int
+lame_set_padding_type(lame_global_flags * gfp, Padding_type padding_type)
+{
+ (void) gfp;
+ (void) padding_type;
+ return 0;
+}
+
+Padding_type
+lame_get_padding_type(const lame_global_flags * gfp)
+{
+ (void) gfp;
+ return PAD_ADJUST;
+}
+
+
+/* MP3 'private extension' bit. Meaningless. */
+int
+lame_set_extension(lame_global_flags * gfp, int extension)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > extension || 1 < extension)
+ return -1;
+ gfp->extension = extension;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_extension(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->extension && 1 >= gfp->extension);
+ return gfp->extension;
+ }
+ return 0;
+}
+
+
+/* Enforce strict ISO compliance. */
+int
+lame_set_strict_ISO(lame_global_flags * gfp, int val)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (val < MDB_DEFAULT || MDB_MAXIMUM < val)
+ return -1;
+ gfp->strict_ISO = val;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_strict_ISO(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->strict_ISO;
+ }
+ return 0;
+}
+
+
+
+
+/********************************************************************
+ * quantization/noise shaping
+ ***********************************************************************/
+
+/* Disable the bit reservoir. For testing only. */
+int
+lame_set_disable_reservoir(lame_global_flags * gfp, int disable_reservoir)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > disable_reservoir || 1 < disable_reservoir)
+ return -1;
+ gfp->disable_reservoir = disable_reservoir;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_disable_reservoir(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->disable_reservoir && 1 >= gfp->disable_reservoir);
+ return gfp->disable_reservoir;
+ }
+ return 0;
+}
+
+
+
+
+int
+lame_set_experimentalX(lame_global_flags * gfp, int experimentalX)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_set_quant_comp(gfp, experimentalX);
+ lame_set_quant_comp_short(gfp, experimentalX);
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_experimentalX(const lame_global_flags * gfp)
+{
+ return lame_get_quant_comp(gfp);
+}
+
+
+/* Select a different "best quantization" function. default = 0 */
+int
+lame_set_quant_comp(lame_global_flags * gfp, int quant_type)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->quant_comp = quant_type;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_quant_comp(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->quant_comp;
+ }
+ return 0;
+}
+
+
+/* Select a different "best quantization" function. default = 0 */
+int
+lame_set_quant_comp_short(lame_global_flags * gfp, int quant_type)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->quant_comp_short = quant_type;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_quant_comp_short(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->quant_comp_short;
+ }
+ return 0;
+}
+
+
+/* Another experimental option. For testing only. */
+int
+lame_set_experimentalY(lame_global_flags * gfp, int experimentalY)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->experimentalY = experimentalY;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_experimentalY(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->experimentalY;
+ }
+ return 0;
+}
+
+
+int
+lame_set_experimentalZ(lame_global_flags * gfp, int experimentalZ)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->experimentalZ = experimentalZ;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_experimentalZ(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->experimentalZ;
+ }
+ return 0;
+}
+
+
+/* Naoki's psycho acoustic model. */
+int
+lame_set_exp_nspsytune(lame_global_flags * gfp, int exp_nspsytune)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+ gfp->exp_nspsytune = exp_nspsytune;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_exp_nspsytune(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->exp_nspsytune;
+ }
+ return 0;
+}
+
+
+
+
+/********************************************************************
+ * VBR control
+ ***********************************************************************/
+
+/* Types of VBR. default = vbr_off = CBR */
+int
+lame_set_VBR(lame_global_flags * gfp, vbr_mode VBR)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ int vbr_q = VBR;
+ if (0 > vbr_q || vbr_max_indicator <= vbr_q)
+ return -1; /* Unknown VBR mode! */
+ gfp->VBR = VBR;
+ return 0;
+ }
+ return -1;
+}
+
+vbr_mode
+lame_get_VBR(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(gfp->VBR < vbr_max_indicator);
+ return gfp->VBR;
+ }
+ return vbr_off;
+}
+
+
+/*
+ * VBR quality level.
+ * 0 = highest
+ * 9 = lowest
+ */
+int
+lame_set_VBR_q(lame_global_flags * gfp, int VBR_q)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ int ret = 0;
+
+ if (0 > VBR_q) {
+ ret = -1; /* Unknown VBR quality level! */
+ VBR_q = 0;
+ }
+ if (9 < VBR_q) {
+ ret = -1;
+ VBR_q = 9;
+ }
+ gfp->VBR_q = VBR_q;
+ gfp->VBR_q_frac = 0;
+ return ret;
+ }
+ return -1;
+}
+
+int
+lame_get_VBR_q(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->VBR_q && 10 > gfp->VBR_q);
+ return gfp->VBR_q;
+ }
+ return 0;
+}
+
+int
+lame_set_VBR_quality(lame_global_flags * gfp, float VBR_q)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ int ret = 0;
+
+ if (0 > VBR_q) {
+ ret = -1; /* Unknown VBR quality level! */
+ VBR_q = 0;
+ }
+ if (9.999 < VBR_q) {
+ ret = -1;
+ VBR_q = 9.999;
+ }
+
+ gfp->VBR_q = (int) VBR_q;
+ gfp->VBR_q_frac = VBR_q - gfp->VBR_q;
+
+ return ret;
+ }
+ return -1;
+}
+
+float
+lame_get_VBR_quality(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->VBR_q + gfp->VBR_q_frac;
+ }
+ return 0;
+}
+
+
+/* Ignored except for VBR = vbr_abr (ABR mode) */
+int
+lame_set_VBR_mean_bitrate_kbps(lame_global_flags * gfp, int VBR_mean_bitrate_kbps)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->VBR_mean_bitrate_kbps = VBR_mean_bitrate_kbps;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_VBR_mean_bitrate_kbps(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->VBR_mean_bitrate_kbps;
+ }
+ return 0;
+}
+
+int
+lame_set_VBR_min_bitrate_kbps(lame_global_flags * gfp, int VBR_min_bitrate_kbps)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->VBR_min_bitrate_kbps = VBR_min_bitrate_kbps;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_VBR_min_bitrate_kbps(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->VBR_min_bitrate_kbps;
+ }
+ return 0;
+}
+
+int
+lame_set_VBR_max_bitrate_kbps(lame_global_flags * gfp, int VBR_max_bitrate_kbps)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->VBR_max_bitrate_kbps = VBR_max_bitrate_kbps;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_VBR_max_bitrate_kbps(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->VBR_max_bitrate_kbps;
+ }
+ return 0;
+}
+
+
+/*
+ * Strictly enforce VBR_min_bitrate.
+ * Normally it will be violated for analog silence.
+ */
+int
+lame_set_VBR_hard_min(lame_global_flags * gfp, int VBR_hard_min)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 (disabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > VBR_hard_min || 1 < VBR_hard_min)
+ return -1;
+
+ gfp->VBR_hard_min = VBR_hard_min;
+
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_VBR_hard_min(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->VBR_hard_min && 1 >= gfp->VBR_hard_min);
+ return gfp->VBR_hard_min;
+ }
+ return 0;
+}
+
+
+/********************************************************************
+ * Filtering control
+ ***********************************************************************/
+
+/*
+ * Freqency in Hz to apply lowpass.
+ * 0 = default = lame chooses
+ * -1 = disabled
+ */
+int
+lame_set_lowpassfreq(lame_global_flags * gfp, int lowpassfreq)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->lowpassfreq = lowpassfreq;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_lowpassfreq(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->lowpassfreq;
+ }
+ return 0;
+}
+
+
+/*
+ * Width of transition band (in Hz).
+ * default = one polyphase filter band
+ */
+int
+lame_set_lowpasswidth(lame_global_flags * gfp, int lowpasswidth)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->lowpasswidth = lowpasswidth;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_lowpasswidth(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->lowpasswidth;
+ }
+ return 0;
+}
+
+
+/*
+ * Frequency in Hz to apply highpass.
+ * 0 = default = lame chooses
+ * -1 = disabled
+ */
+int
+lame_set_highpassfreq(lame_global_flags * gfp, int highpassfreq)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->highpassfreq = highpassfreq;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_highpassfreq(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->highpassfreq;
+ }
+ return 0;
+}
+
+
+/*
+ * Width of transition band (in Hz).
+ * default = one polyphase filter band
+ */
+int
+lame_set_highpasswidth(lame_global_flags * gfp, int highpasswidth)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->highpasswidth = highpasswidth;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_highpasswidth(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->highpasswidth;
+ }
+ return 0;
+}
+
+
+
+
+/*
+ * psycho acoustics and other arguments which you should not change
+ * unless you know what you are doing
+ */
+
+
+/* Adjust masking values. */
+int
+lame_set_maskingadjust(lame_global_flags * gfp, float adjust)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->maskingadjust = adjust;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_maskingadjust(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->maskingadjust;
+ }
+ return 0;
+}
+
+int
+lame_set_maskingadjust_short(lame_global_flags * gfp, float adjust)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->maskingadjust_short = adjust;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_maskingadjust_short(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->maskingadjust_short;
+ }
+ return 0;
+}
+
+/* Only use ATH for masking. */
+int
+lame_set_ATHonly(lame_global_flags * gfp, int ATHonly)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->ATHonly = ATHonly;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_ATHonly(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->ATHonly;
+ }
+ return 0;
+}
+
+
+/* Only use ATH for short blocks. */
+int
+lame_set_ATHshort(lame_global_flags * gfp, int ATHshort)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->ATHshort = ATHshort;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_ATHshort(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->ATHshort;
+ }
+ return 0;
+}
+
+
+/* Disable ATH. */
+int
+lame_set_noATH(lame_global_flags * gfp, int noATH)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->noATH = noATH;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_noATH(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->noATH;
+ }
+ return 0;
+}
+
+
+/* Select ATH formula. */
+int
+lame_set_ATHtype(lame_global_flags * gfp, int ATHtype)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* XXX: ATHtype should be converted to an enum. */
+ gfp->ATHtype = ATHtype;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_ATHtype(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->ATHtype;
+ }
+ return 0;
+}
+
+
+/* Select ATH formula 4 shape. */
+int
+lame_set_ATHcurve(lame_global_flags * gfp, float ATHcurve)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->ATHcurve = ATHcurve;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_ATHcurve(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->ATHcurve;
+ }
+ return 0;
+}
+
+
+/* Lower ATH by this many db. */
+int
+lame_set_ATHlower(lame_global_flags * gfp, float ATHlower)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->ATH_lower_db = ATHlower;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_ATHlower(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->ATH_lower_db;
+ }
+ return 0;
+}
+
+
+/* Select ATH adaptive adjustment scheme. */
+int
+lame_set_athaa_type(lame_global_flags * gfp, int athaa_type)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->athaa_type = athaa_type;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_athaa_type(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->athaa_type;
+ }
+ return 0;
+}
+
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+int CDECL lame_set_athaa_loudapprox(lame_global_flags * gfp, int athaa_loudapprox);
+int CDECL lame_get_athaa_loudapprox(const lame_global_flags * gfp);
+#else
+#endif
+
+/* Select the loudness approximation used by the ATH adaptive auto-leveling. */
+int
+lame_set_athaa_loudapprox(lame_global_flags * gfp, int athaa_loudapprox)
+{
+ (void) gfp;
+ (void) athaa_loudapprox;
+ return 0;
+}
+
+int
+lame_get_athaa_loudapprox(const lame_global_flags * gfp)
+{
+ (void) gfp;
+ /* obsolete, the type known under number 2 is the only survival */
+ return 2;
+}
+
+
+/* Adjust (in dB) the point below which adaptive ATH level adjustment occurs. */
+int
+lame_set_athaa_sensitivity(lame_global_flags * gfp, float athaa_sensitivity)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->athaa_sensitivity = athaa_sensitivity;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_athaa_sensitivity(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->athaa_sensitivity;
+ }
+ return 0;
+}
+
+
+/* Predictability limit (ISO tonality formula) */
+int lame_set_cwlimit(lame_global_flags * gfp, int cwlimit);
+int lame_get_cwlimit(const lame_global_flags * gfp);
+
+int
+lame_set_cwlimit(lame_global_flags * gfp, int cwlimit)
+{
+ (void) gfp;
+ (void) cwlimit;
+ return 0;
+}
+
+int
+lame_get_cwlimit(const lame_global_flags * gfp)
+{
+ (void) gfp;
+ return 0;
+}
+
+
+
+/*
+ * Allow blocktypes to differ between channels.
+ * default:
+ * 0 for jstereo => block types coupled
+ * 1 for stereo => block types may differ
+ */
+int
+lame_set_allow_diff_short(lame_global_flags * gfp, int allow_diff_short)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->short_blocks = allow_diff_short ? short_block_allowed : short_block_coupled;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_allow_diff_short(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ if (gfp->short_blocks == short_block_allowed)
+ return 1; /* short blocks allowed to differ */
+ else
+ return 0; /* not set, dispensed, forced or coupled */
+ }
+ return 0;
+}
+
+
+/* Use temporal masking effect */
+int
+lame_set_useTemporal(lame_global_flags * gfp, int useTemporal)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 1 (enabled) */
+
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 <= useTemporal && useTemporal <= 1) {
+ gfp->useTemporal = useTemporal;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+lame_get_useTemporal(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->useTemporal && 1 >= gfp->useTemporal);
+ return gfp->useTemporal;
+ }
+ return 0;
+}
+
+
+/* Use inter-channel masking effect */
+int
+lame_set_interChRatio(lame_global_flags * gfp, float ratio)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0.0 (no inter-channel maskin) */
+ if (0 <= ratio && ratio <= 1.0) {
+ gfp->interChRatio = ratio;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+float
+lame_get_interChRatio(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert((0 <= gfp->interChRatio && gfp->interChRatio <= 1.0) || EQ(gfp->interChRatio, -1));
+ return gfp->interChRatio;
+ }
+ return 0;
+}
+
+
+/* Use pseudo substep shaping method */
+int
+lame_set_substep(lame_global_flags * gfp, int method)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0.0 (no substep noise shaping) */
+ if (0 <= method && method <= 7) {
+ gfp->substep_shaping = method;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+lame_get_substep(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->substep_shaping && gfp->substep_shaping <= 7);
+ return gfp->substep_shaping;
+ }
+ return 0;
+}
+
+/* scalefactors scale */
+int
+lame_set_sfscale(lame_global_flags * gfp, int val)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->noise_shaping = (val != 0) ? 2 : 1;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_sfscale(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return (gfp->noise_shaping == 2) ? 1 : 0;
+ }
+ return 0;
+}
+
+/* subblock gain */
+int
+lame_set_subblock_gain(lame_global_flags * gfp, int sbgain)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->subblock_gain = sbgain;
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_subblock_gain(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->subblock_gain;
+ }
+ return 0;
+}
+
+
+/* Disable short blocks. */
+int
+lame_set_no_short_blocks(lame_global_flags * gfp, int no_short_blocks)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 <= no_short_blocks && no_short_blocks <= 1) {
+ gfp->short_blocks = no_short_blocks ? short_block_dispensed : short_block_allowed;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+lame_get_no_short_blocks(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ switch (gfp->short_blocks) {
+ default:
+ case short_block_not_set:
+ return -1;
+ case short_block_dispensed:
+ return 1;
+ case short_block_allowed:
+ case short_block_coupled:
+ case short_block_forced:
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+/* Force short blocks. */
+int
+lame_set_force_short_blocks(lame_global_flags * gfp, int short_blocks)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* enforce disable/enable meaning, if we need more than two values
+ we need to switch to an enum to have an apropriate representation
+ of the possible meanings of the value */
+ if (0 > short_blocks || 1 < short_blocks)
+ return -1;
+
+ if (short_blocks == 1)
+ gfp->short_blocks = short_block_forced;
+ else if (gfp->short_blocks == short_block_forced)
+ gfp->short_blocks = short_block_allowed;
+
+ return 0;
+ }
+ return -1;
+}
+
+int
+lame_get_force_short_blocks(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ switch (gfp->short_blocks) {
+ default:
+ case short_block_not_set:
+ return -1;
+ case short_block_dispensed:
+ case short_block_allowed:
+ case short_block_coupled:
+ return 0;
+ case short_block_forced:
+ return 1;
+ }
+ }
+ return -1;
+}
+
+int
+lame_set_short_threshold_lrm(lame_global_flags * gfp, float lrm)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->attackthre = lrm;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_short_threshold_lrm(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->attackthre;
+ }
+ return 0;
+}
+
+int
+lame_set_short_threshold_s(lame_global_flags * gfp, float s)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->attackthre_s = s;
+ return 0;
+ }
+ return -1;
+}
+
+float
+lame_get_short_threshold_s(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->attackthre_s;
+ }
+ return 0;
+}
+
+int
+lame_set_short_threshold(lame_global_flags * gfp, float lrm, float s)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_set_short_threshold_lrm(gfp, lrm);
+ lame_set_short_threshold_s(gfp, s);
+ return 0;
+ }
+ return -1;
+}
+
+
+/*
+ * Input PCM is emphased PCM
+ * (for instance from one of the rarely emphased CDs).
+ *
+ * It is STRONGLY not recommended to use this, because psycho does not
+ * take it into account, and last but not least many decoders
+ * ignore these bits
+ */
+int
+lame_set_emphasis(lame_global_flags * gfp, int emphasis)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* XXX: emphasis should be converted to an enum */
+ if (0 <= emphasis && emphasis < 4) {
+ gfp->emphasis = emphasis;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+lame_get_emphasis(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ assert(0 <= gfp->emphasis && gfp->emphasis < 4);
+ return gfp->emphasis;
+ }
+ return 0;
+}
+
+
+
+
+/***************************************************************/
+/* internal variables, cannot be set... */
+/* provided because they may be of use to calling application */
+/***************************************************************/
+
+/* MPEG version.
+ * 0 = MPEG-2
+ * 1 = MPEG-1
+ * (2 = MPEG-2.5)
+ */
+int
+lame_get_version(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->cfg.version;
+ }
+ }
+ return 0;
+}
+
+
+/* Encoder delay. */
+int
+lame_get_encoder_delay(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->ov_enc.encoder_delay;
+ }
+ }
+ return 0;
+}
+
+/* padding added to the end of the input */
+int
+lame_get_encoder_padding(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->ov_enc.encoder_padding;
+ }
+ }
+ return 0;
+}
+
+
+/* Size of MPEG frame. */
+int
+lame_get_framesize(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ return 576 * cfg->mode_gr;
+ }
+ }
+ return 0;
+}
+
+
+/* Number of frames encoded so far. */
+int
+lame_get_frameNum(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->ov_enc.frame_number;
+ }
+ }
+ return 0;
+}
+
+int
+lame_get_mf_samples_to_encode(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->sv_enc.mf_samples_to_encode;
+ }
+ }
+ return 0;
+}
+
+int CDECL
+lame_get_size_mp3buffer(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ int size;
+ compute_flushbits(gfc, &size);
+ return size;
+ }
+ }
+ return 0;
+}
+
+int
+lame_get_RadioGain(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->ov_rpg.RadioGain;
+ }
+ }
+ return 0;
+}
+
+int
+lame_get_AudiophileGain(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return 0;
+ }
+ }
+ return 0;
+}
+
+float
+lame_get_PeakSample(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return (float) gfc->ov_rpg.PeakSample;
+ }
+ }
+ return 0;
+}
+
+int
+lame_get_noclipGainChange(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->ov_rpg.noclipGainChange;
+ }
+ }
+ return 0;
+}
+
+float
+lame_get_noclipScale(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return gfc->ov_rpg.noclipScale;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * LAME's estimate of the total number of frames to be encoded.
+ * Only valid if calling program set num_samples.
+ */
+int
+lame_get_totalframes(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ unsigned long const pcm_samples_per_frame = 576 * cfg->mode_gr;
+ unsigned long pcm_samples_to_encode = gfp->num_samples;
+ unsigned long end_padding = 0;
+ int frames = 0;
+
+ if (pcm_samples_to_encode == (0ul-1ul))
+ return 0; /* unknown */
+
+ /* estimate based on user set num_samples: */
+ if (cfg->samplerate_in != cfg->samplerate_out) {
+ /* resampling, estimate new samples_to_encode */
+ double resampled_samples_to_encode = 0.0, frames_f = 0.0;
+ if (cfg->samplerate_in > 0) {
+ resampled_samples_to_encode = pcm_samples_to_encode;
+ resampled_samples_to_encode *= cfg->samplerate_out;
+ resampled_samples_to_encode /= cfg->samplerate_in;
+ }
+ if (resampled_samples_to_encode <= 0.0)
+ return 0; /* unlikely to happen, so what, no estimate! */
+ frames_f = floor(resampled_samples_to_encode / pcm_samples_per_frame);
+ if (frames_f >= (INT_MAX-2))
+ return 0; /* overflow, happens eventually, no estimate! */
+ frames = frames_f;
+ resampled_samples_to_encode -= frames * pcm_samples_per_frame;
+ pcm_samples_to_encode = ceil(resampled_samples_to_encode);
+ }
+ else {
+ frames = pcm_samples_to_encode / pcm_samples_per_frame;
+ pcm_samples_to_encode -= frames * pcm_samples_per_frame;
+ }
+ pcm_samples_to_encode += 576ul;
+ end_padding = pcm_samples_per_frame - (pcm_samples_to_encode % pcm_samples_per_frame);
+ if (end_padding < 576ul) {
+ end_padding += pcm_samples_per_frame;
+ }
+ pcm_samples_to_encode += end_padding;
+ frames += (pcm_samples_to_encode / pcm_samples_per_frame);
+ /* check to see if we underestimated totalframes */
+ /* if (totalframes < gfp->frameNum) */
+ /* totalframes = gfp->frameNum; */
+ return frames;
+ }
+ }
+ return 0;
+}
+
+
+
+
+
+int
+lame_set_preset(lame_global_flags * gfp, int preset)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->preset = preset;
+ return apply_preset(gfp, preset, 1);
+ }
+ return -1;
+}
+
+
+
+int
+lame_set_asm_optimizations(lame_global_flags * gfp, int optim, int mode)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ mode = (mode == 1 ? 1 : 0);
+ switch (optim) {
+ case MMX:{
+ gfp->asm_optimizations.mmx = mode;
+ return optim;
+ }
+ case AMD_3DNOW:{
+ gfp->asm_optimizations.amd3dnow = mode;
+ return optim;
+ }
+ case SSE:{
+ gfp->asm_optimizations.sse = mode;
+ return optim;
+ }
+ default:
+ return optim;
+ }
+ }
+ return -1;
+}
+
+
+void
+lame_set_write_id3tag_automatic(lame_global_flags * gfp, int v)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->write_id3tag_automatic = v;
+ }
+}
+
+
+int
+lame_get_write_id3tag_automatic(lame_global_flags const *gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->write_id3tag_automatic;
+ }
+ return 1;
+}
+
+
+/*
+
+UNDOCUMENTED, experimental settings. These routines are not prototyped
+in lame.h. You should not use them, they are experimental and may
+change.
+
+*/
+
+
+/*
+ * just another daily changing developer switch
+ */
+void CDECL lame_set_tune(lame_global_flags *, float);
+
+void
+lame_set_tune(lame_global_flags * gfp, float val)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ gfp->tune_value_a = val;
+ gfp->tune = 1;
+ }
+}
+
+/* Custom msfix hack */
+void
+lame_set_msfix(lame_global_flags * gfp, double msfix)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ /* default = 0 */
+ gfp->msfix = msfix;
+ }
+}
+
+float
+lame_get_msfix(const lame_global_flags * gfp)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ return gfp->msfix;
+ }
+ return 0;
+}
+
+#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED
+int CDECL lame_set_preset_expopts(lame_global_flags *, int);
+#else
+#endif
+
+int
+lame_set_preset_expopts(lame_global_flags * gfp, int preset_expopts)
+{
+ (void) gfp;
+ (void) preset_expopts;
+ return 0;
+}
+
+
+int
+lame_set_preset_notune(lame_global_flags * gfp, int preset_notune)
+{
+ (void) gfp;
+ (void) preset_notune;
+ return 0;
+}
+
+static int
+calc_maximum_input_samples_for_buffer_size(lame_internal_flags const* gfc, size_t buffer_size)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int const pcm_samples_per_frame = 576 * cfg->mode_gr;
+ int frames_per_buffer = 0, input_samples_per_buffer = 0;
+ int kbps = 320;
+
+ if (cfg->samplerate_out < 16000)
+ kbps = 64;
+ else if (cfg->samplerate_out < 32000)
+ kbps = 160;
+ else
+ kbps = 320;
+ if (cfg->free_format)
+ kbps = cfg->avg_bitrate;
+ else if (cfg->vbr == vbr_off) {
+ kbps = cfg->avg_bitrate;
+ }
+ {
+ int const pad = 1;
+ int const bpf = ((cfg->version + 1) * 72000 * kbps / cfg->samplerate_out + pad);
+ frames_per_buffer = buffer_size / bpf;
+ }
+ {
+ double ratio = (double) cfg->samplerate_in / cfg->samplerate_out;
+ input_samples_per_buffer = pcm_samples_per_frame * frames_per_buffer * ratio;
+ }
+ return input_samples_per_buffer;
+}
+
+int
+lame_get_maximum_number_of_samples(lame_t gfp, size_t buffer_size)
+{
+ if (is_lame_global_flags_valid(gfp)) {
+ lame_internal_flags const *const gfc = gfp->internal_flags;
+ if (is_lame_internal_flags_valid(gfc)) {
+ return calc_maximum_input_samples_for_buffer_size(gfc, buffer_size);
+ }
+ }
+ return LAME_GENERICERROR;
+}
diff --git a/pkg/lame/clame/set_get.h b/pkg/lame/clame/set_get.h
new file mode 100644
index 0000000..37e4bcd
--- /dev/null
+++ b/pkg/lame/clame/set_get.h
@@ -0,0 +1,76 @@
+/*
+ * set_get.h -- Internal set/get definitions
+ *
+ * Copyright (C) 2003 Gabriel Bouvigne / Lame project
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SET_GET_H__
+#define __SET_GET_H__
+
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* select psychoacoustic model */
+
+/* manage short blocks */
+ int CDECL lame_set_short_threshold(lame_global_flags *, float, float);
+ int CDECL lame_set_short_threshold_lrm(lame_global_flags *, float);
+ float CDECL lame_get_short_threshold_lrm(const lame_global_flags *);
+ int CDECL lame_set_short_threshold_s(lame_global_flags *, float);
+ float CDECL lame_get_short_threshold_s(const lame_global_flags *);
+
+
+ int CDECL lame_set_maskingadjust(lame_global_flags *, float);
+ float CDECL lame_get_maskingadjust(const lame_global_flags *);
+
+ int CDECL lame_set_maskingadjust_short(lame_global_flags *, float);
+ float CDECL lame_get_maskingadjust_short(const lame_global_flags *);
+
+/* select ATH formula 4 shape */
+ int CDECL lame_set_ATHcurve(lame_global_flags *, float);
+ float CDECL lame_get_ATHcurve(const lame_global_flags *);
+
+ int CDECL lame_set_preset_notune(lame_global_flags *, int);
+
+/* substep shaping method */
+ int CDECL lame_set_substep(lame_global_flags *, int);
+ int CDECL lame_get_substep(const lame_global_flags *);
+
+/* scalefactors scale */
+ int CDECL lame_set_sfscale(lame_global_flags *, int);
+ int CDECL lame_get_sfscale(const lame_global_flags *);
+
+/* subblock gain */
+ int CDECL lame_set_subblock_gain(lame_global_flags *, int);
+ int CDECL lame_get_subblock_gain(const lame_global_flags *);
+
+
+
+/*presets*/
+ int apply_preset(lame_global_flags *, int preset, int enforce);
+
+ void CDECL lame_set_tune(lame_t, float); /* FOR INTERNAL USE ONLY */
+ void CDECL lame_set_msfix(lame_t gfp, double msfix);
+
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/pkg/lame/clame/tables.c b/pkg/lame/clame/tables.c
new file mode 100644
index 0000000..a023099
--- /dev/null
+++ b/pkg/lame/clame/tables.c
@@ -0,0 +1,564 @@
+/*
+ * MPEG layer 3 tables source file
+ *
+ * Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: tables.c,v 1.29 2011/05/07 16:05:17 rbrito Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "machine.h"
+
+#include "lame.h"
+#include "tables.h"
+
+
+static const uint16_t t1HB[] = {
+ 1, 1,
+ 1, 0
+};
+
+static const uint16_t t2HB[] = {
+ 1, 2, 1,
+ 3, 1, 1,
+ 3, 2, 0
+};
+
+static const uint16_t t3HB[] = {
+ 3, 2, 1,
+ 1, 1, 1,
+ 3, 2, 0
+};
+
+static const uint16_t t5HB[] = {
+ 1, 2, 6, 5,
+ 3, 1, 4, 4,
+ 7, 5, 7, 1,
+ 6, 1, 1, 0
+};
+
+static const uint16_t t6HB[] = {
+ 7, 3, 5, 1,
+ 6, 2, 3, 2,
+ 5, 4, 4, 1,
+ 3, 3, 2, 0
+};
+
+static const uint16_t t7HB[] = {
+ 1, 2, 10, 19, 16, 10,
+ 3, 3, 7, 10, 5, 3,
+ 11, 4, 13, 17, 8, 4,
+ 12, 11, 18, 15, 11, 2,
+ 7, 6, 9, 14, 3, 1,
+ 6, 4, 5, 3, 2, 0
+};
+
+static const uint16_t t8HB[] = {
+ 3, 4, 6, 18, 12, 5,
+ 5, 1, 2, 16, 9, 3,
+ 7, 3, 5, 14, 7, 3,
+ 19, 17, 15, 13, 10, 4,
+ 13, 5, 8, 11, 5, 1,
+ 12, 4, 4, 1, 1, 0
+};
+
+static const uint16_t t9HB[] = {
+ 7, 5, 9, 14, 15, 7,
+ 6, 4, 5, 5, 6, 7,
+ 7, 6, 8, 8, 8, 5,
+ 15, 6, 9, 10, 5, 1,
+ 11, 7, 9, 6, 4, 1,
+ 14, 4, 6, 2, 6, 0
+};
+
+static const uint16_t t10HB[] = {
+ 1, 2, 10, 23, 35, 30, 12, 17,
+ 3, 3, 8, 12, 18, 21, 12, 7,
+ 11, 9, 15, 21, 32, 40, 19, 6,
+ 14, 13, 22, 34, 46, 23, 18, 7,
+ 20, 19, 33, 47, 27, 22, 9, 3,
+ 31, 22, 41, 26, 21, 20, 5, 3,
+ 14, 13, 10, 11, 16, 6, 5, 1,
+ 9, 8, 7, 8, 4, 4, 2, 0
+};
+
+static const uint16_t t11HB[] = {
+ 3, 4, 10, 24, 34, 33, 21, 15,
+ 5, 3, 4, 10, 32, 17, 11, 10,
+ 11, 7, 13, 18, 30, 31, 20, 5,
+ 25, 11, 19, 59, 27, 18, 12, 5,
+ 35, 33, 31, 58, 30, 16, 7, 5,
+ 28, 26, 32, 19, 17, 15, 8, 14,
+ 14, 12, 9, 13, 14, 9, 4, 1,
+ 11, 4, 6, 6, 6, 3, 2, 0
+};
+
+static const uint16_t t12HB[] = {
+ 9, 6, 16, 33, 41, 39, 38, 26,
+ 7, 5, 6, 9, 23, 16, 26, 11,
+ 17, 7, 11, 14, 21, 30, 10, 7,
+ 17, 10, 15, 12, 18, 28, 14, 5,
+ 32, 13, 22, 19, 18, 16, 9, 5,
+ 40, 17, 31, 29, 17, 13, 4, 2,
+ 27, 12, 11, 15, 10, 7, 4, 1,
+ 27, 12, 8, 12, 6, 3, 1, 0
+};
+
+static const uint16_t t13HB[] = {
+ 1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19,
+ 3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14,
+ 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16,
+ 22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14,
+ 35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24,
+ 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17,
+ 47, 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15,
+ 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42,
+ 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16,
+ 53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11,
+ 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22,
+ 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7,
+ 34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5,
+ 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3,
+ 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2,
+ 16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1
+};
+
+static const uint16_t t15HB[] = {
+ 7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63,
+ 13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36,
+ 19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33,
+ 29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29,
+ 52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27,
+ 77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38,
+ 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30,
+ 109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25,
+ 90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20,
+ 71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15,
+ 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9,
+ 86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11,
+ 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7,
+ 91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3,
+ 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1,
+ 71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0
+};
+
+static const uint16_t t16HB[] = {
+ 1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17,
+ 3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9,
+ 15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, 110, 209, 206, 16,
+ 45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26,
+ 75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9,
+ 66, 30, 59, 56, 102, 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16,
+ 111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10,
+ 98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, 380, 889, 884, 8,
+ 85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7,
+ 154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11,
+ 139, 129, 67, 125, 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4,
+ 243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6,
+ 202, 224, 222, 218, 216, 389, 386, 381, 364, 888, 443, 707, 440, 437, 1728, 4,
+ 747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2,
+ 377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, 0,
+ 12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3
+};
+
+static const uint16_t t24HB[] = {
+ 15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88,
+ 14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42,
+ 47, 22, 41, 74, 68, 128, 120, 221, 207, 194, 182, 340, 315, 295, 541, 18,
+ 81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16,
+ 147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, 540, 14,
+ 263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12,
+ 249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10,
+ 435, 115, 111, 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17,
+ 427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16,
+ 335, 199, 197, 191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379, 371, 11,
+ 668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10,
+ 652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368, 362, 6,
+ 648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4,
+ 620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2,
+ 1033, 280, 278, 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0,
+ 43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3
+};
+
+static const uint16_t t32HB[] = {
+ 1 << 0, 5 << 1, 4 << 1, 5 << 2, 6 << 1, 5 << 2, 4 << 2, 4 << 3,
+ 7 << 1, 3 << 2, 6 << 2, 0 << 3, 7 << 2, 2 << 3, 3 << 3, 1 << 4
+};
+
+static const uint16_t t33HB[] = {
+ 15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2, 9 << 2, 8 << 3,
+ 7 << 1, 6 << 2, 5 << 2, 4 << 3, 3 << 2, 2 << 3, 1 << 3, 0 << 4
+};
+
+
+const uint8_t t1l[] = {
+ 1, 4,
+ 3, 5
+};
+
+static const uint8_t t2l[] = {
+ 1, 4, 7,
+ 4, 5, 7,
+ 6, 7, 8
+};
+
+static const uint8_t t3l[] = {
+ 2, 3, 7,
+ 4, 4, 7,
+ 6, 7, 8
+};
+
+static const uint8_t t5l[] = {
+ 1, 4, 7, 8,
+ 4, 5, 8, 9,
+ 7, 8, 9, 10,
+ 8, 8, 9, 10
+};
+
+static const uint8_t t6l[] = {
+ 3, 4, 6, 8,
+ 4, 4, 6, 7,
+ 5, 6, 7, 8,
+ 7, 7, 8, 9
+};
+
+static const uint8_t t7l[] = {
+ 1, 4, 7, 9, 9, 10,
+ 4, 6, 8, 9, 9, 10,
+ 7, 7, 9, 10, 10, 11,
+ 8, 9, 10, 11, 11, 11,
+ 8, 9, 10, 11, 11, 12,
+ 9, 10, 11, 12, 12, 12
+};
+
+static const uint8_t t8l[] = {
+ 2, 4, 7, 9, 9, 10,
+ 4, 4, 6, 10, 10, 10,
+ 7, 6, 8, 10, 10, 11,
+ 9, 10, 10, 11, 11, 12,
+ 9, 9, 10, 11, 12, 12,
+ 10, 10, 11, 11, 13, 13
+};
+
+static const uint8_t t9l[] = {
+ 3, 4, 6, 7, 9, 10,
+ 4, 5, 6, 7, 8, 10,
+ 5, 6, 7, 8, 9, 10,
+ 7, 7, 8, 9, 9, 10,
+ 8, 8, 9, 9, 10, 11,
+ 9, 9, 10, 10, 11, 11
+};
+
+static const uint8_t t10l[] = {
+ 1, 4, 7, 9, 10, 10, 10, 11,
+ 4, 6, 8, 9, 10, 11, 10, 10,
+ 7, 8, 9, 10, 11, 12, 11, 11,
+ 8, 9, 10, 11, 12, 12, 11, 12,
+ 9, 10, 11, 12, 12, 12, 12, 12,
+ 10, 11, 12, 12, 13, 13, 12, 13,
+ 9, 10, 11, 12, 12, 12, 13, 13,
+ 10, 10, 11, 12, 12, 13, 13, 13
+};
+
+static const uint8_t t11l[] = {
+ 2, 4, 6, 8, 9, 10, 9, 10,
+ 4, 5, 6, 8, 10, 10, 9, 10,
+ 6, 7, 8, 9, 10, 11, 10, 10,
+ 8, 8, 9, 11, 10, 12, 10, 11,
+ 9, 10, 10, 11, 11, 12, 11, 12,
+ 9, 10, 11, 12, 12, 13, 12, 13,
+ 9, 9, 9, 10, 11, 12, 12, 12,
+ 9, 9, 10, 11, 12, 12, 12, 12
+};
+
+static const uint8_t t12l[] = {
+ 4, 4, 6, 8, 9, 10, 10, 10,
+ 4, 5, 6, 7, 9, 9, 10, 10,
+ 6, 6, 7, 8, 9, 10, 9, 10,
+ 7, 7, 8, 8, 9, 10, 10, 10,
+ 8, 8, 9, 9, 10, 10, 10, 11,
+ 9, 9, 10, 10, 10, 11, 10, 11,
+ 9, 9, 9, 10, 10, 11, 11, 12,
+ 10, 10, 10, 11, 11, 11, 11, 12
+};
+
+static const uint8_t t13l[] = {
+ 1, 5, 7, 8, 9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14,
+ 4, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14,
+ 7, 8, 9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15,
+ 8, 9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15,
+ 9, 9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16,
+ 10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16,
+ 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16,
+ 11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18,
+ 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17,
+ 11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17,
+ 11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19,
+ 12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18,
+ 12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18,
+ 13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18,
+ 14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18,
+ 13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18
+};
+
+static const uint8_t t15l[] = {
+ 3, 5, 6, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14,
+ 5, 5, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13,
+ 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13,
+ 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13,
+ 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13,
+ 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14,
+ 10, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14,
+ 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14,
+ 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14,
+ 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14,
+ 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14,
+ 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15,
+ 12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15,
+ 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15,
+ 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15,
+ 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15
+};
+
+static const uint8_t t16_5l[] = {
+ 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11,
+ 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11,
+ 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12,
+ 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13,
+ 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12,
+ 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13,
+ 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13,
+ 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13,
+ 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13,
+ 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14,
+ 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13,
+ 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14,
+ 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14,
+ 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14,
+ 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14,
+ 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12
+};
+
+static const uint8_t t16l[] = {
+ 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10,
+ 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10,
+ 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11,
+ 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12,
+ 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11,
+ 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12,
+ 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12,
+ 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12,
+ 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12,
+ 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13,
+ 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12,
+ 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13,
+ 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13,
+ 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13,
+ 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13,
+ 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10
+};
+
+static const uint8_t t24l[] = {
+ 4, 5, 7, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10,
+ 5, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10,
+ 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 9,
+ 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 9,
+ 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 9,
+ 10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 9,
+ 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 9,
+ 11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10,
+ 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10,
+ 12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10,
+ 12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10,
+ 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10,
+ 13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 6
+};
+
+const uint8_t t32l[] = {
+ 1 + 0, 4 + 1, 4 + 1, 5 + 2, 4 + 1, 6 + 2, 5 + 2, 6 + 3,
+ 4 + 1, 5 + 2, 5 + 2, 6 + 3, 5 + 2, 6 + 3, 6 + 3, 6 + 4
+};
+
+const uint8_t t33l[] = {
+ 4 + 0, 4 + 1, 4 + 1, 4 + 2, 4 + 1, 4 + 2, 4 + 2, 4 + 3,
+ 4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 2, 4 + 3, 4 + 3, 4 + 4
+};
+
+
+const struct huffcodetab ht[HTN] = {
+ /* xlen, linmax, table, hlen */
+ {0, 0, NULL, NULL},
+ {2, 0, t1HB, t1l},
+ {3, 0, t2HB, t2l},
+ {3, 0, t3HB, t3l},
+ {0, 0, NULL, NULL}, /* Apparently not used */
+ {4, 0, t5HB, t5l},
+ {4, 0, t6HB, t6l},
+ {6, 0, t7HB, t7l},
+ {6, 0, t8HB, t8l},
+ {6, 0, t9HB, t9l},
+ {8, 0, t10HB, t10l},
+ {8, 0, t11HB, t11l},
+ {8, 0, t12HB, t12l},
+ {16, 0, t13HB, t13l},
+ {0, 0, NULL, t16_5l}, /* Apparently not used */
+ {16, 0, t15HB, t15l},
+
+ {1, 1, t16HB, t16l},
+ {2, 3, t16HB, t16l},
+ {3, 7, t16HB, t16l},
+ {4, 15, t16HB, t16l},
+ {6, 63, t16HB, t16l},
+ {8, 255, t16HB, t16l},
+ {10, 1023, t16HB, t16l},
+ {13, 8191, t16HB, t16l},
+
+ {4, 15, t24HB, t24l},
+ {5, 31, t24HB, t24l},
+ {6, 63, t24HB, t24l},
+ {7, 127, t24HB, t24l},
+ {8, 255, t24HB, t24l},
+ {9, 511, t24HB, t24l},
+ {11, 2047, t24HB, t24l},
+ {13, 8191, t24HB, t24l},
+
+ {0, 0, t32HB, t32l},
+ {0, 0, t33HB, t33l},
+};
+
+
+
+
+
+/* for (i = 0; i < 16*16; i++) {
+ * largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i];
+ * }
+ */
+const uint32_t largetbl[16 * 16] = {
+ 0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b,
+ 0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a,
+ 0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b,
+ 0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a,
+ 0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b,
+ 0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009,
+ 0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b,
+ 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009,
+ 0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b,
+ 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009,
+ 0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b,
+ 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009,
+ 0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b,
+ 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009,
+ 0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b,
+ 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a,
+ 0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b,
+ 0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a,
+ 0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c,
+ 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a,
+ 0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c,
+ 0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a,
+ 0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c,
+ 0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a,
+ 0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c,
+ 0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a,
+ 0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c,
+ 0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a,
+ 0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d,
+ 0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a,
+ 0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009,
+ 0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006
+};
+
+/* for (i = 0; i < 3*3; i++) {
+ * table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i];
+ * }
+ */
+const uint32_t table23[3 * 3] = {
+ 0x010002, 0x040003, 0x070007,
+ 0x040004, 0x050004, 0x070007,
+ 0x060006, 0x070007, 0x080008
+};
+
+/* for (i = 0; i < 4*4; i++) {
+ * table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i];
+ * }
+ */
+const uint32_t table56[4 * 4] = {
+ 0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007,
+ 0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009
+};
+
+
+
+/*
+ * 0: MPEG-2 LSF
+ * 1: MPEG-1
+ * 2: MPEG-2.5 LSF FhG extention (1995-07-11 shn)
+ */
+
+typedef enum {
+ MPEG_2 = 0,
+ MPEG_1 = 1,
+ MPEG_25 = 2
+} MPEG_t;
+
+const int bitrate_table[3][16] = {
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, /* MPEG 2 */
+ {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1}, /* MPEG 1 */
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1}, /* MPEG 2.5 */
+};
+
+const int samplerate_table[3][4] = {
+ {22050, 24000, 16000, -1}, /* MPEG 2 */
+ {44100, 48000, 32000, -1}, /* MPEG 1 */
+ {11025, 12000, 8000, -1}, /* MPEG 2.5 */
+};
+
+int
+lame_get_bitrate(int mpeg_version, int table_index)
+{
+ if (0 <= mpeg_version && mpeg_version <= 2) {
+ if (0 <= table_index && table_index <= 15) {
+ return bitrate_table[mpeg_version][table_index];
+ }
+ }
+ return -1;
+}
+
+int
+lame_get_samplerate(int mpeg_version, int table_index)
+{
+ if (0 <= mpeg_version && mpeg_version <= 2) {
+ if (0 <= table_index && table_index <= 3) {
+ return samplerate_table[mpeg_version][table_index];
+ }
+ }
+ return -1;
+}
+
+
+/* This is the scfsi_band table from 2.4.2.7 of the IS */
+const int scfsi_band[5] = { 0, 6, 11, 16, 21 };
+
+/* end of tables.c */
diff --git a/pkg/lame/clame/tables.h b/pkg/lame/clame/tables.h
new file mode 100644
index 0000000..0dd7deb
--- /dev/null
+++ b/pkg/lame/clame/tables.h
@@ -0,0 +1,95 @@
+/*
+ * MPEG layer 3 tables include file
+ *
+ * Copyright (c) 1999 Albert L Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_TABLES_H
+#define LAME_TABLES_H
+
+#if 0
+typedef struct {
+ unsigned char no;
+ unsigned char width;
+ unsigned char minval_2;
+ float quiet_thr;
+ float norm;
+ float bark;
+} type1_t;
+
+typedef struct {
+ unsigned char no;
+ unsigned char width;
+ float quiet_thr;
+ float norm;
+ float SNR;
+ float bark;
+} type2_t;
+
+typedef struct {
+ unsigned int no:5;
+ unsigned int cbw:3;
+ unsigned int bu:6;
+ unsigned int bo:6;
+ unsigned int w1_576:10;
+ unsigned int w2_576:10;
+} type34_t;
+
+typedef struct {
+ size_t len1;
+ const type1_t *const tab1;
+ size_t len2;
+ const type2_t *const tab2;
+ size_t len3;
+ const type34_t *const tab3;
+ size_t len4;
+ const type34_t *const tab4;
+} type5_t;
+
+extern const type5_t table5[6];
+
+#endif
+
+#define HTN 34
+
+struct huffcodetab {
+ const unsigned int xlen; /* max. x-index+ */
+ const unsigned int linmax; /* max number to be stored in linbits */
+ const uint16_t *table; /* pointer to array[xlen][ylen] */
+ const uint8_t *hlen; /* pointer to array[xlen][ylen] */
+};
+
+extern const struct huffcodetab ht[HTN];
+ /* global memory block */
+ /* array of all huffcodtable headers */
+ /* 0..31 Huffman code table 0..31 */
+ /* 32,33 count1-tables */
+
+extern const uint8_t t32l[];
+extern const uint8_t t33l[];
+
+extern const uint32_t largetbl[16 * 16];
+extern const uint32_t table23[3 * 3];
+extern const uint32_t table56[4 * 4];
+
+extern const int scfsi_band[5];
+
+extern const int bitrate_table [3][16];
+extern const int samplerate_table [3][ 4];
+
+#endif /* LAME_TABLES_H */
diff --git a/pkg/lame/clame/takehiro.c b/pkg/lame/clame/takehiro.c
new file mode 100644
index 0000000..67aba1b
--- /dev/null
+++ b/pkg/lame/clame/takehiro.c
@@ -0,0 +1,1375 @@
+/*
+ * MP3 huffman table selecting and bit counting
+ *
+ * Copyright (c) 1999-2005 Takehiro TOMINAGA
+ * Copyright (c) 2002-2005 Gabriel Bouvigne
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: takehiro.c,v 1.80 2017/09/06 15:07:30 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "quantize_pvt.h"
+#include "tables.h"
+
+
+static const struct {
+ const int region0_count;
+ const int region1_count;
+} subdv_table[23] = {
+ {
+ 0, 0}, /* 0 bands */
+ {
+ 0, 0}, /* 1 bands */
+ {
+ 0, 0}, /* 2 bands */
+ {
+ 0, 0}, /* 3 bands */
+ {
+ 0, 0}, /* 4 bands */
+ {
+ 0, 1}, /* 5 bands */
+ {
+ 1, 1}, /* 6 bands */
+ {
+ 1, 1}, /* 7 bands */
+ {
+ 1, 2}, /* 8 bands */
+ {
+ 2, 2}, /* 9 bands */
+ {
+ 2, 3}, /* 10 bands */
+ {
+ 2, 3}, /* 11 bands */
+ {
+ 3, 4}, /* 12 bands */
+ {
+ 3, 4}, /* 13 bands */
+ {
+ 3, 4}, /* 14 bands */
+ {
+ 4, 5}, /* 15 bands */
+ {
+ 4, 5}, /* 16 bands */
+ {
+ 4, 6}, /* 17 bands */
+ {
+ 5, 6}, /* 18 bands */
+ {
+ 5, 6}, /* 19 bands */
+ {
+ 5, 7}, /* 20 bands */
+ {
+ 6, 7}, /* 21 bands */
+ {
+ 6, 7}, /* 22 bands */
+};
+
+
+
+
+
+/*********************************************************************
+ * nonlinear quantization of xr
+ * More accurate formula than the ISO formula. Takes into account
+ * the fact that we are quantizing xr -> ix, but we want ix^4/3 to be
+ * as close as possible to x^4/3. (taking the nearest int would mean
+ * ix is as close as possible to xr, which is different.)
+ *
+ * From Segher Boessenkool 11/1999
+ *
+ * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro
+ * Tominaga. If you need the ASM code, check CVS circa Aug 2000.
+ *
+ * 01/2004: Optimizations by Gabriel Bouvigne
+ *********************************************************************/
+
+
+
+
+
+static void
+quantize_lines_xrpow_01(unsigned int l, FLOAT istep, const FLOAT * xr, int *ix)
+{
+ const FLOAT compareval0 = (1.0f - 0.4054f) / istep;
+ unsigned int i;
+
+ assert(l > 0);
+ assert(l % 2 == 0);
+ for (i = 0; i < l; i += 2) {
+ FLOAT const xr_0 = xr[i+0];
+ FLOAT const xr_1 = xr[i+1];
+ int const ix_0 = (compareval0 > xr_0) ? 0 : 1;
+ int const ix_1 = (compareval0 > xr_1) ? 0 : 1;
+ ix[i+0] = ix_0;
+ ix[i+1] = ix_1;
+ }
+}
+
+
+
+#ifdef TAKEHIRO_IEEE754_HACK
+
+typedef union {
+ float f;
+ int i;
+} fi_union;
+
+#define MAGIC_FLOAT (65536*(128))
+#define MAGIC_INT 0x4b000000
+
+
+static void
+quantize_lines_xrpow(unsigned int l, FLOAT istep, const FLOAT * xp, int *pi)
+{
+ fi_union *fi;
+ unsigned int remaining;
+
+ assert(l > 0);
+
+ fi = (fi_union *) pi;
+
+ l = l >> 1;
+ remaining = l % 2;
+ l = l >> 1;
+ while (l--) {
+ double x0 = istep * xp[0];
+ double x1 = istep * xp[1];
+ double x2 = istep * xp[2];
+ double x3 = istep * xp[3];
+
+ x0 += MAGIC_FLOAT;
+ fi[0].f = x0;
+ x1 += MAGIC_FLOAT;
+ fi[1].f = x1;
+ x2 += MAGIC_FLOAT;
+ fi[2].f = x2;
+ x3 += MAGIC_FLOAT;
+ fi[3].f = x3;
+
+ fi[0].f = x0 + adj43asm[fi[0].i - MAGIC_INT];
+ fi[1].f = x1 + adj43asm[fi[1].i - MAGIC_INT];
+ fi[2].f = x2 + adj43asm[fi[2].i - MAGIC_INT];
+ fi[3].f = x3 + adj43asm[fi[3].i - MAGIC_INT];
+
+ fi[0].i -= MAGIC_INT;
+ fi[1].i -= MAGIC_INT;
+ fi[2].i -= MAGIC_INT;
+ fi[3].i -= MAGIC_INT;
+ fi += 4;
+ xp += 4;
+ };
+ if (remaining) {
+ double x0 = istep * xp[0];
+ double x1 = istep * xp[1];
+
+ x0 += MAGIC_FLOAT;
+ fi[0].f = x0;
+ x1 += MAGIC_FLOAT;
+ fi[1].f = x1;
+
+ fi[0].f = x0 + adj43asm[fi[0].i - MAGIC_INT];
+ fi[1].f = x1 + adj43asm[fi[1].i - MAGIC_INT];
+
+ fi[0].i -= MAGIC_INT;
+ fi[1].i -= MAGIC_INT;
+ }
+
+}
+
+
+#else
+
+/*********************************************************************
+ * XRPOW_FTOI is a macro to convert floats to ints.
+ * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
+ * ROUNDFAC= -0.0946
+ *
+ * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
+ * ROUNDFAC=0.4054
+ *
+ * Note: using floor() or (int) is extremely slow. On machines where
+ * the TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile
+ * to write some ASM for XRPOW_FTOI().
+ *********************************************************************/
+#define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
+#define QUANTFAC(rx) adj43[rx]
+#define ROUNDFAC 0.4054
+
+
+static void
+quantize_lines_xrpow(unsigned int l, FLOAT istep, const FLOAT * xr, int *ix)
+{
+ unsigned int remaining;
+
+ assert(l > 0);
+
+ l = l >> 1;
+ remaining = l % 2;
+ l = l >> 1;
+ while (l--) {
+ FLOAT x0, x1, x2, x3;
+ int rx0, rx1, rx2, rx3;
+
+ x0 = *xr++ * istep;
+ x1 = *xr++ * istep;
+ XRPOW_FTOI(x0, rx0);
+ x2 = *xr++ * istep;
+ XRPOW_FTOI(x1, rx1);
+ x3 = *xr++ * istep;
+ XRPOW_FTOI(x2, rx2);
+ x0 += QUANTFAC(rx0);
+ XRPOW_FTOI(x3, rx3);
+ x1 += QUANTFAC(rx1);
+ XRPOW_FTOI(x0, *ix++);
+ x2 += QUANTFAC(rx2);
+ XRPOW_FTOI(x1, *ix++);
+ x3 += QUANTFAC(rx3);
+ XRPOW_FTOI(x2, *ix++);
+ XRPOW_FTOI(x3, *ix++);
+ };
+ if (remaining) {
+ FLOAT x0, x1;
+ int rx0, rx1;
+
+ x0 = *xr++ * istep;
+ x1 = *xr++ * istep;
+ XRPOW_FTOI(x0, rx0);
+ XRPOW_FTOI(x1, rx1);
+ x0 += QUANTFAC(rx0);
+ x1 += QUANTFAC(rx1);
+ XRPOW_FTOI(x0, *ix++);
+ XRPOW_FTOI(x1, *ix++);
+ }
+
+}
+
+
+
+#endif
+
+
+
+/*********************************************************************
+ * Quantization function
+ * This function will select which lines to quantize and call the
+ * proper quantization function
+ *********************************************************************/
+
+static void
+quantize_xrpow(const FLOAT * xp, int *pi, FLOAT istep, gr_info const *const cod_info,
+ calc_noise_data const *prev_noise)
+{
+ /* quantize on xr^(3/4) instead of xr */
+ int sfb;
+ int sfbmax;
+ int j = 0;
+ int prev_data_use;
+ int *iData;
+ int accumulate = 0;
+ int accumulate01 = 0;
+ int *acc_iData;
+ const FLOAT *acc_xp;
+
+ iData = pi;
+ acc_xp = xp;
+ acc_iData = iData;
+
+
+ /* Reusing previously computed data does not seems to work if global gain
+ is changed. Finding why it behaves this way would allow to use a cache of
+ previously computed values (let's 10 cached values per sfb) that would
+ probably provide a noticeable speedup */
+ prev_data_use = (prev_noise && (cod_info->global_gain == prev_noise->global_gain));
+
+ if (cod_info->block_type == SHORT_TYPE)
+ sfbmax = 38;
+ else
+ sfbmax = 21;
+
+ for (sfb = 0; sfb <= sfbmax; sfb++) {
+ int step = -1;
+
+ if (prev_data_use || cod_info->block_type == NORM_TYPE) {
+ step =
+ cod_info->global_gain
+ - ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0))
+ << (cod_info->scalefac_scale + 1))
+ - cod_info->subblock_gain[cod_info->window[sfb]] * 8;
+ }
+ assert(cod_info->width[sfb] >= 0);
+ if (prev_data_use && (prev_noise->step[sfb] == step)) {
+ /* do not recompute this part,
+ but compute accumulated lines */
+ if (accumulate) {
+ quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);
+ accumulate = 0;
+ }
+ if (accumulate01) {
+ quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);
+ accumulate01 = 0;
+ }
+ }
+ else { /*should compute this part */
+ int l;
+ l = cod_info->width[sfb];
+
+ if ((j + cod_info->width[sfb]) > cod_info->max_nonzero_coeff) {
+ /*do not compute upper zero part */
+ int usefullsize;
+ usefullsize = cod_info->max_nonzero_coeff - j + 1;
+ memset(&pi[cod_info->max_nonzero_coeff], 0,
+ sizeof(int) * (576 - cod_info->max_nonzero_coeff));
+ l = usefullsize;
+
+ if (l < 0) {
+ l = 0;
+ }
+
+ /* no need to compute higher sfb values */
+ sfb = sfbmax + 1;
+ }
+
+ /*accumulate lines to quantize */
+ if (!accumulate && !accumulate01) {
+ acc_iData = iData;
+ acc_xp = xp;
+ }
+ if (prev_noise &&
+ prev_noise->sfb_count1 > 0 &&
+ sfb >= prev_noise->sfb_count1 &&
+ prev_noise->step[sfb] > 0 && step >= prev_noise->step[sfb]) {
+
+ if (accumulate) {
+ quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);
+ accumulate = 0;
+ acc_iData = iData;
+ acc_xp = xp;
+ }
+ accumulate01 += l;
+ }
+ else {
+ if (accumulate01) {
+ quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);
+ accumulate01 = 0;
+ acc_iData = iData;
+ acc_xp = xp;
+ }
+ accumulate += l;
+ }
+
+ if (l <= 0) {
+ /* rh: 20040215
+ * may happen due to "prev_data_use" optimization
+ */
+ if (accumulate01) {
+ quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);
+ accumulate01 = 0;
+ }
+ if (accumulate) {
+ quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);
+ accumulate = 0;
+ }
+
+ break; /* ends for-loop */
+ }
+ }
+ if (sfb <= sfbmax) {
+ iData += cod_info->width[sfb];
+ xp += cod_info->width[sfb];
+ j += cod_info->width[sfb];
+ }
+ }
+ if (accumulate) { /*last data part */
+ quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);
+ accumulate = 0;
+ }
+ if (accumulate01) { /*last data part */
+ quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);
+ accumulate01 = 0;
+ }
+
+}
+
+
+
+
+/*************************************************************************/
+/* ix_max */
+/*************************************************************************/
+
+static int
+ix_max(const int *ix, const int *end)
+{
+ int max1 = 0, max2 = 0;
+
+ do {
+ int const x1 = *ix++;
+ int const x2 = *ix++;
+ if (max1 < x1)
+ max1 = x1;
+
+ if (max2 < x2)
+ max2 = x2;
+ } while (ix < end);
+ if (max1 < max2)
+ max1 = max2;
+ return max1;
+}
+
+
+
+
+
+
+
+
+static int
+count_bit_ESC(const int *ix, const int *const end, int t1, const int t2, unsigned int *const s)
+{
+ /* ESC-table is used */
+ unsigned int const linbits = ht[t1].xlen * 65536u + ht[t2].xlen;
+ unsigned int sum = 0, sum2;
+
+ do {
+ unsigned int x = *ix++;
+ unsigned int y = *ix++;
+
+ if (x >= 15u) {
+ x = 15u;
+ sum += linbits;
+ }
+ if (y >= 15u) {
+ y = 15u;
+ sum += linbits;
+ }
+ x <<= 4u;
+ x += y;
+ sum += largetbl[x];
+ } while (ix < end);
+
+ sum2 = sum & 0xffffu;
+ sum >>= 16u;
+
+ if (sum > sum2) {
+ sum = sum2;
+ t1 = t2;
+ }
+
+ *s += sum;
+ return t1;
+}
+
+
+static int
+count_bit_noESC(const int *ix, const int *end, int mx, unsigned int *s)
+{
+ /* No ESC-words */
+ unsigned int sum1 = 0;
+ const uint8_t *const hlen1 = ht[1].hlen;
+ (void) mx;
+
+ do {
+ unsigned int const x0 = *ix++;
+ unsigned int const x1 = *ix++;
+ sum1 += hlen1[ x0+x0 + x1 ];
+ } while (ix < end);
+
+ *s += sum1;
+ return 1;
+}
+
+
+static const int huf_tbl_noESC[] = {
+ 1, 2, 5, 7, 7, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13
+};
+
+
+static int
+count_bit_noESC_from2(const int *ix, const int *end, int max, unsigned int *s)
+{
+ int t1 = huf_tbl_noESC[max - 1];
+ /* No ESC-words */
+ const unsigned int xlen = ht[t1].xlen;
+ uint32_t const* table = (t1 == 2) ? &table23[0] : &table56[0];
+ unsigned int sum = 0, sum2;
+
+ do {
+ unsigned int const x0 = *ix++;
+ unsigned int const x1 = *ix++;
+ sum += table[ x0 * xlen + x1 ];
+ } while (ix < end);
+
+ sum2 = sum & 0xffffu;
+ sum >>= 16u;
+
+ if (sum > sum2) {
+ sum = sum2;
+ t1++;
+ }
+
+ *s += sum;
+ return t1;
+}
+
+
+inline static int
+count_bit_noESC_from3(const int *ix, const int *end, int max, unsigned int * s)
+{
+ int t1 = huf_tbl_noESC[max - 1];
+ /* No ESC-words */
+ unsigned int sum1 = 0;
+ unsigned int sum2 = 0;
+ unsigned int sum3 = 0;
+ const unsigned int xlen = ht[t1].xlen;
+ const uint8_t *const hlen1 = ht[t1].hlen;
+ const uint8_t *const hlen2 = ht[t1 + 1].hlen;
+ const uint8_t *const hlen3 = ht[t1 + 2].hlen;
+ int t;
+
+ do {
+ unsigned int x0 = *ix++;
+ unsigned int x1 = *ix++;
+ unsigned int x = x0 * xlen + x1;
+ sum1 += hlen1[x];
+ sum2 += hlen2[x];
+ sum3 += hlen3[x];
+ } while (ix < end);
+
+ t = t1;
+ if (sum1 > sum2) {
+ sum1 = sum2;
+ t++;
+ }
+ if (sum1 > sum3) {
+ sum1 = sum3;
+ t = t1 + 2;
+ }
+ *s += sum1;
+
+ return t;
+}
+
+
+/*************************************************************************/
+/* choose table */
+/*************************************************************************/
+
+/*
+ Choose the Huffman table that will encode ix[begin..end] with
+ the fewest bits.
+
+ Note: This code contains knowledge about the sizes and characteristics
+ of the Huffman tables as defined in the IS (Table B.7), and will not work
+ with any arbitrary tables.
+*/
+static int count_bit_null(const int* ix, const int* end, int max, unsigned int* s)
+{
+ (void) ix;
+ (void) end;
+ (void) max;
+ (void) s;
+ return 0;
+}
+
+typedef int (*count_fnc)(const int* ix, const int* end, int max, unsigned int* s);
+
+static const count_fnc count_fncs[] =
+{ &count_bit_null
+, &count_bit_noESC
+, &count_bit_noESC_from2
+, &count_bit_noESC_from2
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+, &count_bit_noESC_from3
+};
+
+static int
+choose_table_nonMMX(const int *ix, const int *const end, int *const _s)
+{
+ unsigned int* s = (unsigned int*)_s;
+ unsigned int max;
+ int choice, choice2;
+ max = ix_max(ix, end);
+
+ if (max <= 15) {
+ return count_fncs[max](ix, end, max, s);
+ }
+ /* try tables with linbits */
+ if (max > IXMAX_VAL) {
+ *s = LARGE_BITS;
+ return -1;
+ }
+ max -= 15u;
+ for (choice2 = 24; choice2 < 32; choice2++) {
+ if (ht[choice2].linmax >= max) {
+ break;
+ }
+ }
+
+ for (choice = choice2 - 8; choice < 24; choice++) {
+ if (ht[choice].linmax >= max) {
+ break;
+ }
+ }
+ return count_bit_ESC(ix, end, choice, choice2, s);
+}
+
+
+
+/*************************************************************************/
+/* count_bit */
+/*************************************************************************/
+int
+noquant_count_bits(lame_internal_flags const *const gfc,
+ gr_info * const gi, calc_noise_data * prev_noise)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int bits = 0;
+ int i, a1, a2;
+ int const *const ix = gi->l3_enc;
+
+ i = Min(576, ((gi->max_nonzero_coeff + 2) >> 1) << 1);
+
+ if (prev_noise)
+ prev_noise->sfb_count1 = 0;
+
+ /* Determine count1 region */
+ for (; i > 1; i -= 2)
+ if (ix[i - 1] | ix[i - 2])
+ break;
+ gi->count1 = i;
+
+ /* Determines the number of bits to encode the quadruples. */
+ a1 = a2 = 0;
+ for (; i > 3; i -= 4) {
+ int x4 = ix[i-4];
+ int x3 = ix[i-3];
+ int x2 = ix[i-2];
+ int x1 = ix[i-1];
+ int p;
+ /* hack to check if all values <= 1 */
+ if ((unsigned int) (x4 | x3 | x2 | x1) > 1)
+ break;
+
+ p = ((x4 * 2 + x3) * 2 + x2) * 2 + x1;
+ a1 += t32l[p];
+ a2 += t33l[p];
+ }
+
+ bits = a1;
+ gi->count1table_select = 0;
+ if (a1 > a2) {
+ bits = a2;
+ gi->count1table_select = 1;
+ }
+
+ gi->count1bits = bits;
+ gi->big_values = i;
+ if (i == 0)
+ return bits;
+
+ if (gi->block_type == SHORT_TYPE) {
+ a1 = 3 * gfc->scalefac_band.s[3];
+ if (a1 > gi->big_values)
+ a1 = gi->big_values;
+ a2 = gi->big_values;
+
+ }
+ else if (gi->block_type == NORM_TYPE) {
+ assert(i <= 576); /* bv_scf has 576 entries (0..575) */
+ a1 = gi->region0_count = gfc->sv_qnt.bv_scf[i - 2];
+ a2 = gi->region1_count = gfc->sv_qnt.bv_scf[i - 1];
+
+ assert(a1 + a2 + 2 < SBPSY_l);
+ a2 = gfc->scalefac_band.l[a1 + a2 + 2];
+ a1 = gfc->scalefac_band.l[a1 + 1];
+ if (a2 < i)
+ gi->table_select[2] = gfc->choose_table(ix + a2, ix + i, &bits);
+
+ }
+ else {
+ gi->region0_count = 7;
+ /*gi->region1_count = SBPSY_l - 7 - 1; */
+ gi->region1_count = SBMAX_l - 1 - 7 - 1;
+ a1 = gfc->scalefac_band.l[7 + 1];
+ a2 = i;
+ if (a1 > a2) {
+ a1 = a2;
+ }
+ }
+
+
+ /* have to allow for the case when bigvalues < region0 < region1 */
+ /* (and region0, region1 are ignored) */
+ a1 = Min(a1, i);
+ a2 = Min(a2, i);
+
+ assert(a1 >= 0);
+ assert(a2 >= 0);
+
+ /* Count the number of bits necessary to code the bigvalues region. */
+ if (0 < a1)
+ gi->table_select[0] = gfc->choose_table(ix, ix + a1, &bits);
+ if (a1 < a2)
+ gi->table_select[1] = gfc->choose_table(ix + a1, ix + a2, &bits);
+ if (cfg->use_best_huffman == 2) {
+ gi->part2_3_length = bits;
+ best_huffman_divide(gfc, gi);
+ bits = gi->part2_3_length;
+ }
+
+
+ if (prev_noise) {
+ if (gi->block_type == NORM_TYPE) {
+ int sfb = 0;
+ while (gfc->scalefac_band.l[sfb] < gi->big_values) {
+ sfb++;
+ }
+ prev_noise->sfb_count1 = sfb;
+ }
+ }
+
+ return bits;
+}
+
+int
+count_bits(lame_internal_flags const *const gfc,
+ const FLOAT * const xr, gr_info * const gi, calc_noise_data * prev_noise)
+{
+ int *const ix = gi->l3_enc;
+
+ /* since quantize_xrpow uses table lookup, we need to check this first: */
+ FLOAT const w = (IXMAX_VAL) / IPOW20(gi->global_gain);
+
+ if (gi->xrpow_max > w)
+ return LARGE_BITS;
+
+ quantize_xrpow(xr, ix, IPOW20(gi->global_gain), gi, prev_noise);
+
+ if (gfc->sv_qnt.substep_shaping & 2) {
+ int sfb, j = 0;
+ /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */
+ int const gain = gi->global_gain + gi->scalefac_scale;
+ const FLOAT roundfac = 0.634521682242439 / IPOW20(gain);
+ for (sfb = 0; sfb < gi->sfbmax; sfb++) {
+ int const width = gi->width[sfb];
+ assert(width >= 0);
+ if (!gfc->sv_qnt.pseudohalf[sfb]) {
+ j += width;
+ }
+ else {
+ int k;
+ for (k = j, j += width; k < j; ++k) {
+ ix[k] = (xr[k] >= roundfac) ? ix[k] : 0;
+ }
+ }
+ }
+ }
+ return noquant_count_bits(gfc, gi, prev_noise);
+}
+
+/***********************************************************************
+ re-calculate the best scalefac_compress using scfsi
+ the saved bits are kept in the bit reservoir.
+ **********************************************************************/
+
+
+inline static void
+recalc_divide_init(const lame_internal_flags * const gfc,
+ gr_info const *cod_info,
+ int const *const ix, int r01_bits[], int r01_div[], int r0_tbl[], int r1_tbl[])
+{
+ int r0, r1, bigv, r0t, r1t, bits;
+
+ bigv = cod_info->big_values;
+
+ for (r0 = 0; r0 <= 7 + 15; r0++) {
+ r01_bits[r0] = LARGE_BITS;
+ }
+
+ for (r0 = 0; r0 < 16; r0++) {
+ int const a1 = gfc->scalefac_band.l[r0 + 1];
+ int r0bits;
+ if (a1 >= bigv)
+ break;
+ r0bits = 0;
+ r0t = gfc->choose_table(ix, ix + a1, &r0bits);
+
+ for (r1 = 0; r1 < 8; r1++) {
+ int const a2 = gfc->scalefac_band.l[r0 + r1 + 2];
+ if (a2 >= bigv)
+ break;
+
+ bits = r0bits;
+ r1t = gfc->choose_table(ix + a1, ix + a2, &bits);
+ if (r01_bits[r0 + r1] > bits) {
+ r01_bits[r0 + r1] = bits;
+ r01_div[r0 + r1] = r0;
+ r0_tbl[r0 + r1] = r0t;
+ r1_tbl[r0 + r1] = r1t;
+ }
+ }
+ }
+}
+
+inline static void
+recalc_divide_sub(const lame_internal_flags * const gfc,
+ const gr_info * cod_info2,
+ gr_info * const gi,
+ const int *const ix,
+ const int r01_bits[], const int r01_div[], const int r0_tbl[], const int r1_tbl[])
+{
+ int bits, r2, a2, bigv, r2t;
+
+ bigv = cod_info2->big_values;
+
+ for (r2 = 2; r2 < SBMAX_l + 1; r2++) {
+ a2 = gfc->scalefac_band.l[r2];
+ if (a2 >= bigv)
+ break;
+
+ bits = r01_bits[r2 - 2] + cod_info2->count1bits;
+ if (gi->part2_3_length <= bits)
+ break;
+
+ r2t = gfc->choose_table(ix + a2, ix + bigv, &bits);
+ if (gi->part2_3_length <= bits)
+ continue;
+
+ memcpy(gi, cod_info2, sizeof(gr_info));
+ gi->part2_3_length = bits;
+ gi->region0_count = r01_div[r2 - 2];
+ gi->region1_count = r2 - 2 - r01_div[r2 - 2];
+ gi->table_select[0] = r0_tbl[r2 - 2];
+ gi->table_select[1] = r1_tbl[r2 - 2];
+ gi->table_select[2] = r2t;
+ }
+}
+
+
+
+
+void
+best_huffman_divide(const lame_internal_flags * const gfc, gr_info * const gi)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int i, a1, a2;
+ gr_info cod_info2;
+ int const *const ix = gi->l3_enc;
+
+ int r01_bits[7 + 15 + 1];
+ int r01_div[7 + 15 + 1];
+ int r0_tbl[7 + 15 + 1];
+ int r1_tbl[7 + 15 + 1];
+
+
+ /* SHORT BLOCK stuff fails for MPEG2 */
+ if (gi->block_type == SHORT_TYPE && cfg->mode_gr == 1)
+ return;
+
+
+ memcpy(&cod_info2, gi, sizeof(gr_info));
+ if (gi->block_type == NORM_TYPE) {
+ recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl);
+ recalc_divide_sub(gfc, &cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl);
+ }
+
+ i = cod_info2.big_values;
+ if (i == 0 || (unsigned int) (ix[i - 2] | ix[i - 1]) > 1)
+ return;
+
+ i = gi->count1 + 2;
+ if (i > 576)
+ return;
+
+ /* Determines the number of bits to encode the quadruples. */
+ memcpy(&cod_info2, gi, sizeof(gr_info));
+ cod_info2.count1 = i;
+ a1 = a2 = 0;
+
+ assert(i <= 576);
+
+ for (; i > cod_info2.big_values; i -= 4) {
+ int const p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1];
+ a1 += t32l[p];
+ a2 += t33l[p];
+ }
+ cod_info2.big_values = i;
+
+ cod_info2.count1table_select = 0;
+ if (a1 > a2) {
+ a1 = a2;
+ cod_info2.count1table_select = 1;
+ }
+
+ cod_info2.count1bits = a1;
+
+ if (cod_info2.block_type == NORM_TYPE)
+ recalc_divide_sub(gfc, &cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl);
+ else {
+ /* Count the number of bits necessary to code the bigvalues region. */
+ cod_info2.part2_3_length = a1;
+ a1 = gfc->scalefac_band.l[7 + 1];
+ if (a1 > i) {
+ a1 = i;
+ }
+ if (a1 > 0)
+ cod_info2.table_select[0] =
+ gfc->choose_table(ix, ix + a1, (int *) &cod_info2.part2_3_length);
+ if (i > a1)
+ cod_info2.table_select[1] =
+ gfc->choose_table(ix + a1, ix + i, (int *) &cod_info2.part2_3_length);
+ if (gi->part2_3_length > cod_info2.part2_3_length)
+ memcpy(gi, &cod_info2, sizeof(gr_info));
+ }
+}
+
+static const int slen1_n[16] = { 1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16 };
+static const int slen2_n[16] = { 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8 };
+const int slen1_tab[16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 };
+const int slen2_tab[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 };
+
+static void
+scfsi_calc(int ch, III_side_info_t * l3_side)
+{
+ unsigned int i;
+ int s1, s2, c1, c2;
+ int sfb;
+ gr_info *const gi = &l3_side->tt[1][ch];
+ gr_info const *const g0 = &l3_side->tt[0][ch];
+
+ for (i = 0; i < (sizeof(scfsi_band) / sizeof(int)) - 1; i++) {
+ for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) {
+ if (g0->scalefac[sfb] != gi->scalefac[sfb]
+ && gi->scalefac[sfb] >= 0)
+ break;
+ }
+ if (sfb == scfsi_band[i + 1]) {
+ for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) {
+ gi->scalefac[sfb] = -1;
+ }
+ l3_side->scfsi[ch][i] = 1;
+ }
+ }
+
+ s1 = c1 = 0;
+ for (sfb = 0; sfb < 11; sfb++) {
+ if (gi->scalefac[sfb] == -1)
+ continue;
+ c1++;
+ if (s1 < gi->scalefac[sfb])
+ s1 = gi->scalefac[sfb];
+ }
+
+ s2 = c2 = 0;
+ for (; sfb < SBPSY_l; sfb++) {
+ if (gi->scalefac[sfb] == -1)
+ continue;
+ c2++;
+ if (s2 < gi->scalefac[sfb])
+ s2 = gi->scalefac[sfb];
+ }
+
+ for (i = 0; i < 16; i++) {
+ if (s1 < slen1_n[i] && s2 < slen2_n[i]) {
+ int const c = slen1_tab[i] * c1 + slen2_tab[i] * c2;
+ if (gi->part2_length > c) {
+ gi->part2_length = c;
+ gi->scalefac_compress = (int)i;
+ }
+ }
+ }
+}
+
+/*
+Find the optimal way to store the scalefactors.
+Only call this routine after final scalefactors have been
+chosen and the channel/granule will not be re-encoded.
+ */
+void
+best_scalefac_store(const lame_internal_flags * gfc,
+ const int gr, const int ch, III_side_info_t * const l3_side)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ /* use scalefac_scale if we can */
+ gr_info *const gi = &l3_side->tt[gr][ch];
+ int sfb, i, j, l;
+ int recalc = 0;
+
+ /* remove scalefacs from bands with ix=0. This idea comes
+ * from the AAC ISO docs. added mt 3/00 */
+ /* check if l3_enc=0 */
+ j = 0;
+ for (sfb = 0; sfb < gi->sfbmax; sfb++) {
+ int const width = gi->width[sfb];
+ assert(width >= 0);
+ for (l = j, j += width; l < j; ++l) {
+ if (gi->l3_enc[l] != 0)
+ break;
+ }
+ if (l == j)
+ gi->scalefac[sfb] = recalc = -2; /* anything goes. */
+ /* only best_scalefac_store and calc_scfsi
+ * know--and only they should know--about the magic number -2.
+ */
+ }
+
+ if (!gi->scalefac_scale && !gi->preflag) {
+ int s = 0;
+ for (sfb = 0; sfb < gi->sfbmax; sfb++)
+ if (gi->scalefac[sfb] > 0)
+ s |= gi->scalefac[sfb];
+
+ if (!(s & 1) && s != 0) {
+ for (sfb = 0; sfb < gi->sfbmax; sfb++)
+ if (gi->scalefac[sfb] > 0)
+ gi->scalefac[sfb] >>= 1;
+
+ gi->scalefac_scale = recalc = 1;
+ }
+ }
+
+ if (!gi->preflag && gi->block_type != SHORT_TYPE && cfg->mode_gr == 2) {
+ for (sfb = 11; sfb < SBPSY_l; sfb++)
+ if (gi->scalefac[sfb] < pretab[sfb] && gi->scalefac[sfb] != -2)
+ break;
+ if (sfb == SBPSY_l) {
+ for (sfb = 11; sfb < SBPSY_l; sfb++)
+ if (gi->scalefac[sfb] > 0)
+ gi->scalefac[sfb] -= pretab[sfb];
+
+ gi->preflag = recalc = 1;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ l3_side->scfsi[ch][i] = 0;
+
+ if (cfg->mode_gr == 2 && gr == 1
+ && l3_side->tt[0][ch].block_type != SHORT_TYPE
+ && l3_side->tt[1][ch].block_type != SHORT_TYPE) {
+ scfsi_calc(ch, l3_side);
+ recalc = 0;
+ }
+ for (sfb = 0; sfb < gi->sfbmax; sfb++) {
+ if (gi->scalefac[sfb] == -2) {
+ gi->scalefac[sfb] = 0; /* if anything goes, then 0 is a good choice */
+ }
+ }
+ if (recalc) {
+ (void) scale_bitcount(gfc, gi);
+ }
+}
+
+
+#ifndef NDEBUG
+static int
+all_scalefactors_not_negative(int const *scalefac, int n)
+{
+ int i;
+ for (i = 0; i < n; ++i) {
+ if (scalefac[i] < 0)
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+
+/* number of bits used to encode scalefacs */
+
+/* 18*slen1_tab[i] + 18*slen2_tab[i] */
+static const int scale_short[16] = {
+ 0, 18, 36, 54, 54, 36, 54, 72, 54, 72, 90, 72, 90, 108, 108, 126
+};
+
+/* 17*slen1_tab[i] + 18*slen2_tab[i] */
+static const int scale_mixed[16] = {
+ 0, 18, 36, 54, 51, 35, 53, 71, 52, 70, 88, 69, 87, 105, 104, 122
+};
+
+/* 11*slen1_tab[i] + 10*slen2_tab[i] */
+static const int scale_long[16] = {
+ 0, 10, 20, 30, 33, 21, 31, 41, 32, 42, 52, 43, 53, 63, 64, 74
+};
+
+
+/*************************************************************************/
+/* scale_bitcount */
+/*************************************************************************/
+
+/* Also calculates the number of bits necessary to code the scalefactors. */
+
+static int
+mpeg1_scale_bitcount(const lame_internal_flags * gfc, gr_info * const cod_info)
+{
+ int k, sfb, max_slen1 = 0, max_slen2 = 0;
+
+ /* maximum values */
+ const int *tab;
+ int *const scalefac = cod_info->scalefac;
+
+ (void) gfc;
+ assert(all_scalefactors_not_negative(scalefac, cod_info->sfbmax));
+
+ if (cod_info->block_type == SHORT_TYPE) {
+ tab = scale_short;
+ if (cod_info->mixed_block_flag)
+ tab = scale_mixed;
+ }
+ else { /* block_type == 1,2,or 3 */
+ tab = scale_long;
+ if (!cod_info->preflag) {
+ for (sfb = 11; sfb < SBPSY_l; sfb++)
+ if (scalefac[sfb] < pretab[sfb])
+ break;
+
+ if (sfb == SBPSY_l) {
+ cod_info->preflag = 1;
+ for (sfb = 11; sfb < SBPSY_l; sfb++)
+ scalefac[sfb] -= pretab[sfb];
+ }
+ }
+ }
+
+ for (sfb = 0; sfb < cod_info->sfbdivide; sfb++)
+ if (max_slen1 < scalefac[sfb])
+ max_slen1 = scalefac[sfb];
+
+ for (; sfb < cod_info->sfbmax; sfb++)
+ if (max_slen2 < scalefac[sfb])
+ max_slen2 = scalefac[sfb];
+
+ /* from Takehiro TOMINAGA 10/99
+ * loop over *all* posible values of scalefac_compress to find the
+ * one which uses the smallest number of bits. ISO would stop
+ * at first valid index */
+ cod_info->part2_length = LARGE_BITS;
+ for (k = 0; k < 16; k++) {
+ if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k]
+ && cod_info->part2_length > tab[k]) {
+ cod_info->part2_length = tab[k];
+ cod_info->scalefac_compress = k;
+ }
+ }
+ return cod_info->part2_length == LARGE_BITS;
+}
+
+
+
+/*
+ table of largest scalefactor values for MPEG2
+*/
+static const int max_range_sfac_tab[6][4] = {
+ {15, 15, 7, 7},
+ {15, 15, 7, 0},
+ {7, 3, 0, 0},
+ {15, 31, 31, 0},
+ {7, 7, 7, 0},
+ {3, 3, 0, 0}
+};
+
+
+
+
+/*************************************************************************/
+/* scale_bitcount_lsf */
+/*************************************************************************/
+
+/* Also counts the number of bits to encode the scalefacs but for MPEG 2 */
+/* Lower sampling frequencies (24, 22.05 and 16 kHz.) */
+
+/* This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS, */
+/* "Audio Decoding Layer III" */
+
+static int
+mpeg2_scale_bitcount(const lame_internal_flags * gfc, gr_info * const cod_info)
+{
+ int table_number, row_in_table, partition, nr_sfb, window, over;
+ int i, sfb, max_sfac[4];
+ const int *partition_table;
+ int const *const scalefac = cod_info->scalefac;
+
+ /*
+ Set partition table. Note that should try to use table one,
+ but do not yet...
+ */
+ if (cod_info->preflag)
+ table_number = 2;
+ else
+ table_number = 0;
+
+ for (i = 0; i < 4; i++)
+ max_sfac[i] = 0;
+
+ if (cod_info->block_type == SHORT_TYPE) {
+ row_in_table = 1;
+ partition_table = &nr_of_sfb_block[table_number][row_in_table][0];
+ for (sfb = 0, partition = 0; partition < 4; partition++) {
+ nr_sfb = partition_table[partition] / 3;
+ for (i = 0; i < nr_sfb; i++, sfb++)
+ for (window = 0; window < 3; window++)
+ if (scalefac[sfb * 3 + window] > max_sfac[partition])
+ max_sfac[partition] = scalefac[sfb * 3 + window];
+ }
+ }
+ else {
+ row_in_table = 0;
+ partition_table = &nr_of_sfb_block[table_number][row_in_table][0];
+ for (sfb = 0, partition = 0; partition < 4; partition++) {
+ nr_sfb = partition_table[partition];
+ for (i = 0; i < nr_sfb; i++, sfb++)
+ if (scalefac[sfb] > max_sfac[partition])
+ max_sfac[partition] = scalefac[sfb];
+ }
+ }
+
+ for (over = 0, partition = 0; partition < 4; partition++) {
+ if (max_sfac[partition] > max_range_sfac_tab[table_number][partition])
+ over++;
+ }
+ if (!over) {
+ /*
+ Since no bands have been over-amplified, we can set scalefac_compress
+ and slen[] for the formatter
+ */
+ static const int log2tab[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
+
+ int slen1, slen2, slen3, slen4;
+
+ cod_info->sfb_partition_table = nr_of_sfb_block[table_number][row_in_table];
+ for (partition = 0; partition < 4; partition++)
+ cod_info->slen[partition] = log2tab[max_sfac[partition]];
+
+ /* set scalefac_compress */
+ slen1 = cod_info->slen[0];
+ slen2 = cod_info->slen[1];
+ slen3 = cod_info->slen[2];
+ slen4 = cod_info->slen[3];
+
+ switch (table_number) {
+ case 0:
+ cod_info->scalefac_compress = (((slen1 * 5) + slen2) << 4)
+ + (slen3 << 2)
+ + slen4;
+ break;
+
+ case 1:
+ cod_info->scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2)
+ + slen3;
+ break;
+
+ case 2:
+ cod_info->scalefac_compress = 500 + (slen1 * 3) + slen2;
+ break;
+
+ default:
+ ERRORF(gfc, "intensity stereo not implemented yet\n");
+ break;
+ }
+ }
+#ifdef DEBUG
+ if (over)
+ ERRORF(gfc, "---WARNING !! Amplification of some bands over limits\n");
+#endif
+ if (!over) {
+ assert(cod_info->sfb_partition_table);
+ cod_info->part2_length = 0;
+ for (partition = 0; partition < 4; partition++)
+ cod_info->part2_length +=
+ cod_info->slen[partition] * cod_info->sfb_partition_table[partition];
+ }
+ return over;
+}
+
+
+int
+scale_bitcount(const lame_internal_flags * gfc, gr_info * cod_info)
+{
+ if (gfc->cfg.mode_gr == 2) {
+ return mpeg1_scale_bitcount(gfc, cod_info);
+ }
+ else {
+ return mpeg2_scale_bitcount(gfc, cod_info);
+ }
+}
+
+
+#ifdef MMX_choose_table
+extern int choose_table_MMX(const int *ix, const int *const end, int *const s);
+#endif
+
+void
+huffman_init(lame_internal_flags * const gfc)
+{
+ int i;
+
+ gfc->choose_table = choose_table_nonMMX;
+
+#ifdef MMX_choose_table
+ if (gfc->CPU_features.MMX) {
+ gfc->choose_table = choose_table_MMX;
+ }
+#endif
+
+ for (i = 2; i <= 576; i += 2) {
+ int scfb_anz = 0, bv_index;
+ while (gfc->scalefac_band.l[++scfb_anz] < i);
+
+ bv_index = subdv_table[scfb_anz].region0_count;
+ while (gfc->scalefac_band.l[bv_index + 1] > i)
+ bv_index--;
+
+ if (bv_index < 0) {
+ /* this is an indication that everything is going to
+ be encoded as region0: bigvalues < region0 < region1
+ so lets set region0, region1 to some value larger
+ than bigvalues */
+ bv_index = subdv_table[scfb_anz].region0_count;
+ }
+
+ gfc->sv_qnt.bv_scf[i - 2] = bv_index;
+
+ bv_index = subdv_table[scfb_anz].region1_count;
+ while (gfc->scalefac_band.l[bv_index + gfc->sv_qnt.bv_scf[i - 2] + 2] > i)
+ bv_index--;
+
+ if (bv_index < 0) {
+ bv_index = subdv_table[scfb_anz].region1_count;
+ }
+
+ gfc->sv_qnt.bv_scf[i - 1] = bv_index;
+ }
+}
diff --git a/pkg/lame/clame/util.c b/pkg/lame/clame/util.c
new file mode 100644
index 0000000..43b457c
--- /dev/null
+++ b/pkg/lame/clame/util.c
@@ -0,0 +1,1018 @@
+/*
+ * lame utility library source file
+ *
+ * Copyright (c) 1999 Albert L Faber
+ * Copyright (c) 2000-2005 Alexander Leidinger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: util.c,v 1.159 2017/09/06 15:07:30 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "tables.h"
+
+#define PRECOMPUTE
+#if defined(__FreeBSD__) && !defined(__alpha__)
+# include
+#endif
+
+
+/***********************************************************************
+*
+* Global Function Definitions
+*
+***********************************************************************/
+/*empty and close mallocs in gfc */
+
+void
+free_id3tag(lame_internal_flags * const gfc)
+{
+ gfc->tag_spec.language[0] = 0;
+ if (gfc->tag_spec.title != 0) {
+ free(gfc->tag_spec.title);
+ gfc->tag_spec.title = 0;
+ }
+ if (gfc->tag_spec.artist != 0) {
+ free(gfc->tag_spec.artist);
+ gfc->tag_spec.artist = 0;
+ }
+ if (gfc->tag_spec.album != 0) {
+ free(gfc->tag_spec.album);
+ gfc->tag_spec.album = 0;
+ }
+ if (gfc->tag_spec.comment != 0) {
+ free(gfc->tag_spec.comment);
+ gfc->tag_spec.comment = 0;
+ }
+
+ if (gfc->tag_spec.albumart != 0) {
+ free(gfc->tag_spec.albumart);
+ gfc->tag_spec.albumart = 0;
+ gfc->tag_spec.albumart_size = 0;
+ gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE;
+ }
+ if (gfc->tag_spec.v2_head != 0) {
+ FrameDataNode *node = gfc->tag_spec.v2_head;
+ do {
+ void *p = node->dsc.ptr.b;
+ void *q = node->txt.ptr.b;
+ void *r = node;
+ node = node->nxt;
+ free(p);
+ free(q);
+ free(r);
+ } while (node != 0);
+ gfc->tag_spec.v2_head = 0;
+ gfc->tag_spec.v2_tail = 0;
+ }
+}
+
+
+static void
+free_global_data(lame_internal_flags * gfc)
+{
+ if (gfc && gfc->cd_psy) {
+ if (gfc->cd_psy->l.s3) {
+ /* XXX allocated in psymodel_init() */
+ free(gfc->cd_psy->l.s3);
+ }
+ if (gfc->cd_psy->s.s3) {
+ /* XXX allocated in psymodel_init() */
+ free(gfc->cd_psy->s.s3);
+ }
+ free(gfc->cd_psy);
+ gfc->cd_psy = 0;
+ }
+}
+
+
+void
+freegfc(lame_internal_flags * const gfc)
+{ /* bit stream structure */
+ int i;
+
+ if (gfc == 0) return;
+
+ for (i = 0; i <= 2 * BPC; i++)
+ if (gfc->sv_enc.blackfilt[i] != NULL) {
+ free(gfc->sv_enc.blackfilt[i]);
+ gfc->sv_enc.blackfilt[i] = NULL;
+ }
+ if (gfc->sv_enc.inbuf_old[0]) {
+ free(gfc->sv_enc.inbuf_old[0]);
+ gfc->sv_enc.inbuf_old[0] = NULL;
+ }
+ if (gfc->sv_enc.inbuf_old[1]) {
+ free(gfc->sv_enc.inbuf_old[1]);
+ gfc->sv_enc.inbuf_old[1] = NULL;
+ }
+
+ if (gfc->bs.buf != NULL) {
+ free(gfc->bs.buf);
+ gfc->bs.buf = NULL;
+ }
+
+ if (gfc->VBR_seek_table.bag) {
+ free(gfc->VBR_seek_table.bag);
+ gfc->VBR_seek_table.bag = NULL;
+ gfc->VBR_seek_table.size = 0;
+ }
+ if (gfc->ATH) {
+ free(gfc->ATH);
+ }
+ if (gfc->sv_rpg.rgdata) {
+ free(gfc->sv_rpg.rgdata);
+ }
+ if (gfc->sv_enc.in_buffer_0) {
+ free(gfc->sv_enc.in_buffer_0);
+ }
+ if (gfc->sv_enc.in_buffer_1) {
+ free(gfc->sv_enc.in_buffer_1);
+ }
+ free_id3tag(gfc);
+
+#ifdef DECODE_ON_THE_FLY
+ if (gfc->hip) {
+ hip_decode_exit(gfc->hip);
+ gfc->hip = 0;
+ }
+#endif
+
+ free_global_data(gfc);
+
+ free(gfc);
+}
+
+void
+calloc_aligned(aligned_pointer_t * ptr, unsigned int size, unsigned int bytes)
+{
+ if (ptr) {
+ if (!ptr->pointer) {
+ ptr->pointer = malloc(size + bytes);
+ if (ptr->pointer != 0) {
+ memset(ptr->pointer, 0, size + bytes);
+ if (bytes > 0) {
+ ptr->aligned = (void *) ((((size_t) ptr->pointer + bytes - 1) / bytes) * bytes);
+ }
+ else {
+ ptr->aligned = ptr->pointer;
+ }
+ }
+ else {
+ ptr->aligned = 0;
+ }
+ }
+ }
+}
+
+void
+free_aligned(aligned_pointer_t * ptr)
+{
+ if (ptr) {
+ if (ptr->pointer) {
+ free(ptr->pointer);
+ ptr->pointer = 0;
+ ptr->aligned = 0;
+ }
+ }
+}
+
+/*those ATH formulas are returning
+their minimum value for input = -1*/
+
+static FLOAT
+ATHformula_GB(FLOAT f, FLOAT value, FLOAT f_min, FLOAT f_max)
+{
+ /* from Painter & Spanias
+ modified by Gabriel Bouvigne to better fit the reality
+ ath = 3.640 * pow(f,-0.8)
+ - 6.800 * exp(-0.6*pow(f-3.4,2.0))
+ + 6.000 * exp(-0.15*pow(f-8.7,2.0))
+ + 0.6* 0.001 * pow(f,4.0);
+
+
+ In the past LAME was using the Painter &Spanias formula.
+ But we had some recurrent problems with HF content.
+ We measured real ATH values, and found the older formula
+ to be inacurate in the higher part. So we made this new
+ formula and this solved most of HF problematic testcases.
+ The tradeoff is that in VBR mode it increases a lot the
+ bitrate. */
+
+
+/*this curve can be udjusted according to the VBR scale:
+it adjusts from something close to Painter & Spanias
+on V9 up to Bouvigne's formula for V0. This way the VBR
+bitrate is more balanced according to the -V value.*/
+
+ FLOAT ath;
+
+ /* the following Hack allows to ask for the lowest value */
+ if (f < -.3)
+ f = 3410;
+
+ f /= 1000; /* convert to khz */
+ f = Max(f_min, f);
+ f = Min(f_max, f);
+
+ ath = 3.640 * pow(f, -0.8)
+ - 6.800 * exp(-0.6 * pow(f - 3.4, 2.0))
+ + 6.000 * exp(-0.15 * pow(f - 8.7, 2.0))
+ + (0.6 + 0.04 * value) * 0.001 * pow(f, 4.0);
+ return ath;
+}
+
+
+
+FLOAT
+ATHformula(SessionConfig_t const *cfg, FLOAT f)
+{
+ FLOAT ath;
+ switch (cfg->ATHtype) {
+ case 0:
+ ath = ATHformula_GB(f, 9, 0.1f, 24.0f);
+ break;
+ case 1:
+ ath = ATHformula_GB(f, -1, 0.1f, 24.0f); /*over sensitive, should probably be removed */
+ break;
+ case 2:
+ ath = ATHformula_GB(f, 0, 0.1f, 24.0f);
+ break;
+ case 3:
+ ath = ATHformula_GB(f, 1, 0.1f, 24.0f) + 6; /*modification of GB formula by Roel */
+ break;
+ case 4:
+ ath = ATHformula_GB(f, cfg->ATHcurve, 0.1f, 24.0f);
+ break;
+ case 5:
+ ath = ATHformula_GB(f, cfg->ATHcurve, 3.41f, 16.1f);
+ break;
+ default:
+ ath = ATHformula_GB(f, 0, 0.1f, 24.0f);
+ break;
+ }
+ return ath;
+}
+
+/* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
+FLOAT
+freq2bark(FLOAT freq)
+{
+ /* input: freq in hz output: barks */
+ if (freq < 0)
+ freq = 0;
+ freq = freq * 0.001;
+ return 13.0 * atan(.76 * freq) + 3.5 * atan(freq * freq / (7.5 * 7.5));
+}
+
+#if 0
+extern FLOAT freq2cbw(FLOAT freq);
+
+/* see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */
+FLOAT
+freq2cbw(FLOAT freq)
+{
+ /* input: freq in hz output: critical band width */
+ freq = freq * 0.001;
+ return 25 + 75 * pow(1 + 1.4 * (freq * freq), 0.69);
+}
+
+#endif
+
+
+
+
+#define ABS(A) (((A)>0) ? (A) : -(A))
+
+int
+FindNearestBitrate(int bRate, /* legal rates from 8 to 320 */
+ int version, int samplerate)
+{ /* MPEG-1 or MPEG-2 LSF */
+ int bitrate;
+ int i;
+
+ if (samplerate < 16000)
+ version = 2;
+
+ bitrate = bitrate_table[version][1];
+
+ for (i = 2; i <= 14; i++) {
+ if (bitrate_table[version][i] > 0) {
+ if (ABS(bitrate_table[version][i] - bRate) < ABS(bitrate - bRate))
+ bitrate = bitrate_table[version][i];
+ }
+ }
+ return bitrate;
+}
+
+
+
+
+
+#ifndef Min
+#define Min(A, B) ((A) < (B) ? (A) : (B))
+#endif
+#ifndef Max
+#define Max(A, B) ((A) > (B) ? (A) : (B))
+#endif
+
+
+/* Used to find table index when
+ * we need bitrate-based values
+ * determined using tables
+ *
+ * bitrate in kbps
+ *
+ * Gabriel Bouvigne 2002-11-03
+ */
+int
+nearestBitrateFullIndex(uint16_t bitrate)
+{
+ /* borrowed from DM abr presets */
+
+ const int full_bitrate_table[] =
+ { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
+
+
+ int lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0;
+
+
+ int b;
+
+
+ /* We assume specified bitrate will be 320kbps */
+ upper_range_kbps = full_bitrate_table[16];
+ upper_range = 16;
+ lower_range_kbps = full_bitrate_table[16];
+ lower_range = 16;
+
+ /* Determine which significant bitrates the value specified falls between,
+ * if loop ends without breaking then we were correct above that the value was 320
+ */
+ for (b = 0; b < 16; b++) {
+ if ((Max(bitrate, full_bitrate_table[b + 1])) != bitrate) {
+ upper_range_kbps = full_bitrate_table[b + 1];
+ upper_range = b + 1;
+ lower_range_kbps = full_bitrate_table[b];
+ lower_range = (b);
+ break; /* We found upper range */
+ }
+ }
+
+ /* Determine which range the value specified is closer to */
+ if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) {
+ return lower_range;
+ }
+ return upper_range;
+}
+
+
+
+
+
+/* map frequency to a valid MP3 sample frequency
+ *
+ * Robert Hegemann 2000-07-01
+ */
+int
+map2MP3Frequency(int freq)
+{
+ if (freq <= 8000)
+ return 8000;
+ if (freq <= 11025)
+ return 11025;
+ if (freq <= 12000)
+ return 12000;
+ if (freq <= 16000)
+ return 16000;
+ if (freq <= 22050)
+ return 22050;
+ if (freq <= 24000)
+ return 24000;
+ if (freq <= 32000)
+ return 32000;
+ if (freq <= 44100)
+ return 44100;
+
+ return 48000;
+}
+
+int
+BitrateIndex(int bRate, /* legal rates from 32 to 448 kbps */
+ int version, /* MPEG-1 or MPEG-2/2.5 LSF */
+ int samplerate)
+{ /* convert bitrate in kbps to index */
+ int i;
+ if (samplerate < 16000)
+ version = 2;
+ for (i = 0; i <= 14; i++) {
+ if (bitrate_table[version][i] > 0) {
+ if (bitrate_table[version][i] == bRate) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+/* convert samp freq in Hz to index */
+
+int
+SmpFrqIndex(int sample_freq, int *const version)
+{
+ switch (sample_freq) {
+ case 44100:
+ *version = 1;
+ return 0;
+ case 48000:
+ *version = 1;
+ return 1;
+ case 32000:
+ *version = 1;
+ return 2;
+ case 22050:
+ *version = 0;
+ return 0;
+ case 24000:
+ *version = 0;
+ return 1;
+ case 16000:
+ *version = 0;
+ return 2;
+ case 11025:
+ *version = 0;
+ return 0;
+ case 12000:
+ *version = 0;
+ return 1;
+ case 8000:
+ *version = 0;
+ return 2;
+ default:
+ *version = 0;
+ return -1;
+ }
+}
+
+
+/*****************************************************************************
+*
+* End of bit_stream.c package
+*
+*****************************************************************************/
+
+
+
+
+
+
+
+
+
+
+/* resampling via FIR filter, blackman window */
+inline static FLOAT
+blackman(FLOAT x, FLOAT fcn, int l)
+{
+ /* This algorithm from:
+ SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C
+ S.D. Stearns and R.A. David, Prentice-Hall, 1992
+ */
+ FLOAT bkwn, x2;
+ FLOAT const wcn = (PI * fcn);
+
+ x /= l;
+ if (x < 0)
+ x = 0;
+ if (x > 1)
+ x = 1;
+ x2 = x - .5;
+
+ bkwn = 0.42 - 0.5 * cos(2 * x * PI) + 0.08 * cos(4 * x * PI);
+ if (fabs(x2) < 1e-9)
+ return wcn / PI;
+ else
+ return (bkwn * sin(l * wcn * x2) / (PI * l * x2));
+
+
+}
+
+
+
+
+/* gcd - greatest common divisor */
+/* Joint work of Euclid and M. Hendry */
+
+static int
+gcd(int i, int j)
+{
+ /* assert ( i > 0 && j > 0 ); */
+ return j ? gcd(j, i % j) : i;
+}
+
+
+
+static int
+fill_buffer_resample(lame_internal_flags * gfc,
+ sample_t * outbuf,
+ int desired_len, sample_t const *inbuf, int len, int *num_used, int ch)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ EncStateVar_t *esv = &gfc->sv_enc;
+ double resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out;
+ int BLACKSIZE;
+ FLOAT offset, xvalue;
+ int i, j = 0, k;
+ int filter_l;
+ FLOAT fcn, intratio;
+ FLOAT *inbuf_old;
+ int bpc; /* number of convolution functions to pre-compute */
+ bpc = cfg->samplerate_out / gcd(cfg->samplerate_out, cfg->samplerate_in);
+ if (bpc > BPC)
+ bpc = BPC;
+
+ intratio = (fabs(resample_ratio - floor(.5 + resample_ratio)) < FLT_EPSILON);
+ fcn = 1.00 / resample_ratio;
+ if (fcn > 1.00)
+ fcn = 1.00;
+ filter_l = 31; /* must be odd */
+ filter_l += intratio; /* unless resample_ratio=int, it must be even */
+
+
+ BLACKSIZE = filter_l + 1; /* size of data needed for FIR */
+
+ if (gfc->fill_buffer_resample_init == 0) {
+ esv->inbuf_old[0] = lame_calloc(sample_t, BLACKSIZE);
+ esv->inbuf_old[1] = lame_calloc(sample_t, BLACKSIZE);
+ for (i = 0; i <= 2 * bpc; ++i)
+ esv->blackfilt[i] = lame_calloc(sample_t, BLACKSIZE);
+
+ esv->itime[0] = 0;
+ esv->itime[1] = 0;
+
+ /* precompute blackman filter coefficients */
+ for (j = 0; j <= 2 * bpc; j++) {
+ FLOAT sum = 0.;
+ offset = (j - bpc) / (2. * bpc);
+ for (i = 0; i <= filter_l; i++)
+ sum += esv->blackfilt[j][i] = blackman(i - offset, fcn, filter_l);
+ for (i = 0; i <= filter_l; i++)
+ esv->blackfilt[j][i] /= sum;
+ }
+ gfc->fill_buffer_resample_init = 1;
+ }
+
+ inbuf_old = esv->inbuf_old[ch];
+
+ /* time of j'th element in inbuf = itime + j/ifreq; */
+ /* time of k'th element in outbuf = j/ofreq */
+ for (k = 0; k < desired_len; k++) {
+ double time0 = k * resample_ratio; /* time of k'th output sample */
+ int joff;
+
+ j = floor(time0 - esv->itime[ch]);
+
+ /* check if we need more input data */
+ if ((filter_l + j - filter_l / 2) >= len)
+ break;
+
+ /* blackman filter. by default, window centered at j+.5(filter_l%2) */
+ /* but we want a window centered at time0. */
+ offset = (time0 - esv->itime[ch] - (j + .5 * (filter_l % 2)));
+ assert(fabs(offset) <= .501);
+
+ /* find the closest precomputed window for this offset: */
+ joff = floor((offset * 2 * bpc) + bpc + .5);
+
+ xvalue = 0.;
+ for (i = 0; i <= filter_l; ++i) {
+ int const j2 = i + j - filter_l / 2;
+ sample_t y;
+ assert(j2 < len);
+ assert(j2 + BLACKSIZE >= 0);
+ y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[j2];
+#ifdef PRECOMPUTE
+ xvalue += y * esv->blackfilt[joff][i];
+#else
+ xvalue += y * blackman(i - offset, fcn, filter_l); /* very slow! */
+#endif
+ }
+ outbuf[k] = xvalue;
+ }
+
+
+ /* k = number of samples added to outbuf */
+ /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2] */
+
+ /* how many samples of input data were used: */
+ *num_used = Min(len, filter_l + j - filter_l / 2);
+
+ /* adjust our input time counter. Incriment by the number of samples used,
+ * then normalize so that next output sample is at time 0, next
+ * input buffer is at time itime[ch] */
+ esv->itime[ch] += *num_used - k * resample_ratio;
+
+ /* save the last BLACKSIZE samples into the inbuf_old buffer */
+ if (*num_used >= BLACKSIZE) {
+ for (i = 0; i < BLACKSIZE; i++)
+ inbuf_old[i] = inbuf[*num_used + i - BLACKSIZE];
+ }
+ else {
+ /* shift in *num_used samples into inbuf_old */
+ int const n_shift = BLACKSIZE - *num_used; /* number of samples to shift */
+
+ /* shift n_shift samples by *num_used, to make room for the
+ * num_used new samples */
+ for (i = 0; i < n_shift; ++i)
+ inbuf_old[i] = inbuf_old[i + *num_used];
+
+ /* shift in the *num_used samples */
+ for (j = 0; i < BLACKSIZE; ++i, ++j)
+ inbuf_old[i] = inbuf[j];
+
+ assert(j == *num_used);
+ }
+ return k; /* return the number samples created at the new samplerate */
+}
+
+int
+isResamplingNecessary(SessionConfig_t const* cfg)
+{
+ int const l = cfg->samplerate_out * 0.9995f;
+ int const h = cfg->samplerate_out * 1.0005f;
+ return (cfg->samplerate_in < l) || (h < cfg->samplerate_in) ? 1 : 0;
+}
+
+/* copy in new samples from in_buffer into mfbuf, with resampling
+ if necessary. n_in = number of samples from the input buffer that
+ were used. n_out = number of samples copied into mfbuf */
+
+void
+fill_buffer(lame_internal_flags * gfc,
+ sample_t * const mfbuf[2], sample_t const * const in_buffer[2], int nsamples, int *n_in, int *n_out)
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int mf_size = gfc->sv_enc.mf_size;
+ int framesize = 576 * cfg->mode_gr;
+ int nout, ch = 0;
+ int nch = cfg->channels_out;
+
+ /* copy in new samples into mfbuf, with resampling if necessary */
+ if (isResamplingNecessary(cfg)) {
+ do {
+ nout =
+ fill_buffer_resample(gfc, &mfbuf[ch][mf_size],
+ framesize, in_buffer[ch], nsamples, n_in, ch);
+ } while (++ch < nch);
+ *n_out = nout;
+ }
+ else {
+ nout = Min(framesize, nsamples);
+ do {
+ memcpy(&mfbuf[ch][mf_size], &in_buffer[ch][0], nout * sizeof(mfbuf[0][0]));
+ } while (++ch < nch);
+ *n_out = nout;
+ *n_in = nout;
+ }
+}
+
+
+
+
+
+
+
+/***********************************************************************
+*
+* Message Output
+*
+***********************************************************************/
+
+void
+lame_report_def(const char *format, va_list args)
+{
+ (void) vfprintf(stderr, format, args);
+ fflush(stderr); /* an debug function should flush immediately */
+}
+
+void
+lame_report_fnc(lame_report_function print_f, const char *format, ...)
+{
+ if (print_f) {
+ va_list args;
+ va_start(args, format);
+ print_f(format, args);
+ va_end(args);
+ }
+}
+
+
+void
+lame_debugf(const lame_internal_flags* gfc, const char *format, ...)
+{
+ if (gfc && gfc->report_dbg) {
+ va_list args;
+ va_start(args, format);
+ gfc->report_dbg(format, args);
+ va_end(args);
+ }
+}
+
+
+void
+lame_msgf(const lame_internal_flags* gfc, const char *format, ...)
+{
+ if (gfc && gfc->report_msg) {
+ va_list args;
+ va_start(args, format);
+ gfc->report_msg(format, args);
+ va_end(args);
+ }
+}
+
+
+void
+lame_errorf(const lame_internal_flags* gfc, const char *format, ...)
+{
+ if (gfc && gfc->report_err) {
+ va_list args;
+ va_start(args, format);
+ gfc->report_err(format, args);
+ va_end(args);
+ }
+}
+
+
+
+/***********************************************************************
+ *
+ * routines to detect CPU specific features like 3DNow, MMX, SSE
+ *
+ * donated by Frank Klemm
+ * added Robert Hegemann 2000-10-10
+ *
+ ***********************************************************************/
+
+#ifdef HAVE_NASM
+extern int has_MMX_nasm(void);
+extern int has_3DNow_nasm(void);
+extern int has_SSE_nasm(void);
+extern int has_SSE2_nasm(void);
+#endif
+
+int
+has_MMX(void)
+{
+#ifdef HAVE_NASM
+ return has_MMX_nasm();
+#else
+ return 0; /* don't know, assume not */
+#endif
+}
+
+int
+has_3DNow(void)
+{
+#ifdef HAVE_NASM
+ return has_3DNow_nasm();
+#else
+ return 0; /* don't know, assume not */
+#endif
+}
+
+int
+has_SSE(void)
+{
+#ifdef HAVE_NASM
+ return has_SSE_nasm();
+#else
+#if defined( _M_X64 ) || defined( MIN_ARCH_SSE )
+ return 1;
+#else
+ return 0; /* don't know, assume not */
+#endif
+#endif
+}
+
+int
+has_SSE2(void)
+{
+#ifdef HAVE_NASM
+ return has_SSE2_nasm();
+#else
+#if defined( _M_X64 ) || defined( MIN_ARCH_SSE )
+ return 1;
+#else
+ return 0; /* don't know, assume not */
+#endif
+#endif
+}
+
+void
+disable_FPE(void)
+{
+/* extremly system dependent stuff, move to a lib to make the code readable */
+/*==========================================================================*/
+
+
+
+ /*
+ * Disable floating point exceptions
+ */
+
+
+
+
+#if defined(__FreeBSD__) && !defined(__alpha__)
+ {
+ /* seet floating point mask to the Linux default */
+ fp_except_t mask;
+ mask = fpgetmask();
+ /* if bit is set, we get SIGFPE on that error! */
+ fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));
+ /* DEBUGF("FreeBSD mask is 0x%x\n",mask); */
+ }
+#endif
+
+#if defined(__riscos__) && !defined(ABORTFP)
+ /* Disable FPE's under RISC OS */
+ /* if bit is set, we disable trapping that error! */
+ /* _FPE_IVO : invalid operation */
+ /* _FPE_DVZ : divide by zero */
+ /* _FPE_OFL : overflow */
+ /* _FPE_UFL : underflow */
+ /* _FPE_INX : inexact */
+ DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);
+#endif
+
+ /*
+ * Debugging stuff
+ * The default is to ignore FPE's, unless compiled with -DABORTFP
+ * so add code below to ENABLE FPE's.
+ */
+
+#if defined(ABORTFP)
+#if defined(_MSC_VER)
+ {
+#if 0
+ /* rh 061207
+ the following fix seems to be a workaround for a problem in the
+ parent process calling LAME. It would be better to fix the broken
+ application => code disabled.
+ */
+
+ /* set affinity to a single CPU. Fix for EAC/lame on SMP systems from
+ "Todd Richmond" */
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ SetProcessAffinityMask(GetCurrentProcess(), si.dwActiveProcessorMask);
+#endif
+#include
+ unsigned int mask;
+ mask = _controlfp(0, 0);
+ mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
+ mask = _controlfp(mask, _MCW_EM);
+ }
+#elif defined(__CYGWIN__)
+# define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
+# define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
+
+# define _EM_INEXACT 0x00000020 /* inexact (precision) */
+# define _EM_UNDERFLOW 0x00000010 /* underflow */
+# define _EM_OVERFLOW 0x00000008 /* overflow */
+# define _EM_ZERODIVIDE 0x00000004 /* zero divide */
+# define _EM_INVALID 0x00000001 /* invalid */
+ {
+ unsigned int mask;
+ _FPU_GETCW(mask);
+ /* Set the FPU control word to abort on most FPEs */
+ mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID);
+ _FPU_SETCW(mask);
+ }
+# elif defined(__linux__)
+ {
+
+# include
+# ifndef _FPU_GETCW
+# define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
+# endif
+# ifndef _FPU_SETCW
+# define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
+# endif
+
+ /*
+ * Set the Linux mask to abort on most FPE's
+ * if bit is set, we _mask_ SIGFPE on that error!
+ * mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM );
+ */
+
+ unsigned int mask;
+ _FPU_GETCW(mask);
+ mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);
+ _FPU_SETCW(mask);
+ }
+#endif
+#endif /* ABORTFP */
+}
+
+
+
+
+
+#ifdef USE_FAST_LOG
+/***********************************************************************
+ *
+ * Fast Log Approximation for log2, used to approximate every other log
+ * (log10 and log)
+ * maximum absolute error for log10 is around 10-6
+ * maximum *relative* error can be high when x is almost 1 because error/log10(x) tends toward x/e
+ *
+ * use it if typical RESULT values are > 1e-5 (for example if x>1.00001 or x<0.99999)
+ * or if the relative precision in the domain around 1 is not important (result in 1 is exact and 0)
+ *
+ ***********************************************************************/
+
+
+#define LOG2_SIZE (512)
+#define LOG2_SIZE_L2 (9)
+
+static ieee754_float32_t log_table[LOG2_SIZE + 1];
+
+
+
+void
+init_log_table(void)
+{
+ int j;
+ static int init = 0;
+
+ /* Range for log2(x) over [1,2[ is [0,1[ */
+ assert((1 << LOG2_SIZE_L2) == LOG2_SIZE);
+
+ if (!init) {
+ for (j = 0; j < LOG2_SIZE + 1; j++)
+ log_table[j] = log(1.0f + j / (ieee754_float32_t) LOG2_SIZE) / log(2.0f);
+ }
+ init = 1;
+}
+
+
+
+ieee754_float32_t
+fast_log2(ieee754_float32_t x)
+{
+ ieee754_float32_t log2val, partial;
+ union {
+ ieee754_float32_t f;
+ int i;
+ } fi;
+ int mantisse;
+ fi.f = x;
+ mantisse = fi.i & 0x7fffff;
+ log2val = ((fi.i >> 23) & 0xFF) - 0x7f;
+ partial = (mantisse & ((1 << (23 - LOG2_SIZE_L2)) - 1));
+ partial *= 1.0f / ((1 << (23 - LOG2_SIZE_L2)));
+
+
+ mantisse >>= (23 - LOG2_SIZE_L2);
+
+ /* log2val += log_table[mantisse]; without interpolation the results are not good */
+ log2val += log_table[mantisse] * (1.0f - partial) + log_table[mantisse + 1] * partial;
+
+ return log2val;
+}
+
+#else /* Don't use FAST_LOG */
+
+
+void
+init_log_table(void)
+{
+}
+
+
+#endif
+
+/* end of util.c */
diff --git a/pkg/lame/clame/util.h b/pkg/lame/clame/util.h
new file mode 100644
index 0000000..13f0cd4
--- /dev/null
+++ b/pkg/lame/clame/util.h
@@ -0,0 +1,616 @@
+/*
+ * lame utility library include file
+ *
+ * Copyright (c) 1999 Albert L Faber
+ * Copyright (c) 2008 Robert Hegemann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_UTIL_H
+#define LAME_UTIL_H
+
+#include "l3side.h"
+#include "id3tag.h"
+#include "lame_global_flags.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************
+*
+* Global Definitions
+*
+***********************************************************************/
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#ifdef UINT_MAX
+# define MAX_U_32_NUM UINT_MAX
+#else
+# define MAX_U_32_NUM 0xFFFFFFFF
+#endif
+
+#ifndef PI
+# ifdef M_PI
+# define PI M_PI
+# else
+# define PI 3.14159265358979323846
+# endif
+#endif
+
+
+#ifdef M_LN2
+# define LOG2 M_LN2
+#else
+# define LOG2 0.69314718055994530942
+#endif
+
+#ifdef M_LN10
+# define LOG10 M_LN10
+#else
+# define LOG10 2.30258509299404568402
+#endif
+
+
+#ifdef M_SQRT2
+# define SQRT2 M_SQRT2
+#else
+# define SQRT2 1.41421356237309504880
+#endif
+
+
+#define CRC16_POLYNOMIAL 0x8005
+
+#define MAX_BITS_PER_CHANNEL 4095
+#define MAX_BITS_PER_GRANULE 7680
+
+/* "bit_stream.h" Definitions */
+#define BUFFER_SIZE LAME_MAXMP3BUFFER
+
+#define Min(A, B) ((A) < (B) ? (A) : (B))
+#define Max(A, B) ((A) > (B) ? (A) : (B))
+
+/* log/log10 approximations */
+#ifdef USE_FAST_LOG
+#define FAST_LOG10(x) (fast_log2(x)*(LOG2/LOG10))
+#define FAST_LOG(x) (fast_log2(x)*LOG2)
+#define FAST_LOG10_X(x,y) (fast_log2(x)*(LOG2/LOG10*(y)))
+#define FAST_LOG_X(x,y) (fast_log2(x)*(LOG2*(y)))
+#else
+#define FAST_LOG10(x) log10(x)
+#define FAST_LOG(x) log(x)
+#define FAST_LOG10_X(x,y) (log10(x)*(y))
+#define FAST_LOG_X(x,y) (log(x)*(y))
+#endif
+
+
+ struct replaygain_data;
+#ifndef replaygain_data_defined
+#define replaygain_data_defined
+ typedef struct replaygain_data replaygain_t;
+#endif
+ struct plotting_data;
+#ifndef plotting_data_defined
+#define plotting_data_defined
+ typedef struct plotting_data plotting_data;
+#endif
+
+/***********************************************************************
+*
+* Global Type Definitions
+*
+***********************************************************************/
+
+ typedef struct {
+ void *aligned; /* pointer to ie. 128 bit aligned memory */
+ void *pointer; /* to use with malloc/free */
+ } aligned_pointer_t;
+
+ void calloc_aligned(aligned_pointer_t * ptr, unsigned int size, unsigned int bytes);
+ void free_aligned(aligned_pointer_t * ptr);
+
+
+ /* "bit_stream.h" Type Definitions */
+
+ typedef struct bit_stream_struc {
+ unsigned char *buf; /* bit stream buffer */
+ int buf_size; /* size of buffer (in number of bytes) */
+ int totbit; /* bit counter of bit stream */
+ int buf_byte_idx; /* pointer to top byte in buffer */
+ int buf_bit_idx; /* pointer to top bit of top byte in buffer */
+
+ /* format of file in rd mode (BINARY/ASCII) */
+ } Bit_stream_struc;
+
+
+
+ typedef struct {
+ int sum; /* what we have seen so far */
+ int seen; /* how many frames we have seen in this chunk */
+ int want; /* how many frames we want to collect into one chunk */
+ int pos; /* actual position in our bag */
+ int size; /* size of our bag */
+ int *bag; /* pointer to our bag */
+ unsigned int nVbrNumFrames;
+ unsigned long nBytesWritten;
+ /* VBR tag data */
+ unsigned int TotalFrameSize;
+ } VBR_seek_info_t;
+
+
+ /**
+ * ATH related stuff, if something new ATH related has to be added,
+ * please plugg it here into the ATH_t struct
+ */
+ typedef struct {
+ int use_adjust; /* method for the auto adjustment */
+ FLOAT aa_sensitivity_p; /* factor for tuning the (sample power)
+ point below which adaptive threshold
+ of hearing adjustment occurs */
+ FLOAT adjust_factor; /* lowering based on peak volume, 1 = no lowering */
+ FLOAT adjust_limit; /* limit for dynamic ATH adjust */
+ FLOAT decay; /* determined to lower x dB each second */
+ FLOAT floor; /* lowest ATH value */
+ FLOAT l[SBMAX_l]; /* ATH for sfbs in long blocks */
+ FLOAT s[SBMAX_s]; /* ATH for sfbs in short blocks */
+ FLOAT psfb21[PSFB21]; /* ATH for partitionned sfb21 in long blocks */
+ FLOAT psfb12[PSFB12]; /* ATH for partitionned sfb12 in short blocks */
+ FLOAT cb_l[CBANDS]; /* ATH for long block convolution bands */
+ FLOAT cb_s[CBANDS]; /* ATH for short block convolution bands */
+ FLOAT eql_w[BLKSIZE / 2]; /* equal loudness weights (based on ATH) */
+ } ATH_t;
+
+ /**
+ * PSY Model related stuff
+ */
+
+ typedef struct {
+ FLOAT masking_lower[CBANDS];
+ FLOAT minval[CBANDS];
+ FLOAT rnumlines[CBANDS];
+ FLOAT mld_cb[CBANDS];
+ FLOAT mld[Max(SBMAX_l,SBMAX_s)];
+ FLOAT bo_weight[Max(SBMAX_l,SBMAX_s)]; /* band weight long scalefactor bands, at transition */
+ FLOAT attack_threshold; /* short block tuning */
+ int s3ind[CBANDS][2];
+ int numlines[CBANDS];
+ int bm[Max(SBMAX_l,SBMAX_s)];
+ int bo[Max(SBMAX_l,SBMAX_s)];
+ int npart;
+ int n_sb; /* SBMAX_l or SBMAX_s */
+ FLOAT *s3;
+ } PsyConst_CB2SB_t;
+
+
+ /**
+ * global data constants
+ */
+ typedef struct {
+ FLOAT window[BLKSIZE], window_s[BLKSIZE_s / 2];
+ PsyConst_CB2SB_t l;
+ PsyConst_CB2SB_t s;
+ PsyConst_CB2SB_t l_to_s;
+ FLOAT attack_threshold[4];
+ FLOAT decay;
+ int force_short_block_calc;
+ } PsyConst_t;
+
+
+ typedef struct {
+
+ FLOAT nb_l1[4][CBANDS], nb_l2[4][CBANDS];
+ FLOAT nb_s1[4][CBANDS], nb_s2[4][CBANDS];
+
+ III_psy_xmin thm[4];
+ III_psy_xmin en[4];
+
+ /* loudness calculation (for adaptive threshold of hearing) */
+ FLOAT loudness_sq_save[2]; /* account for granule delay of L3psycho_anal */
+
+ FLOAT tot_ener[4];
+
+ FLOAT last_en_subshort[4][9];
+ int last_attacks[4];
+
+ int blocktype_old[2];
+ } PsyStateVar_t;
+
+
+ typedef struct {
+ /* loudness calculation (for adaptive threshold of hearing) */
+ FLOAT loudness_sq[2][2]; /* loudness^2 approx. per granule and channel */
+ } PsyResult_t;
+
+
+ /* variables used by encoder.c */
+ typedef struct {
+ /* variables for newmdct.c */
+ FLOAT sb_sample[2][2][18][SBLIMIT];
+ FLOAT amp_filter[32];
+
+ /* variables used by util.c */
+ /* BPC = maximum number of filter convolution windows to precompute */
+#define BPC 320
+ double itime[2]; /* float precision seems to be not enough */
+ sample_t *inbuf_old[2];
+ sample_t *blackfilt[2 * BPC + 1];
+
+ FLOAT pefirbuf[19];
+
+ /* used for padding */
+ int frac_SpF;
+ int slot_lag;
+
+ /* variables for bitstream.c */
+ /* mpeg1: buffer=511 bytes smallest frame: 96-38(sideinfo)=58
+ * max number of frames in reservoir: 8
+ * mpeg2: buffer=255 bytes. smallest frame: 24-23bytes=1
+ * with VBR, if you are encoding all silence, it is possible to
+ * have 8kbs/24khz frames with 1byte of data each, which means we need
+ * to buffer up to 255 headers! */
+ /* also, max_header_buf has to be a power of two */
+#define MAX_HEADER_BUF 256
+#define MAX_HEADER_LEN 40 /* max size of header is 38 */
+ struct {
+ int write_timing;
+ int ptr;
+ char buf[MAX_HEADER_LEN];
+ } header[MAX_HEADER_BUF];
+
+ int h_ptr;
+ int w_ptr;
+ int ancillary_flag;
+
+ /* variables for reservoir.c */
+ int ResvSize; /* in bits */
+ int ResvMax; /* in bits */
+
+ int in_buffer_nsamples;
+ sample_t *in_buffer_0;
+ sample_t *in_buffer_1;
+
+#ifndef MFSIZE
+# define MFSIZE ( 3*1152 + ENCDELAY - MDCTDELAY )
+#endif
+ sample_t mfbuf[2][MFSIZE];
+
+ int mf_samples_to_encode;
+ int mf_size;
+
+ } EncStateVar_t;
+
+
+ typedef struct {
+ /* simple statistics */
+ int bitrate_channelmode_hist[16][4 + 1];
+ int bitrate_blocktype_hist[16][4 + 1 + 1]; /*norm/start/short/stop/mixed(short)/sum */
+
+ int bitrate_index;
+ int frame_number; /* number of frames encoded */
+ int padding; /* padding for the current frame? */
+ int mode_ext;
+ int encoder_delay;
+ int encoder_padding; /* number of samples of padding appended to input */
+ } EncResult_t;
+
+
+ /* variables used by quantize.c */
+ typedef struct {
+ /* variables for nspsytune */
+ FLOAT longfact[SBMAX_l];
+ FLOAT shortfact[SBMAX_s];
+ FLOAT masking_lower;
+ FLOAT mask_adjust; /* the dbQ stuff */
+ FLOAT mask_adjust_short; /* the dbQ stuff */
+ int OldValue[2];
+ int CurrentStep[2];
+ int pseudohalf[SFBMAX];
+ int sfb21_extra; /* will be set in lame_init_params */
+ int substep_shaping; /* 0 = no substep
+ 1 = use substep shaping at last step(VBR only)
+ (not implemented yet)
+ 2 = use substep inside loop
+ 3 = use substep inside loop and last step
+ */
+
+
+ char bv_scf[576];
+ } QntStateVar_t;
+
+
+ typedef struct {
+ replaygain_t *rgdata;
+ /* ReplayGain */
+ } RpgStateVar_t;
+
+
+ typedef struct {
+ FLOAT noclipScale; /* user-specified scale factor required for preventing clipping */
+ sample_t PeakSample;
+ int RadioGain;
+ int noclipGainChange; /* gain change required for preventing clipping */
+ } RpgResult_t;
+
+
+ typedef struct {
+ int version; /* 0=MPEG-2/2.5 1=MPEG-1 */
+ int samplerate_index;
+ int sideinfo_len;
+
+ int noise_shaping; /* 0 = none
+ 1 = ISO AAC model
+ 2 = allow scalefac_select=1
+ */
+
+ int subblock_gain; /* 0 = no, 1 = yes */
+ int use_best_huffman; /* 0 = no. 1=outside loop 2=inside loop(slow) */
+ int noise_shaping_amp; /* 0 = ISO model: amplify all distorted bands
+ 1 = amplify within 50% of max (on db scale)
+ 2 = amplify only most distorted band
+ 3 = method 1 and refine with method 2
+ */
+
+ int noise_shaping_stop; /* 0 = stop at over=0, all scalefacs amplified or
+ a scalefac has reached max value
+ 1 = stop when all scalefacs amplified or
+ a scalefac has reached max value
+ 2 = stop when all scalefacs amplified
+ */
+
+
+ int full_outer_loop; /* 0 = stop early after 0 distortion found. 1 = full search */
+
+ int lowpassfreq;
+ int highpassfreq;
+ int samplerate_in; /* input_samp_rate in Hz. default=44.1 kHz */
+ int samplerate_out; /* output_samp_rate. */
+ int channels_in; /* number of channels in the input data stream (PCM or decoded PCM) */
+ int channels_out; /* number of channels in the output data stream (not used for decoding) */
+ int mode_gr; /* granules per frame */
+ int force_ms; /* force M/S mode. requires mode=1 */
+
+ int quant_comp;
+ int quant_comp_short;
+
+ int use_temporal_masking_effect;
+ int use_safe_joint_stereo;
+
+ int preset;
+
+ vbr_mode vbr;
+ int vbr_avg_bitrate_kbps;
+ int vbr_min_bitrate_index; /* min bitrate index */
+ int vbr_max_bitrate_index; /* max bitrate index */
+ int avg_bitrate;
+ int enforce_min_bitrate; /* strictly enforce VBR_min_bitrate normaly, it will be violated for analog silence */
+
+ int findReplayGain; /* find the RG value? default=0 */
+ int findPeakSample;
+ int decode_on_the_fly; /* decode on the fly? default=0 */
+ int analysis;
+ int disable_reservoir;
+ int buffer_constraint; /* enforce ISO spec as much as possible */
+ int free_format;
+ int write_lame_tag; /* add Xing VBR tag? */
+
+ int error_protection; /* use 2 bytes per frame for a CRC checksum. default=0 */
+ int copyright; /* mark as copyright. default=0 */
+ int original; /* mark as original. default=1 */
+ int extension; /* the MP3 'private extension' bit. Meaningless */
+ int emphasis; /* Input PCM is emphased PCM (for
+ instance from one of the rarely
+ emphased CDs), it is STRONGLY not
+ recommended to use this, because
+ psycho does not take it into account,
+ and last but not least many decoders
+ don't care about these bits */
+
+
+ MPEG_mode mode;
+ short_block_t short_blocks;
+
+ float interChRatio;
+ float msfix; /* Naoki's adjustment of Mid/Side maskings */
+ float ATH_offset_db;/* add to ATH this many db */
+ float ATH_offset_factor;/* change ATH by this factor, derived from ATH_offset_db */
+ float ATHcurve; /* change ATH formula 4 shape */
+ int ATHtype;
+ int ATHonly; /* only use ATH */
+ int ATHshort; /* only use ATH for short blocks */
+ int noATH; /* disable ATH */
+
+ float ATHfixpoint;
+
+ float adjust_alto_db;
+ float adjust_bass_db;
+ float adjust_treble_db;
+ float adjust_sfb21_db;
+
+ float compression_ratio; /* sizeof(wav file)/sizeof(mp3 file) */
+
+ /* lowpass and highpass filter control */
+ FLOAT lowpass1, lowpass2; /* normalized frequency bounds of passband */
+ FLOAT highpass1, highpass2; /* normalized frequency bounds of passband */
+
+ /* scale input by this amount before encoding at least not used for MP3 decoding */
+ FLOAT pcm_transform[2][2];
+
+ FLOAT minval;
+ } SessionConfig_t;
+
+
+ struct lame_internal_flags {
+
+ /********************************************************************
+ * internal variables NOT set by calling program, and should not be *
+ * modified by the calling program *
+ ********************************************************************/
+
+ /*
+ * Some remarks to the Class_ID field:
+ * The Class ID is an Identifier for a pointer to this struct.
+ * It is very unlikely that a pointer to lame_global_flags has the same 32 bits
+ * in it's structure (large and other special properties, for instance prime).
+ *
+ * To test that the structure is right and initialized, use:
+ * if ( gfc -> Class_ID == LAME_ID ) ...
+ * Other remark:
+ * If you set a flag to 0 for uninit data and 1 for init data, the right test
+ * should be "if (flag == 1)" and NOT "if (flag)". Unintended modification
+ * of this element will be otherwise misinterpreted as an init.
+ */
+# define LAME_ID 0xFFF88E3B
+ unsigned long class_id;
+
+ int lame_init_params_successful;
+ int lame_encode_frame_init;
+ int iteration_init_init;
+ int fill_buffer_resample_init;
+
+ SessionConfig_t cfg;
+
+ /* variables used by lame.c */
+ Bit_stream_struc bs;
+ III_side_info_t l3_side;
+
+ scalefac_struct scalefac_band;
+
+ PsyStateVar_t sv_psy; /* DATA FROM PSYMODEL.C */
+ PsyResult_t ov_psy;
+ EncStateVar_t sv_enc; /* DATA FROM ENCODER.C */
+ EncResult_t ov_enc;
+ QntStateVar_t sv_qnt; /* DATA FROM QUANTIZE.C */
+
+ RpgStateVar_t sv_rpg;
+ RpgResult_t ov_rpg;
+
+ /* optional ID3 tags, used in id3tag.c */
+ struct id3tag_spec tag_spec;
+ uint16_t nMusicCRC;
+
+ uint16_t _unused;
+
+ /* CPU features */
+ struct {
+ unsigned int MMX:1; /* Pentium MMX, Pentium II...IV, K6, K6-2,
+ K6-III, Athlon */
+ unsigned int AMD_3DNow:1; /* K6-2, K6-III, Athlon */
+ unsigned int SSE:1; /* Pentium III, Pentium 4 */
+ unsigned int SSE2:1; /* Pentium 4, K8 */
+ unsigned int _unused:28;
+ } CPU_features;
+
+
+ VBR_seek_info_t VBR_seek_table; /* used for Xing VBR header */
+
+ ATH_t *ATH; /* all ATH related stuff */
+
+ PsyConst_t *cd_psy;
+
+ /* used by the frame analyzer */
+ plotting_data *pinfo;
+ hip_t hip;
+
+ /* functions to replace with CPU feature optimized versions in takehiro.c */
+ int (*choose_table) (const int *ix, const int *const end, int *const s);
+ void (*fft_fht) (FLOAT *, int);
+ void (*init_xrpow_core) (gr_info * const cod_info, FLOAT xrpow[576], int upper,
+ FLOAT * sum);
+
+ lame_report_function report_msg;
+ lame_report_function report_dbg;
+ lame_report_function report_err;
+ };
+
+#ifndef lame_internal_flags_defined
+#define lame_internal_flags_defined
+ typedef struct lame_internal_flags lame_internal_flags;
+#endif
+
+
+/***********************************************************************
+*
+* Global Function Prototype Declarations
+*
+***********************************************************************/
+ void freegfc(lame_internal_flags * const gfc);
+ void free_id3tag(lame_internal_flags * const gfc);
+ extern int BitrateIndex(int, int, int);
+ extern int FindNearestBitrate(int, int, int);
+ extern int map2MP3Frequency(int freq);
+ extern int SmpFrqIndex(int, int *const);
+ extern int nearestBitrateFullIndex(uint16_t brate);
+ extern FLOAT ATHformula(SessionConfig_t const *cfg, FLOAT freq);
+ extern FLOAT freq2bark(FLOAT freq);
+ void disable_FPE(void);
+
+/* log/log10 approximations */
+ extern void init_log_table(void);
+ extern ieee754_float32_t fast_log2(ieee754_float32_t x);
+
+ int isResamplingNecessary(SessionConfig_t const* cfg);
+
+ void fill_buffer(lame_internal_flags * gfc,
+ sample_t *const mfbuf[2],
+ sample_t const *const in_buffer[2], int nsamples, int *n_in, int *n_out);
+
+/* same as lame_decode1 (look in lame.h), but returns
+ unclipped raw floating-point samples. It is declared
+ here, not in lame.h, because it returns LAME's
+ internal type sample_t. No more than 1152 samples
+ per channel are allowed. */
+ int hip_decode1_unclipped(hip_t hip, unsigned char *mp3buf,
+ size_t len, sample_t pcm_l[], sample_t pcm_r[]);
+
+
+ extern int has_MMX(void);
+ extern int has_3DNow(void);
+ extern int has_SSE(void);
+ extern int has_SSE2(void);
+
+
+
+/***********************************************************************
+*
+* Macros about Message Printing and Exit
+*
+***********************************************************************/
+
+ extern void lame_report_def(const char* format, va_list args);
+ extern void lame_report_fnc(lame_report_function print_f, const char *, ...);
+ extern void lame_errorf(const lame_internal_flags * gfc, const char *, ...);
+ extern void lame_debugf(const lame_internal_flags * gfc, const char *, ...);
+ extern void lame_msgf(const lame_internal_flags * gfc, const char *, ...);
+#define DEBUGF lame_debugf
+#define ERRORF lame_errorf
+#define MSGF lame_msgf
+
+ int is_lame_internal_flags_valid(const lame_internal_flags * gfp);
+
+ extern void hip_set_pinfo(hip_t hip, plotting_data* pinfo);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* LAME_UTIL_H */
diff --git a/pkg/lame/clame/vbrquantize.c b/pkg/lame/clame/vbrquantize.c
new file mode 100644
index 0000000..0f703b7
--- /dev/null
+++ b/pkg/lame/clame/vbrquantize.c
@@ -0,0 +1,1580 @@
+/*
+ * MP3 quantization
+ *
+ * Copyright (c) 1999-2000 Mark Taylor
+ * Copyright (c) 2000-2012 Robert Hegemann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* $Id: vbrquantize.c,v 1.142 2012/02/07 13:36:35 robert Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "vbrquantize.h"
+#include "quantize_pvt.h"
+
+
+
+
+struct algo_s;
+typedef struct algo_s algo_t;
+
+typedef void (*alloc_sf_f) (const algo_t *, const int *, const int *, int);
+typedef uint8_t (*find_sf_f) (const FLOAT *, const FLOAT *, FLOAT, unsigned int, uint8_t);
+
+struct algo_s {
+ alloc_sf_f alloc;
+ find_sf_f find;
+ const FLOAT *xr34orig;
+ lame_internal_flags *gfc;
+ gr_info *cod_info;
+ int mingain_l;
+ int mingain_s[3];
+};
+
+
+
+/* Remarks on optimizing compilers:
+ *
+ * the MSVC compiler may get into aliasing problems when accessing
+ * memory through the fi_union. declaring it volatile does the trick here
+ *
+ * the calc_sfb_noise_* functions are not inlined because the intel compiler
+ * optimized executeables won't work as expected anymore
+ */
+
+#ifdef _MSC_VER
+# if _MSC_VER < 1400
+# define VOLATILE volatile
+# else
+# define VOLATILE
+# endif
+#else
+# define VOLATILE
+#endif
+
+typedef VOLATILE union {
+ float f;
+ int i;
+} fi_union;
+
+
+
+#ifdef TAKEHIRO_IEEE754_HACK
+#define DOUBLEX double
+#else
+#define DOUBLEX FLOAT
+#endif
+
+#define MAGIC_FLOAT_def (65536*(128))
+#define MAGIC_INT_def 0x4b000000
+
+#ifdef TAKEHIRO_IEEE754_HACK
+#else
+/*********************************************************************
+ * XRPOW_FTOI is a macro to convert floats to ints.
+ * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
+ * ROUNDFAC= -0.0946
+ *
+ * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
+ * ROUNDFAC=0.4054
+ *********************************************************************/
+# define QUANTFAC(rx) adj43[rx]
+# define ROUNDFAC_def 0.4054f
+# define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
+#endif
+
+static int const MAGIC_INT = MAGIC_INT_def;
+#ifndef TAKEHIRO_IEEE754_HACK
+static DOUBLEX const ROUNDFAC = ROUNDFAC_def;
+#endif
+static DOUBLEX const MAGIC_FLOAT = MAGIC_FLOAT_def;
+
+
+inline static float
+vec_max_c(const float * xr34, unsigned int bw)
+{
+ float xfsf = 0;
+ unsigned int i = bw >> 2u;
+ unsigned int const remaining = (bw & 0x03u);
+
+ while (i-- > 0) {
+ if (xfsf < xr34[0]) {
+ xfsf = xr34[0];
+ }
+ if (xfsf < xr34[1]) {
+ xfsf = xr34[1];
+ }
+ if (xfsf < xr34[2]) {
+ xfsf = xr34[2];
+ }
+ if (xfsf < xr34[3]) {
+ xfsf = xr34[3];
+ }
+ xr34 += 4;
+ }
+ switch( remaining ) {
+ case 3: if (xfsf < xr34[2]) xfsf = xr34[2];
+ case 2: if (xfsf < xr34[1]) xfsf = xr34[1];
+ case 1: if (xfsf < xr34[0]) xfsf = xr34[0];
+ default: break;
+ }
+ return xfsf;
+}
+
+
+inline static uint8_t
+find_lowest_scalefac(const FLOAT xr34)
+{
+ uint8_t sf_ok = 255;
+ uint8_t sf = 128, delsf = 64;
+ uint8_t i;
+ FLOAT const ixmax_val = IXMAX_VAL;
+ for (i = 0; i < 8; ++i) {
+ FLOAT const xfsf = ipow20[sf] * xr34;
+ if (xfsf <= ixmax_val) {
+ sf_ok = sf;
+ sf -= delsf;
+ }
+ else {
+ sf += delsf;
+ }
+ delsf >>= 1;
+ }
+ return sf_ok;
+}
+
+
+inline static void
+k_34_4(DOUBLEX x[4], int l3[4])
+{
+#ifdef TAKEHIRO_IEEE754_HACK
+ fi_union fi[4];
+
+ assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);
+ x[0] += MAGIC_FLOAT;
+ fi[0].f = x[0];
+ x[1] += MAGIC_FLOAT;
+ fi[1].f = x[1];
+ x[2] += MAGIC_FLOAT;
+ fi[2].f = x[2];
+ x[3] += MAGIC_FLOAT;
+ fi[3].f = x[3];
+ fi[0].f = x[0] + adj43asm[fi[0].i - MAGIC_INT];
+ fi[1].f = x[1] + adj43asm[fi[1].i - MAGIC_INT];
+ fi[2].f = x[2] + adj43asm[fi[2].i - MAGIC_INT];
+ fi[3].f = x[3] + adj43asm[fi[3].i - MAGIC_INT];
+ l3[0] = fi[0].i - MAGIC_INT;
+ l3[1] = fi[1].i - MAGIC_INT;
+ l3[2] = fi[2].i - MAGIC_INT;
+ l3[3] = fi[3].i - MAGIC_INT;
+#else
+ assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);
+ XRPOW_FTOI(x[0], l3[0]);
+ XRPOW_FTOI(x[1], l3[1]);
+ XRPOW_FTOI(x[2], l3[2]);
+ XRPOW_FTOI(x[3], l3[3]);
+ x[0] += QUANTFAC(l3[0]);
+ x[1] += QUANTFAC(l3[1]);
+ x[2] += QUANTFAC(l3[2]);
+ x[3] += QUANTFAC(l3[3]);
+ XRPOW_FTOI(x[0], l3[0]);
+ XRPOW_FTOI(x[1], l3[1]);
+ XRPOW_FTOI(x[2], l3[2]);
+ XRPOW_FTOI(x[3], l3[3]);
+#endif
+}
+
+
+
+
+
+/* do call the calc_sfb_noise_* functions only with sf values
+ * for which holds: sfpow34*xr34 <= IXMAX_VAL
+ */
+
+static FLOAT
+calc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, unsigned int bw, uint8_t sf)
+{
+ DOUBLEX x[4];
+ int l3[4];
+ const FLOAT sfpow = pow20[sf + Q_MAX2]; /*pow(2.0,sf/4.0); */
+ const FLOAT sfpow34 = ipow20[sf]; /*pow(sfpow,-3.0/4.0); */
+
+ FLOAT xfsf = 0;
+ unsigned int i = bw >> 2u;
+ unsigned int const remaining = (bw & 0x03u);
+
+ while (i-- > 0) {
+ x[0] = sfpow34 * xr34[0];
+ x[1] = sfpow34 * xr34[1];
+ x[2] = sfpow34 * xr34[2];
+ x[3] = sfpow34 * xr34[3];
+
+ k_34_4(x, l3);
+
+ x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]];
+ x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]];
+ x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]];
+ x[3] = fabsf(xr[3]) - sfpow * pow43[l3[3]];
+ xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);
+
+ xr += 4;
+ xr34 += 4;
+ }
+ if (remaining) {
+ x[0] = x[1] = x[2] = x[3] = 0;
+ switch( remaining ) {
+ case 3: x[2] = sfpow34 * xr34[2];
+ case 2: x[1] = sfpow34 * xr34[1];
+ case 1: x[0] = sfpow34 * xr34[0];
+ }
+
+ k_34_4(x, l3);
+ x[0] = x[1] = x[2] = x[3] = 0;
+
+ switch( remaining ) {
+ case 3: x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]];
+ case 2: x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]];
+ case 1: x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]];
+ }
+ xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);
+ }
+ return xfsf;
+}
+
+
+
+struct calc_noise_cache {
+ int valid;
+ FLOAT value;
+};
+
+typedef struct calc_noise_cache calc_noise_cache_t;
+
+
+static uint8_t
+tri_calc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw,
+ uint8_t sf, calc_noise_cache_t * did_it)
+{
+ if (did_it[sf].valid == 0) {
+ did_it[sf].valid = 1;
+ did_it[sf].value = calc_sfb_noise_x34(xr, xr34, bw, sf);
+ }
+ if (l3_xmin < did_it[sf].value) {
+ return 1;
+ }
+ if (sf < 255) {
+ uint8_t const sf_x = sf + 1;
+ if (did_it[sf_x].valid == 0) {
+ did_it[sf_x].valid = 1;
+ did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x);
+ }
+ if (l3_xmin < did_it[sf_x].value) {
+ return 1;
+ }
+ }
+ if (sf > 0) {
+ uint8_t const sf_x = sf - 1;
+ if (did_it[sf_x].valid == 0) {
+ did_it[sf_x].valid = 1;
+ did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x);
+ }
+ if (l3_xmin < did_it[sf_x].value) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/**
+ * Robert Hegemann 2001-05-01
+ * calculates quantization step size determined by allowed masking
+ */
+static int
+calc_scalefac(FLOAT l3_xmin, int bw)
+{
+ FLOAT const c = 5.799142446; /* 10 * 10^(2/3) * log10(4/3) */
+ return 210 + (int) (c * log10f(l3_xmin / bw) - .5f);
+}
+
+static uint8_t
+guess_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw, uint8_t sf_min)
+{
+ int const guess = calc_scalefac(l3_xmin, bw);
+ if (guess < sf_min) return sf_min;
+ if (guess >= 255) return 255;
+ (void) xr;
+ (void) xr34;
+ return guess;
+}
+
+
+/* the find_scalefac* routines calculate
+ * a quantization step size which would
+ * introduce as much noise as is allowed.
+ * The larger the step size the more
+ * quantization noise we'll get. The
+ * scalefactors are there to lower the
+ * global step size, allowing limited
+ * differences in quantization step sizes
+ * per band (shaping the noise).
+ */
+
+static uint8_t
+find_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw,
+ uint8_t sf_min)
+{
+ calc_noise_cache_t did_it[256];
+ uint8_t sf = 128, sf_ok = 255, delsf = 128, seen_good_one = 0, i;
+ memset(did_it, 0, sizeof(did_it));
+ for (i = 0; i < 8; ++i) {
+ delsf >>= 1;
+ if (sf <= sf_min) {
+ sf += delsf;
+ }
+ else {
+ uint8_t const bad = tri_calc_sfb_noise_x34(xr, xr34, l3_xmin, bw, sf, did_it);
+ if (bad) { /* distortion. try a smaller scalefactor */
+ sf -= delsf;
+ }
+ else {
+ sf_ok = sf;
+ sf += delsf;
+ seen_good_one = 1;
+ }
+ }
+ }
+ /* returning a scalefac without distortion, if possible
+ */
+ if (seen_good_one > 0) {
+ sf = sf_ok;
+ }
+ if (sf <= sf_min) {
+ sf = sf_min;
+ }
+ return sf;
+}
+
+
+
+/***********************************************************************
+ *
+ * calc_short_block_vbr_sf()
+ * calc_long_block_vbr_sf()
+ *
+ * Mark Taylor 2000-??-??
+ * Robert Hegemann 2000-10-25 made functions of it
+ *
+ ***********************************************************************/
+
+/* a variation for vbr-mtrh */
+static int
+block_sf(algo_t * that, const FLOAT l3_xmin[SFBMAX], int vbrsf[SFBMAX], int vbrsfmin[SFBMAX])
+{
+ FLOAT max_xr34;
+ const FLOAT *const xr = &that->cod_info->xr[0];
+ const FLOAT *const xr34_orig = &that->xr34orig[0];
+ const int *const width = &that->cod_info->width[0];
+ const char *const energy_above_cutoff = &that->cod_info->energy_above_cutoff[0];
+ unsigned int const max_nonzero_coeff = (unsigned int) that->cod_info->max_nonzero_coeff;
+ uint8_t maxsf = 0;
+ int sfb = 0, m_o = -1;
+ unsigned int j = 0, i = 0;
+ int const psymax = that->cod_info->psymax;
+
+ assert(that->cod_info->max_nonzero_coeff >= 0);
+
+ that->mingain_l = 0;
+ that->mingain_s[0] = 0;
+ that->mingain_s[1] = 0;
+ that->mingain_s[2] = 0;
+ while (j <= max_nonzero_coeff) {
+ unsigned int const w = (unsigned int) width[sfb];
+ unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1);
+ unsigned int l = w;
+ uint8_t m1, m2;
+ if (l > m) {
+ l = m;
+ }
+ max_xr34 = vec_max_c(&xr34_orig[j], l);
+
+ m1 = find_lowest_scalefac(max_xr34);
+ vbrsfmin[sfb] = m1;
+ if (that->mingain_l < m1) {
+ that->mingain_l = m1;
+ }
+ if (that->mingain_s[i] < m1) {
+ that->mingain_s[i] = m1;
+ }
+ if (++i > 2) {
+ i = 0;
+ }
+ if (sfb < psymax && w > 2) { /* mpeg2.5 at 8 kHz doesn't use all scalefactors, unused have width 2 */
+ if (energy_above_cutoff[sfb]) {
+ m2 = that->find(&xr[j], &xr34_orig[j], l3_xmin[sfb], l, m1);
+#if 0
+ if (0) {
+ /** Robert Hegemann 2007-09-29:
+ * It seems here is some more potential for speed improvements.
+ * Current find method does 11-18 quantization calculations.
+ * Using a "good guess" may help to reduce this amount.
+ */
+ uint8_t guess = calc_scalefac(l3_xmin[sfb], l);
+ DEBUGF(that->gfc, "sfb=%3d guess=%3d found=%3d diff=%3d\n", sfb, guess, m2,
+ m2 - guess);
+ }
+#endif
+ if (maxsf < m2) {
+ maxsf = m2;
+ }
+ if (m_o < m2 && m2 < 255) {
+ m_o = m2;
+ }
+ }
+ else {
+ m2 = 255;
+ maxsf = 255;
+ }
+ }
+ else {
+ if (maxsf < m1) {
+ maxsf = m1;
+ }
+ m2 = maxsf;
+ }
+ vbrsf[sfb] = m2;
+ ++sfb;
+ j += w;
+ }
+ for (; sfb < SFBMAX; ++sfb) {
+ vbrsf[sfb] = maxsf;
+ vbrsfmin[sfb] = 0;
+ }
+ if (m_o > -1) {
+ maxsf = m_o;
+ for (sfb = 0; sfb < SFBMAX; ++sfb) {
+ if (vbrsf[sfb] == 255) {
+ vbrsf[sfb] = m_o;
+ }
+ }
+ }
+ return maxsf;
+}
+
+
+
+/***********************************************************************
+ *
+ * quantize xr34 based on scalefactors
+ *
+ * block_xr34
+ *
+ * Mark Taylor 2000-??-??
+ * Robert Hegemann 2000-10-20 made functions of them
+ *
+ ***********************************************************************/
+
+static void
+quantize_x34(const algo_t * that)
+{
+ DOUBLEX x[4];
+ const FLOAT *xr34_orig = that->xr34orig;
+ gr_info *const cod_info = that->cod_info;
+ int const ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4;
+ int *l3 = cod_info->l3_enc;
+ unsigned int j = 0, sfb = 0;
+ unsigned int const max_nonzero_coeff = (unsigned int) cod_info->max_nonzero_coeff;
+
+ assert(cod_info->max_nonzero_coeff >= 0);
+ assert(cod_info->max_nonzero_coeff < 576);
+
+ while (j <= max_nonzero_coeff) {
+ int const s =
+ (cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep
+ + cod_info->subblock_gain[cod_info->window[sfb]] * 8;
+ uint8_t const sfac = (uint8_t) (cod_info->global_gain - s);
+ FLOAT const sfpow34 = ipow20[sfac];
+ unsigned int const w = (unsigned int) cod_info->width[sfb];
+ unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1);
+ unsigned int i, remaining;
+
+ assert((cod_info->global_gain - s) >= 0);
+ assert(cod_info->width[sfb] >= 0);
+ j += w;
+ ++sfb;
+
+ i = (w <= m) ? w : m;
+ remaining = (i & 0x03u);
+ i >>= 2u;
+
+ while (i-- > 0) {
+ x[0] = sfpow34 * xr34_orig[0];
+ x[1] = sfpow34 * xr34_orig[1];
+ x[2] = sfpow34 * xr34_orig[2];
+ x[3] = sfpow34 * xr34_orig[3];
+
+ k_34_4(x, l3);
+
+ l3 += 4;
+ xr34_orig += 4;
+ }
+ if (remaining) {
+ int tmp_l3[4];
+ x[0] = x[1] = x[2] = x[3] = 0;
+ switch( remaining ) {
+ case 3: x[2] = sfpow34 * xr34_orig[2];
+ case 2: x[1] = sfpow34 * xr34_orig[1];
+ case 1: x[0] = sfpow34 * xr34_orig[0];
+ }
+
+ k_34_4(x, tmp_l3);
+
+ switch( remaining ) {
+ case 3: l3[2] = tmp_l3[2];
+ case 2: l3[1] = tmp_l3[1];
+ case 1: l3[0] = tmp_l3[0];
+ }
+
+ l3 += remaining;
+ xr34_orig += remaining;
+ }
+ }
+}
+
+
+
+static const uint8_t max_range_short[SBMAX_s * 3] = {
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 0, 0, 0
+};
+
+static const uint8_t max_range_long[SBMAX_l] = {
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0
+};
+
+static const uint8_t max_range_long_lsf_pretab[SBMAX_l] = {
+ 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+
+/*
+ sfb=0..5 scalefac < 16
+ sfb>5 scalefac < 8
+
+ ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+ ol_sf = (cod_info->global_gain-210.0);
+ ol_sf -= 8*cod_info->subblock_gain[i];
+ ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i];
+*/
+
+static void
+set_subblock_gain(gr_info * cod_info, const int mingain_s[3], int sf[])
+{
+ const int maxrange1 = 15, maxrange2 = 7;
+ const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2;
+ int *const sbg = cod_info->subblock_gain;
+ unsigned int const psymax = (unsigned int) cod_info->psymax;
+ unsigned int psydiv = 18;
+ int sbg0, sbg1, sbg2;
+ unsigned int sfb, i;
+ int min_sbg = 7;
+
+ if (psydiv > psymax) {
+ psydiv = psymax;
+ }
+ for (i = 0; i < 3; ++i) {
+ int maxsf1 = 0, maxsf2 = 0, minsf = 1000;
+ /* see if we should use subblock gain */
+ for (sfb = i; sfb < psydiv; sfb += 3) { /* part 1 */
+ int const v = -sf[sfb];
+ if (maxsf1 < v) {
+ maxsf1 = v;
+ }
+ if (minsf > v) {
+ minsf = v;
+ }
+ }
+ for (; sfb < SFBMAX; sfb += 3) { /* part 2 */
+ int const v = -sf[sfb];
+ if (maxsf2 < v) {
+ maxsf2 = v;
+ }
+ if (minsf > v) {
+ minsf = v;
+ }
+ }
+
+ /* boost subblock gain as little as possible so we can
+ * reach maxsf1 with scalefactors
+ * 8*sbg >= maxsf1
+ */
+ {
+ int const m1 = maxsf1 - (maxrange1 << ifqstepShift);
+ int const m2 = maxsf2 - (maxrange2 << ifqstepShift);
+
+ maxsf1 = Max(m1, m2);
+ }
+ if (minsf > 0) {
+ sbg[i] = minsf >> 3;
+ }
+ else {
+ sbg[i] = 0;
+ }
+ if (maxsf1 > 0) {
+ int const m1 = sbg[i];
+ int const m2 = (maxsf1 + 7) >> 3;
+ sbg[i] = Max(m1, m2);
+ }
+ if (sbg[i] > 0 && mingain_s[i] > (cod_info->global_gain - sbg[i] * 8)) {
+ sbg[i] = (cod_info->global_gain - mingain_s[i]) >> 3;
+ }
+ if (sbg[i] > 7) {
+ sbg[i] = 7;
+ }
+ if (min_sbg > sbg[i]) {
+ min_sbg = sbg[i];
+ }
+ }
+ sbg0 = sbg[0] * 8;
+ sbg1 = sbg[1] * 8;
+ sbg2 = sbg[2] * 8;
+ for (sfb = 0; sfb < SFBMAX; sfb += 3) {
+ sf[sfb + 0] += sbg0;
+ sf[sfb + 1] += sbg1;
+ sf[sfb + 2] += sbg2;
+ }
+ if (min_sbg > 0) {
+ for (i = 0; i < 3; ++i) {
+ sbg[i] -= min_sbg;
+ }
+ cod_info->global_gain -= min_sbg * 8;
+ }
+}
+
+
+
+/*
+ ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
+ ol_sf = (cod_info->global_gain-210.0);
+ ol_sf -= ifqstep*scalefac[gr][ch].l[sfb];
+ if (cod_info->preflag && sfb>=11)
+ ol_sf -= ifqstep*pretab[sfb];
+*/
+static void
+set_scalefacs(gr_info * cod_info, const int *vbrsfmin, int sf[], const uint8_t * max_range)
+{
+ const int ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4;
+ const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2;
+ int *const scalefac = cod_info->scalefac;
+ int const sfbmax = cod_info->sfbmax;
+ int sfb;
+ int const *const sbg = cod_info->subblock_gain;
+ int const *const window = cod_info->window;
+ int const preflag = cod_info->preflag;
+
+ if (preflag) {
+ for (sfb = 11; sfb < sfbmax; ++sfb) {
+ sf[sfb] += pretab[sfb] * ifqstep;
+ }
+ }
+ for (sfb = 0; sfb < sfbmax; ++sfb) {
+ int const gain = cod_info->global_gain - (sbg[window[sfb]] * 8)
+ - ((preflag ? pretab[sfb] : 0) * ifqstep);
+
+ if (sf[sfb] < 0) {
+ int const m = gain - vbrsfmin[sfb];
+ /* ifqstep*scalefac >= -sf[sfb], so round UP */
+ scalefac[sfb] = (ifqstep - 1 - sf[sfb]) >> ifqstepShift;
+
+ if (scalefac[sfb] > max_range[sfb]) {
+ scalefac[sfb] = max_range[sfb];
+ }
+ if (scalefac[sfb] > 0 && (scalefac[sfb] << ifqstepShift) > m) {
+ scalefac[sfb] = m >> ifqstepShift;
+ }
+ }
+ else {
+ scalefac[sfb] = 0;
+ }
+ }
+ for (; sfb < SFBMAX; ++sfb) {
+ scalefac[sfb] = 0; /* sfb21 */
+ }
+}
+
+
+#ifndef NDEBUG
+static int
+checkScalefactor(const gr_info * cod_info, const int vbrsfmin[SFBMAX])
+{
+ int const ifqstep = cod_info->scalefac_scale == 0 ? 2 : 4;
+ int sfb;
+ for (sfb = 0; sfb < cod_info->psymax; ++sfb) {
+ const int s =
+ ((cod_info->scalefac[sfb] +
+ (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep) +
+ cod_info->subblock_gain[cod_info->window[sfb]] * 8;
+
+ if ((cod_info->global_gain - s) < vbrsfmin[sfb]) {
+ /*
+ fprintf( stdout, "sf %d\n", sfb );
+ fprintf( stdout, "min %d\n", vbrsfmin[sfb] );
+ fprintf( stdout, "ggain %d\n", cod_info->global_gain );
+ fprintf( stdout, "scalefac %d\n", cod_info->scalefac[sfb] );
+ fprintf( stdout, "pretab %d\n", (cod_info->preflag ? pretab[sfb] : 0) );
+ fprintf( stdout, "scale %d\n", (cod_info->scalefac_scale + 1) );
+ fprintf( stdout, "subgain %d\n", cod_info->subblock_gain[cod_info->window[sfb]] * 8 );
+ fflush( stdout );
+ exit(-1);
+ */
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif
+
+
+/******************************************************************
+ *
+ * short block scalefacs
+ *
+ ******************************************************************/
+
+static void
+short_block_constrain(const algo_t * that, const int vbrsf[SFBMAX],
+ const int vbrsfmin[SFBMAX], int vbrmax)
+{
+ gr_info *const cod_info = that->cod_info;
+ lame_internal_flags const *const gfc = that->gfc;
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int const maxminsfb = that->mingain_l;
+ int mover, maxover0 = 0, maxover1 = 0, delta = 0;
+ int v, v0, v1;
+ int sfb;
+ int const psymax = cod_info->psymax;
+
+ for (sfb = 0; sfb < psymax; ++sfb) {
+ assert(vbrsf[sfb] >= vbrsfmin[sfb]);
+ v = vbrmax - vbrsf[sfb];
+ if (delta < v) {
+ delta = v;
+ }
+ v0 = v - (4 * 14 + 2 * max_range_short[sfb]);
+ v1 = v - (4 * 14 + 4 * max_range_short[sfb]);
+ if (maxover0 < v0) {
+ maxover0 = v0;
+ }
+ if (maxover1 < v1) {
+ maxover1 = v1;
+ }
+ }
+ if (cfg->noise_shaping == 2) {
+ /* allow scalefac_scale=1 */
+ mover = Min(maxover0, maxover1);
+ }
+ else {
+ mover = maxover0;
+ }
+ if (delta > mover) {
+ delta = mover;
+ }
+ vbrmax -= delta;
+ maxover0 -= mover;
+ maxover1 -= mover;
+
+ if (maxover0 == 0) {
+ cod_info->scalefac_scale = 0;
+ }
+ else if (maxover1 == 0) {
+ cod_info->scalefac_scale = 1;
+ }
+ if (vbrmax < maxminsfb) {
+ vbrmax = maxminsfb;
+ }
+ cod_info->global_gain = vbrmax;
+
+ if (cod_info->global_gain < 0) {
+ cod_info->global_gain = 0;
+ }
+ else if (cod_info->global_gain > 255) {
+ cod_info->global_gain = 255;
+ }
+ {
+ int sf_temp[SFBMAX];
+ for (sfb = 0; sfb < SFBMAX; ++sfb) {
+ sf_temp[sfb] = vbrsf[sfb] - vbrmax;
+ }
+ set_subblock_gain(cod_info, &that->mingain_s[0], sf_temp);
+ set_scalefacs(cod_info, vbrsfmin, sf_temp, max_range_short);
+ }
+ assert(checkScalefactor(cod_info, vbrsfmin));
+}
+
+
+
+/******************************************************************
+ *
+ * long block scalefacs
+ *
+ ******************************************************************/
+
+static void
+long_block_constrain(const algo_t * that, const int vbrsf[SFBMAX], const int vbrsfmin[SFBMAX],
+ int vbrmax)
+{
+ gr_info *const cod_info = that->cod_info;
+ lame_internal_flags const *const gfc = that->gfc;
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ uint8_t const *max_rangep;
+ int const maxminsfb = that->mingain_l;
+ int sfb;
+ int maxover0, maxover1, maxover0p, maxover1p, mover, delta = 0;
+ int v, v0, v1, v0p, v1p, vm0p = 1, vm1p = 1;
+ int const psymax = cod_info->psymax;
+
+ max_rangep = cfg->mode_gr == 2 ? max_range_long : max_range_long_lsf_pretab;
+
+ maxover0 = 0;
+ maxover1 = 0;
+ maxover0p = 0; /* pretab */
+ maxover1p = 0; /* pretab */
+
+ for (sfb = 0; sfb < psymax; ++sfb) {
+ assert(vbrsf[sfb] >= vbrsfmin[sfb]);
+ v = vbrmax - vbrsf[sfb];
+ if (delta < v) {
+ delta = v;
+ }
+ v0 = v - 2 * max_range_long[sfb];
+ v1 = v - 4 * max_range_long[sfb];
+ v0p = v - 2 * (max_rangep[sfb] + pretab[sfb]);
+ v1p = v - 4 * (max_rangep[sfb] + pretab[sfb]);
+ if (maxover0 < v0) {
+ maxover0 = v0;
+ }
+ if (maxover1 < v1) {
+ maxover1 = v1;
+ }
+ if (maxover0p < v0p) {
+ maxover0p = v0p;
+ }
+ if (maxover1p < v1p) {
+ maxover1p = v1p;
+ }
+ }
+ if (vm0p == 1) {
+ int gain = vbrmax - maxover0p;
+ if (gain < maxminsfb) {
+ gain = maxminsfb;
+ }
+ for (sfb = 0; sfb < psymax; ++sfb) {
+ int const a = (gain - vbrsfmin[sfb]) - 2 * pretab[sfb];
+ if (a <= 0) {
+ vm0p = 0;
+ vm1p = 0;
+ break;
+ }
+ }
+ }
+ if (vm1p == 1) {
+ int gain = vbrmax - maxover1p;
+ if (gain < maxminsfb) {
+ gain = maxminsfb;
+ }
+ for (sfb = 0; sfb < psymax; ++sfb) {
+ int const b = (gain - vbrsfmin[sfb]) - 4 * pretab[sfb];
+ if (b <= 0) {
+ vm1p = 0;
+ break;
+ }
+ }
+ }
+ if (vm0p == 0) {
+ maxover0p = maxover0;
+ }
+ if (vm1p == 0) {
+ maxover1p = maxover1;
+ }
+ if (cfg->noise_shaping != 2) {
+ maxover1 = maxover0;
+ maxover1p = maxover0p;
+ }
+ mover = Min(maxover0, maxover0p);
+ mover = Min(mover, maxover1);
+ mover = Min(mover, maxover1p);
+
+ if (delta > mover) {
+ delta = mover;
+ }
+ vbrmax -= delta;
+ if (vbrmax < maxminsfb) {
+ vbrmax = maxminsfb;
+ }
+ maxover0 -= mover;
+ maxover0p -= mover;
+ maxover1 -= mover;
+ maxover1p -= mover;
+
+ if (maxover0 == 0) {
+ cod_info->scalefac_scale = 0;
+ cod_info->preflag = 0;
+ max_rangep = max_range_long;
+ }
+ else if (maxover0p == 0) {
+ cod_info->scalefac_scale = 0;
+ cod_info->preflag = 1;
+ }
+ else if (maxover1 == 0) {
+ cod_info->scalefac_scale = 1;
+ cod_info->preflag = 0;
+ max_rangep = max_range_long;
+ }
+ else if (maxover1p == 0) {
+ cod_info->scalefac_scale = 1;
+ cod_info->preflag = 1;
+ }
+ else {
+ assert(0); /* this should not happen */
+ }
+ cod_info->global_gain = vbrmax;
+ if (cod_info->global_gain < 0) {
+ cod_info->global_gain = 0;
+ }
+ else if (cod_info->global_gain > 255) {
+ cod_info->global_gain = 255;
+ }
+ {
+ int sf_temp[SFBMAX];
+ for (sfb = 0; sfb < SFBMAX; ++sfb) {
+ sf_temp[sfb] = vbrsf[sfb] - vbrmax;
+ }
+ set_scalefacs(cod_info, vbrsfmin, sf_temp, max_rangep);
+ }
+ assert(checkScalefactor(cod_info, vbrsfmin));
+}
+
+
+
+static void
+bitcount(const algo_t * that)
+{
+ int rc = scale_bitcount(that->gfc, that->cod_info);
+
+ if (rc == 0) {
+ return;
+ }
+ /* this should not happen due to the way the scalefactors are selected */
+ ERRORF(that->gfc, "INTERNAL ERROR IN VBR NEW CODE (986), please send bug report\n");
+ exit(-1);
+}
+
+
+
+static int
+quantizeAndCountBits(const algo_t * that)
+{
+ quantize_x34(that);
+ that->cod_info->part2_3_length = noquant_count_bits(that->gfc, that->cod_info, 0);
+ return that->cod_info->part2_3_length;
+}
+
+
+
+
+
+static int
+tryGlobalStepsize(const algo_t * that, const int sfwork[SFBMAX],
+ const int vbrsfmin[SFBMAX], int delta)
+{
+ FLOAT const xrpow_max = that->cod_info->xrpow_max;
+ int sftemp[SFBMAX], i, nbits;
+ int gain, vbrmax = 0;
+ for (i = 0; i < SFBMAX; ++i) {
+ gain = sfwork[i] + delta;
+ if (gain < vbrsfmin[i]) {
+ gain = vbrsfmin[i];
+ }
+ if (gain > 255) {
+ gain = 255;
+ }
+ if (vbrmax < gain) {
+ vbrmax = gain;
+ }
+ sftemp[i] = gain;
+ }
+ that->alloc(that, sftemp, vbrsfmin, vbrmax);
+ bitcount(that);
+ nbits = quantizeAndCountBits(that);
+ that->cod_info->xrpow_max = xrpow_max;
+ return nbits;
+}
+
+
+
+static void
+searchGlobalStepsizeMax(const algo_t * that, const int sfwork[SFBMAX],
+ const int vbrsfmin[SFBMAX], int target)
+{
+ gr_info const *const cod_info = that->cod_info;
+ const int gain = cod_info->global_gain;
+ int curr = gain;
+ int gain_ok = 1024;
+ int nbits = LARGE_BITS;
+ int l = gain, r = 512;
+
+ assert(gain >= 0);
+ while (l <= r) {
+ curr = (l + r) >> 1;
+ nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain);
+ if (nbits == 0 || (nbits + cod_info->part2_length) < target) {
+ r = curr - 1;
+ gain_ok = curr;
+ }
+ else {
+ l = curr + 1;
+ if (gain_ok == 1024) {
+ gain_ok = curr;
+ }
+ }
+ }
+ if (gain_ok != curr) {
+ curr = gain_ok;
+ nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain);
+ }
+}
+
+
+
+static int
+sfDepth(const int sfwork[SFBMAX])
+{
+ int m = 0;
+ unsigned int i, j;
+ for (j = SFBMAX, i = 0; j > 0; --j, ++i) {
+ int const di = 255 - sfwork[i];
+ if (m < di) {
+ m = di;
+ }
+ assert(sfwork[i] >= 0);
+ assert(sfwork[i] <= 255);
+ }
+ assert(m >= 0);
+ assert(m <= 255);
+ return m;
+}
+
+
+static void
+cutDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int cut)
+{
+ unsigned int i, j;
+ for (j = SFBMAX, i = 0; j > 0; --j, ++i) {
+ int const x = sfwork[i];
+ sf_out[i] = x < cut ? x : cut;
+ }
+}
+
+
+static int
+flattenDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int dm, int k, int p)
+{
+ unsigned int i, j;
+ int x, sfmax = 0;
+ if (dm > 0) {
+ for (j = SFBMAX, i = 0; j > 0; --j, ++i) {
+ int const di = p - sfwork[i];
+ x = sfwork[i] + (k * di) / dm;
+ if (x < 0) {
+ x = 0;
+ }
+ else {
+ if (x > 255) {
+ x = 255;
+ }
+ }
+ sf_out[i] = x;
+ if (sfmax < x) {
+ sfmax = x;
+ }
+ }
+ }
+ else {
+ for (j = SFBMAX, i = 0; j > 0u; --j, ++i) {
+ x = sfwork[i];
+ sf_out[i] = x;
+ if (sfmax < x) {
+ sfmax = x;
+ }
+ }
+ }
+ return sfmax;
+}
+
+
+static int
+tryThatOne(algo_t const* that, const int sftemp[SFBMAX], const int vbrsfmin[SFBMAX], int vbrmax)
+{
+ FLOAT const xrpow_max = that->cod_info->xrpow_max;
+ int nbits = LARGE_BITS;
+ that->alloc(that, sftemp, vbrsfmin, vbrmax);
+ bitcount(that);
+ nbits = quantizeAndCountBits(that);
+ nbits += that->cod_info->part2_length;
+ that->cod_info->xrpow_max = xrpow_max;
+ return nbits;
+}
+
+
+static void
+outOfBitsStrategy(algo_t const* that, const int sfwork[SFBMAX], const int vbrsfmin[SFBMAX], int target)
+{
+ int wrk[SFBMAX];
+ int const dm = sfDepth(sfwork);
+ int const p = that->cod_info->global_gain;
+ int nbits;
+
+ /* PART 1 */
+ {
+ int bi = dm / 2;
+ int bi_ok = -1;
+ int bu = 0;
+ int bo = dm;
+ for (;;) {
+ int const sfmax = flattenDistribution(sfwork, wrk, dm, bi, p);
+ nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
+ if (nbits <= target) {
+ bi_ok = bi;
+ bo = bi - 1;
+ }
+ else {
+ bu = bi + 1;
+ }
+ if (bu <= bo) {
+ bi = (bu + bo) / 2;
+ }
+ else {
+ break;
+ }
+ }
+ if (bi_ok >= 0) {
+ if (bi != bi_ok) {
+ int const sfmax = flattenDistribution(sfwork, wrk, dm, bi_ok, p);
+ nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
+ }
+ return;
+ }
+ }
+
+ /* PART 2: */
+ {
+ int bi = (255 + p) / 2;
+ int bi_ok = -1;
+ int bu = p;
+ int bo = 255;
+ for (;;) {
+ int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi);
+ nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
+ if (nbits <= target) {
+ bi_ok = bi;
+ bo = bi - 1;
+ }
+ else {
+ bu = bi + 1;
+ }
+ if (bu <= bo) {
+ bi = (bu + bo) / 2;
+ }
+ else {
+ break;
+ }
+ }
+ if (bi_ok >= 0) {
+ if (bi != bi_ok) {
+ int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi_ok);
+ nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
+ }
+ return;
+ }
+ }
+
+ /* fall back to old code, likely to be never called */
+ searchGlobalStepsizeMax(that, wrk, vbrsfmin, target);
+}
+
+
+static int
+reduce_bit_usage(lame_internal_flags * gfc, int gr, int ch
+#if 0
+ , const FLOAT xr34orig[576], const FLOAT l3_xmin[SFBMAX], int maxbits
+#endif
+ )
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
+ /* try some better scalefac storage
+ */
+ best_scalefac_store(gfc, gr, ch, &gfc->l3_side);
+
+ /* best huffman_divide may save some bits too
+ */
+ if (cfg->use_best_huffman == 1)
+ best_huffman_divide(gfc, cod_info);
+ return cod_info->part2_3_length + cod_info->part2_length;
+}
+
+
+
+
+int
+VBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576],
+ const FLOAT l3_xmin[2][2][SFBMAX], const int max_bits[2][2])
+{
+ SessionConfig_t const *const cfg = &gfc->cfg;
+ int sfwork_[2][2][SFBMAX];
+ int vbrsfmin_[2][2][SFBMAX];
+ algo_t that_[2][2];
+ int const ngr = cfg->mode_gr;
+ int const nch = cfg->channels_out;
+ int max_nbits_ch[2][2] = {{0, 0}, {0 ,0}};
+ int max_nbits_gr[2] = {0, 0};
+ int max_nbits_fr = 0;
+ int use_nbits_ch[2][2] = {{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1}
+ ,{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1}};
+ int use_nbits_gr[2] = { MAX_BITS_PER_GRANULE+1, MAX_BITS_PER_GRANULE+1 };
+ int use_nbits_fr = MAX_BITS_PER_GRANULE+MAX_BITS_PER_GRANULE;
+ int gr, ch;
+ int ok, sum_fr;
+
+ /* set up some encoding parameters
+ */
+ for (gr = 0; gr < ngr; ++gr) {
+ max_nbits_gr[gr] = 0;
+ for (ch = 0; ch < nch; ++ch) {
+ max_nbits_ch[gr][ch] = max_bits[gr][ch];
+ use_nbits_ch[gr][ch] = 0;
+ max_nbits_gr[gr] += max_bits[gr][ch];
+ max_nbits_fr += max_bits[gr][ch];
+ that_[gr][ch].find = (cfg->full_outer_loop < 0) ? guess_scalefac_x34 : find_scalefac_x34;
+ that_[gr][ch].gfc = gfc;
+ that_[gr][ch].cod_info = &gfc->l3_side.tt[gr][ch];
+ that_[gr][ch].xr34orig = xr34orig[gr][ch];
+ if (that_[gr][ch].cod_info->block_type == SHORT_TYPE) {
+ that_[gr][ch].alloc = short_block_constrain;
+ }
+ else {
+ that_[gr][ch].alloc = long_block_constrain;
+ }
+ } /* for ch */
+ }
+ /* searches scalefactors
+ */
+ for (gr = 0; gr < ngr; ++gr) {
+ for (ch = 0; ch < nch; ++ch) {
+ if (max_bits[gr][ch] > 0) {
+ algo_t *that = &that_[gr][ch];
+ int *sfwork = sfwork_[gr][ch];
+ int *vbrsfmin = vbrsfmin_[gr][ch];
+ int vbrmax;
+
+ vbrmax = block_sf(that, l3_xmin[gr][ch], sfwork, vbrsfmin);
+ that->alloc(that, sfwork, vbrsfmin, vbrmax);
+ bitcount(that);
+ }
+ else {
+ /* xr contains no energy
+ * l3_enc, our encoding data, will be quantized to zero
+ * continue with next channel
+ */
+ }
+ } /* for ch */
+ }
+ /* encode 'as is'
+ */
+ use_nbits_fr = 0;
+ for (gr = 0; gr < ngr; ++gr) {
+ use_nbits_gr[gr] = 0;
+ for (ch = 0; ch < nch; ++ch) {
+ algo_t const *that = &that_[gr][ch];
+ if (max_bits[gr][ch] > 0) {
+ memset(&that->cod_info->l3_enc[0], 0, sizeof(that->cod_info->l3_enc));
+ (void) quantizeAndCountBits(that);
+ }
+ else {
+ /* xr contains no energy
+ * l3_enc, our encoding data, will be quantized to zero
+ * continue with next channel
+ */
+ }
+ use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch);
+ use_nbits_gr[gr] += use_nbits_ch[gr][ch];
+ } /* for ch */
+ use_nbits_fr += use_nbits_gr[gr];
+ }
+
+ /* check bit constrains
+ */
+ if (use_nbits_fr <= max_nbits_fr) {
+ ok = 1;
+ for (gr = 0; gr < ngr; ++gr) {
+ if (use_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {
+ /* violates the rule that every granule has to use no more
+ * bits than MAX_BITS_PER_GRANULE
+ */
+ ok = 0;
+ }
+ for (ch = 0; ch < nch; ++ch) {
+ if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
+ /* violates the rule that every gr_ch has to use no more
+ * bits than MAX_BITS_PER_CHANNEL
+ *
+ * This isn't explicitly stated in the ISO docs, but the
+ * part2_3_length field has only 12 bits, that makes it
+ * up to a maximum size of 4095 bits!!!
+ */
+ ok = 0;
+ }
+ }
+ }
+ if (ok) {
+ return use_nbits_fr;
+ }
+ }
+
+ /* OK, we are in trouble and have to define how many bits are
+ * to be used for each granule
+ */
+ {
+ ok = 1;
+ sum_fr = 0;
+
+ for (gr = 0; gr < ngr; ++gr) {
+ max_nbits_gr[gr] = 0;
+ for (ch = 0; ch < nch; ++ch) {
+ if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
+ max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL;
+ }
+ else {
+ max_nbits_ch[gr][ch] = use_nbits_ch[gr][ch];
+ }
+ max_nbits_gr[gr] += max_nbits_ch[gr][ch];
+ }
+ if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {
+ float f[2] = {0.0f, 0.0f}, s = 0.0f;
+ for (ch = 0; ch < nch; ++ch) {
+ if (max_nbits_ch[gr][ch] > 0) {
+ f[ch] = sqrt(sqrt(max_nbits_ch[gr][ch]));
+ s += f[ch];
+ }
+ else {
+ f[ch] = 0;
+ }
+ }
+ for (ch = 0; ch < nch; ++ch) {
+ if (s > 0) {
+ max_nbits_ch[gr][ch] = MAX_BITS_PER_GRANULE * f[ch] / s;
+ }
+ else {
+ max_nbits_ch[gr][ch] = 0;
+ }
+ }
+ if (nch > 1) {
+ if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) {
+ max_nbits_ch[gr][1] += max_nbits_ch[gr][0];
+ max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32;
+ max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32;
+ }
+ if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) {
+ max_nbits_ch[gr][0] += max_nbits_ch[gr][1];
+ max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32;
+ max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32;
+ }
+ if (max_nbits_ch[gr][0] > MAX_BITS_PER_CHANNEL) {
+ max_nbits_ch[gr][0] = MAX_BITS_PER_CHANNEL;
+ }
+ if (max_nbits_ch[gr][1] > MAX_BITS_PER_CHANNEL) {
+ max_nbits_ch[gr][1] = MAX_BITS_PER_CHANNEL;
+ }
+ }
+ max_nbits_gr[gr] = 0;
+ for (ch = 0; ch < nch; ++ch) {
+ max_nbits_gr[gr] += max_nbits_ch[gr][ch];
+ }
+ }
+ sum_fr += max_nbits_gr[gr];
+ }
+ if (sum_fr > max_nbits_fr) {
+ {
+ float f[2] = {0.0f, 0.0f}, s = 0.0f;
+ for (gr = 0; gr < ngr; ++gr) {
+ if (max_nbits_gr[gr] > 0) {
+ f[gr] = sqrt(max_nbits_gr[gr]);
+ s += f[gr];
+ }
+ else {
+ f[gr] = 0;
+ }
+ }
+ for (gr = 0; gr < ngr; ++gr) {
+ if (s > 0) {
+ max_nbits_gr[gr] = max_nbits_fr * f[gr] / s;
+ }
+ else {
+ max_nbits_gr[gr] = 0;
+ }
+ }
+ }
+ if (ngr > 1) {
+ if (max_nbits_gr[0] > use_nbits_gr[0] + 125) {
+ max_nbits_gr[1] += max_nbits_gr[0];
+ max_nbits_gr[1] -= use_nbits_gr[0] + 125;
+ max_nbits_gr[0] = use_nbits_gr[0] + 125;
+ }
+ if (max_nbits_gr[1] > use_nbits_gr[1] + 125) {
+ max_nbits_gr[0] += max_nbits_gr[1];
+ max_nbits_gr[0] -= use_nbits_gr[1] + 125;
+ max_nbits_gr[1] = use_nbits_gr[1] + 125;
+ }
+ for (gr = 0; gr < ngr; ++gr) {
+ if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {
+ max_nbits_gr[gr] = MAX_BITS_PER_GRANULE;
+ }
+ }
+ }
+ for (gr = 0; gr < ngr; ++gr) {
+ float f[2] = {0.0f, 0.0f}, s = 0.0f;
+ for (ch = 0; ch < nch; ++ch) {
+ if (max_nbits_ch[gr][ch] > 0) {
+ f[ch] = sqrt(max_nbits_ch[gr][ch]);
+ s += f[ch];
+ }
+ else {
+ f[ch] = 0;
+ }
+ }
+ for (ch = 0; ch < nch; ++ch) {
+ if (s > 0) {
+ max_nbits_ch[gr][ch] = max_nbits_gr[gr] * f[ch] / s;
+ }
+ else {
+ max_nbits_ch[gr][ch] = 0;
+ }
+ }
+ if (nch > 1) {
+ if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) {
+ max_nbits_ch[gr][1] += max_nbits_ch[gr][0];
+ max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32;
+ max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32;
+ }
+ if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) {
+ max_nbits_ch[gr][0] += max_nbits_ch[gr][1];
+ max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32;
+ max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32;
+ }
+ for (ch = 0; ch < nch; ++ch) {
+ if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
+ max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL;
+ }
+ }
+ }
+ }
+ }
+ /* sanity check */
+ sum_fr = 0;
+ for (gr = 0; gr < ngr; ++gr) {
+ int sum_gr = 0;
+ for (ch = 0; ch < nch; ++ch) {
+ sum_gr += max_nbits_ch[gr][ch];
+ if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
+ ok = 0;
+ }
+ }
+ sum_fr += sum_gr;
+ if (sum_gr > MAX_BITS_PER_GRANULE) {
+ ok = 0;
+ }
+ }
+ if (sum_fr > max_nbits_fr) {
+ ok = 0;
+ }
+ if (!ok) {
+ /* we must have done something wrong, fallback to 'on_pe' based constrain */
+ for (gr = 0; gr < ngr; ++gr) {
+ for (ch = 0; ch < nch; ++ch) {
+ max_nbits_ch[gr][ch] = max_bits[gr][ch];
+ }
+ }
+ }
+ }
+
+ /* we already called the 'best_scalefac_store' function, so we need to reset some
+ * variables before we can do it again.
+ */
+ for (ch = 0; ch < nch; ++ch) {
+ gfc->l3_side.scfsi[ch][0] = 0;
+ gfc->l3_side.scfsi[ch][1] = 0;
+ gfc->l3_side.scfsi[ch][2] = 0;
+ gfc->l3_side.scfsi[ch][3] = 0;
+ }
+ for (gr = 0; gr < ngr; ++gr) {
+ for (ch = 0; ch < nch; ++ch) {
+ gfc->l3_side.tt[gr][ch].scalefac_compress = 0;
+ }
+ }
+
+ /* alter our encoded data, until it fits into the target bitrate
+ */
+ use_nbits_fr = 0;
+ for (gr = 0; gr < ngr; ++gr) {
+ use_nbits_gr[gr] = 0;
+ for (ch = 0; ch < nch; ++ch) {
+ algo_t const *that = &that_[gr][ch];
+ use_nbits_ch[gr][ch] = 0;
+ if (max_bits[gr][ch] > 0) {
+ int *sfwork = sfwork_[gr][ch];
+ int const *vbrsfmin = vbrsfmin_[gr][ch];
+ cutDistribution(sfwork, sfwork, that->cod_info->global_gain);
+ outOfBitsStrategy(that, sfwork, vbrsfmin, max_nbits_ch[gr][ch]);
+ }
+ use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch);
+ assert(use_nbits_ch[gr][ch] <= max_nbits_ch[gr][ch]);
+ use_nbits_gr[gr] += use_nbits_ch[gr][ch];
+ } /* for ch */
+ use_nbits_fr += use_nbits_gr[gr];
+ }
+
+ /* check bit constrains, but it should always be ok, iff there are no bugs ;-)
+ */
+ if (use_nbits_fr <= max_nbits_fr) {
+ return use_nbits_fr;
+ }
+
+ ERRORF(gfc, "INTERNAL ERROR IN VBR NEW CODE (1313), please send bug report\n"
+ "maxbits=%d usedbits=%d\n", max_nbits_fr, use_nbits_fr);
+ exit(-1);
+}
diff --git a/pkg/lame/clame/vbrquantize.h b/pkg/lame/clame/vbrquantize.h
new file mode 100644
index 0000000..1c0d18f
--- /dev/null
+++ b/pkg/lame/clame/vbrquantize.h
@@ -0,0 +1,28 @@
+/*
+ * MP3 VBR quantization
+ *
+ * Copyright (c) 1999 Mark Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_VBRQUANTIZE_H
+#define LAME_VBRQUANTIZE_H
+
+int VBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576],
+ const FLOAT l3_xmin[2][2][SFBMAX], const int maxbits[2][2]);
+
+#endif /* LAME_VBRQUANTIZE_H */
diff --git a/pkg/lame/clame/version.c b/pkg/lame/clame/version.c
new file mode 100644
index 0000000..2943406
--- /dev/null
+++ b/pkg/lame/clame/version.c
@@ -0,0 +1,254 @@
+/*
+ * Version numbering for LAME.
+ *
+ * Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*!
+ \file version.c
+ \brief Version numbering for LAME.
+
+ Contains functions which describe the version of LAME.
+
+ \author A.L. Faber
+ \version \$Id: version.c,v 1.34 2011/11/18 09:51:02 robert Exp $
+ \ingroup libmp3lame
+*/
+
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+
+#include "lame.h"
+#include "machine.h"
+
+#include "version.h" /* macros of version numbers */
+
+
+
+
+
+/*! Get the LAME version string. */
+/*!
+ \param void
+ \return a pointer to a string which describes the version of LAME.
+*/
+const char *
+get_lame_version(void)
+{ /* primary to write screen reports */
+ /* Here we can also add informations about compile time configurations */
+
+#if LAME_ALPHA_VERSION
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " "
+ "(alpha " STR(LAME_PATCH_VERSION) ", " __DATE__ " " __TIME__ ")";
+#elif LAME_BETA_VERSION
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " "
+ "(beta " STR(LAME_PATCH_VERSION) ", " __DATE__ ")";
+#elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0)
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) "." STR(LAME_PATCH_VERSION);
+#else
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION);
+#endif
+
+ return str;
+}
+
+
+/*! Get the short LAME version string. */
+/*!
+ It's mainly for inclusion into the MP3 stream.
+
+ \param void
+ \return a pointer to the short version of the LAME version string.
+*/
+const char *
+get_lame_short_version(void)
+{
+ /* adding date and time to version string makes it harder for output
+ validation */
+
+#if LAME_ALPHA_VERSION
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " (alpha " STR(LAME_PATCH_VERSION) ")";
+#elif LAME_BETA_VERSION
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " (beta " STR(LAME_PATCH_VERSION) ")";
+#elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0)
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) "." STR(LAME_PATCH_VERSION);
+#else
+ static /*@observer@ */ const char *const str =
+ STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION);
+#endif
+
+ return str;
+}
+
+/*! Get the _very_ short LAME version string. */
+/*!
+ It's used in the LAME VBR tag only.
+
+ \param void
+ \return a pointer to the short version of the LAME version string.
+*/
+const char *
+get_lame_very_short_version(void)
+{
+ /* adding date and time to version string makes it harder for output
+ validation */
+#if LAME_ALPHA_VERSION
+#define P "a"
+#elif LAME_BETA_VERSION
+#define P "b"
+#elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0)
+#define P "r"
+#else
+#define P " "
+#endif
+ static /*@observer@ */ const char *const str =
+#if (LAME_PATCH_VERSION > 0)
+ "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P STR(LAME_PATCH_VERSION)
+#else
+ "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P
+#endif
+ ;
+ return str;
+}
+
+/*! Get the _very_ short LAME version string. */
+/*!
+ It's used in the LAME VBR tag only, limited to 9 characters max.
+ Due to some 3rd party HW/SW decoders, it has to start with LAME.
+
+ \param void
+ \return a pointer to the short version of the LAME version string.
+ */
+const char*
+get_lame_tag_encoder_short_version(void)
+{
+ static /*@observer@ */ const char *const str =
+ /* FIXME: new scheme / new version counting / drop versioning here ? */
+ "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P
+ ;
+ return str;
+}
+
+/*! Get the version string for GPSYCHO. */
+/*!
+ \param void
+ \return a pointer to a string which describes the version of GPSYCHO.
+*/
+const char *
+get_psy_version(void)
+{
+#if PSY_ALPHA_VERSION > 0
+ static /*@observer@ */ const char *const str =
+ STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION)
+ " (alpha " STR(PSY_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")";
+#elif PSY_BETA_VERSION > 0
+ static /*@observer@ */ const char *const str =
+ STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION)
+ " (beta " STR(PSY_BETA_VERSION) ", " __DATE__ ")";
+#else
+ static /*@observer@ */ const char *const str =
+ STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION);
+#endif
+
+ return str;
+}
+
+
+/*! Get the URL for the LAME website. */
+/*!
+ \param void
+ \return a pointer to a string which is a URL for the LAME website.
+*/
+const char *
+get_lame_url(void)
+{
+ static /*@observer@ */ const char *const str = LAME_URL;
+
+ return str;
+}
+
+
+/*! Get the numerical representation of the version. */
+/*!
+ Writes the numerical representation of the version of LAME and
+ GPSYCHO into lvp.
+
+ \param lvp
+*/
+void
+get_lame_version_numerical(lame_version_t * lvp)
+{
+ static /*@observer@ */ const char *const features = ""; /* obsolete */
+
+ /* generic version */
+ lvp->major = LAME_MAJOR_VERSION;
+ lvp->minor = LAME_MINOR_VERSION;
+#if LAME_ALPHA_VERSION
+ lvp->alpha = LAME_PATCH_VERSION;
+ lvp->beta = 0;
+#elif LAME_BETA_VERSION
+ lvp->alpha = 0;
+ lvp->beta = LAME_PATCH_VERSION;
+#else
+ lvp->alpha = 0;
+ lvp->beta = 0;
+#endif
+
+ /* psy version */
+ lvp->psy_major = PSY_MAJOR_VERSION;
+ lvp->psy_minor = PSY_MINOR_VERSION;
+ lvp->psy_alpha = PSY_ALPHA_VERSION;
+ lvp->psy_beta = PSY_BETA_VERSION;
+
+ /* compile time features */
+ /*@-mustfree@ */
+ lvp->features = features;
+ /*@=mustfree@ */
+}
+
+
+const char *
+get_lame_os_bitness(void)
+{
+ static /*@observer@ */ const char *const strXX = "";
+ static /*@observer@ */ const char *const str32 = "32bits";
+ static /*@observer@ */ const char *const str64 = "64bits";
+
+ switch (sizeof(void *)) {
+ case 4:
+ return str32;
+
+ case 8:
+ return str64;
+
+ default:
+ return strXX;
+ }
+}
+
+/* end of version.c */
diff --git a/pkg/lame/clame/version.h b/pkg/lame/clame/version.h
new file mode 100644
index 0000000..f5fef50
--- /dev/null
+++ b/pkg/lame/clame/version.h
@@ -0,0 +1,68 @@
+/*
+ * Version numbering for LAME.
+ *
+ * Copyright (c) 1999 A.L. Faber
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef LAME_VERSION_H
+#define LAME_VERSION_H
+
+
+/*
+ * To make a string from a token, use the # operator:
+ */
+#ifndef STR
+# define __STR(x) #x
+# define STR(x) __STR(x)
+#endif
+
+# define LAME_URL "http://lame.sf.net"
+
+
+# define LAME_MAJOR_VERSION 3 /* Major version number */
+# define LAME_MINOR_VERSION 100 /* Minor version number */
+# define LAME_TYPE_VERSION 2 /* 0:alpha 1:beta 2:release */
+# define LAME_PATCH_VERSION 0 /* Patch level */
+# define LAME_ALPHA_VERSION (LAME_TYPE_VERSION==0)
+# define LAME_BETA_VERSION (LAME_TYPE_VERSION==1)
+# define LAME_RELEASE_VERSION (LAME_TYPE_VERSION==2)
+
+# define PSY_MAJOR_VERSION 1 /* Major version number */
+# define PSY_MINOR_VERSION 0 /* Minor version number */
+# define PSY_ALPHA_VERSION 0 /* Set number if this is an alpha version, otherwise zero */
+# define PSY_BETA_VERSION 0 /* Set number if this is a beta version, otherwise zero */
+
+#if LAME_ALPHA_VERSION
+#define LAME_PATCH_LEVEL_STRING " alpha " STR(LAME_PATCH_VERSION)
+#endif
+#if LAME_BETA_VERSION
+#define LAME_PATCH_LEVEL_STRING " beta " STR(LAME_PATCH_VERSION)
+#endif
+#if LAME_RELEASE_VERSION
+#if LAME_PATCH_VERSION
+#define LAME_PATCH_LEVEL_STRING " release " STR(LAME_PATCH_VERSION)
+#else
+#define LAME_PATCH_LEVEL_STRING ""
+#endif
+#endif
+
+# define LAME_VERSION_STRING STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) LAME_PATCH_LEVEL_STRING
+
+#endif /* LAME_VERSION_H */
+
+/* End of version.h */
diff --git a/pkg/lame/clame/xmm_quantize_sub.c b/pkg/lame/clame/xmm_quantize_sub.c
new file mode 100644
index 0000000..d68f761
--- /dev/null
+++ b/pkg/lame/clame/xmm_quantize_sub.c
@@ -0,0 +1,240 @@
+/*
+ * MP3 quantization, intrinsics functions
+ *
+ * Copyright (c) 2005-2006 Gabriel Bouvigne
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "lame.h"
+#include "machine.h"
+#include "encoder.h"
+#include "util.h"
+#include "lame_intrin.h"
+
+
+
+#ifdef HAVE_XMMINTRIN_H
+
+#include
+
+typedef union {
+ int32_t _i_32[4]; /* unions are initialized by its first member */
+ float _float[4];
+ __m128 _m128;
+} vecfloat_union;
+
+#define TRI_SIZE (5-1) /* 1024 = 4**5 */
+static const FLOAT costab[TRI_SIZE * 2] = {
+ 9.238795325112867e-01, 3.826834323650898e-01,
+ 9.951847266721969e-01, 9.801714032956060e-02,
+ 9.996988186962042e-01, 2.454122852291229e-02,
+ 9.999811752826011e-01, 6.135884649154475e-03
+};
+
+
+/* make sure functions with SSE instructions maintain their own properly aligned stack */
+#if defined (__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)))
+#define SSE_FUNCTION __attribute__((force_align_arg_pointer))
+#else
+#define SSE_FUNCTION
+#endif
+
+
+SSE_FUNCTION void
+init_xrpow_core_sse(gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum)
+{
+ int i;
+ float tmp_max = 0;
+ float tmp_sum = 0;
+ int upper4 = (upper / 4) * 4;
+ int rest = upper-upper4;
+
+ const vecfloat_union fabs_mask = {{ 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }};
+ const __m128 vec_fabs_mask = _mm_loadu_ps(&fabs_mask._float[0]);
+ vecfloat_union vec_xrpow_max;
+ vecfloat_union vec_sum;
+ vecfloat_union vec_tmp;
+
+ _mm_prefetch((char *) cod_info->xr, _MM_HINT_T0);
+ _mm_prefetch((char *) xrpow, _MM_HINT_T0);
+
+ vec_xrpow_max._m128 = _mm_set_ps1(0);
+ vec_sum._m128 = _mm_set_ps1(0);
+
+ for (i = 0; i < upper4; i += 4) {
+ vec_tmp._m128 = _mm_loadu_ps(&(cod_info->xr[i])); /* load */
+ vec_tmp._m128 = _mm_and_ps(vec_tmp._m128, vec_fabs_mask); /* fabs */
+ vec_sum._m128 = _mm_add_ps(vec_sum._m128, vec_tmp._m128);
+ vec_tmp._m128 = _mm_sqrt_ps(_mm_mul_ps(vec_tmp._m128, _mm_sqrt_ps(vec_tmp._m128)));
+ vec_xrpow_max._m128 = _mm_max_ps(vec_xrpow_max._m128, vec_tmp._m128); /* retrieve max */
+ _mm_storeu_ps(&(xrpow[i]), vec_tmp._m128); /* store into xrpow[] */
+ }
+ vec_tmp._m128 = _mm_set_ps1(0);
+ switch (rest) {
+ case 3: vec_tmp._float[2] = cod_info->xr[upper4+2];
+ case 2: vec_tmp._float[1] = cod_info->xr[upper4+1];
+ case 1: vec_tmp._float[0] = cod_info->xr[upper4+0];
+ vec_tmp._m128 = _mm_and_ps(vec_tmp._m128, vec_fabs_mask); /* fabs */
+ vec_sum._m128 = _mm_add_ps(vec_sum._m128, vec_tmp._m128);
+ vec_tmp._m128 = _mm_sqrt_ps(_mm_mul_ps(vec_tmp._m128, _mm_sqrt_ps(vec_tmp._m128)));
+ vec_xrpow_max._m128 = _mm_max_ps(vec_xrpow_max._m128, vec_tmp._m128); /* retrieve max */
+ switch (rest) {
+ case 3: xrpow[upper4+2] = vec_tmp._float[2];
+ case 2: xrpow[upper4+1] = vec_tmp._float[1];
+ case 1: xrpow[upper4+0] = vec_tmp._float[0];
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ tmp_sum = vec_sum._float[0] + vec_sum._float[1] + vec_sum._float[2] + vec_sum._float[3];
+ {
+ float ma = vec_xrpow_max._float[0] > vec_xrpow_max._float[1]
+ ? vec_xrpow_max._float[0] : vec_xrpow_max._float[1];
+ float mb = vec_xrpow_max._float[2] > vec_xrpow_max._float[3]
+ ? vec_xrpow_max._float[2] : vec_xrpow_max._float[3];
+ tmp_max = ma > mb ? ma : mb;
+ }
+ cod_info->xrpow_max = tmp_max;
+ *sum = tmp_sum;
+}
+
+
+SSE_FUNCTION static void
+store4(__m128 v, float* f0, float* f1, float* f2, float* f3)
+{
+ vecfloat_union r;
+ r._m128 = v;
+ *f0 = r._float[0];
+ *f1 = r._float[1];
+ *f2 = r._float[2];
+ *f3 = r._float[3];
+}
+
+
+SSE_FUNCTION void
+fht_SSE2(FLOAT * fz, int n)
+{
+ const FLOAT *tri = costab;
+ int k4;
+ FLOAT *fi, *gi;
+ FLOAT const *fn;
+
+ n <<= 1; /* to get BLKSIZE, because of 3DNow! ASM routine */
+ fn = fz + n;
+ k4 = 4;
+ do {
+ FLOAT s1, c1;
+ int i, k1, k2, k3, kx;
+ kx = k4 >> 1;
+ k1 = k4;
+ k2 = k4 << 1;
+ k3 = k2 + k1;
+ k4 = k2 << 1;
+ fi = fz;
+ gi = fi + kx;
+ do {
+ FLOAT f0, f1, f2, f3;
+ f1 = fi[0] - fi[k1];
+ f0 = fi[0] + fi[k1];
+ f3 = fi[k2] - fi[k3];
+ f2 = fi[k2] + fi[k3];
+ fi[k2] = f0 - f2;
+ fi[0] = f0 + f2;
+ fi[k3] = f1 - f3;
+ fi[k1] = f1 + f3;
+ f1 = gi[0] - gi[k1];
+ f0 = gi[0] + gi[k1];
+ f3 = SQRT2 * gi[k3];
+ f2 = SQRT2 * gi[k2];
+ gi[k2] = f0 - f2;
+ gi[0] = f0 + f2;
+ gi[k3] = f1 - f3;
+ gi[k1] = f1 + f3;
+ gi += k4;
+ fi += k4;
+ } while (fi < fn);
+ c1 = tri[0];
+ s1 = tri[1];
+ for (i = 1; i < kx; i++) {
+ __m128 v_s2;
+ __m128 v_c2;
+ __m128 v_c1;
+ __m128 v_s1;
+ FLOAT c2, s2, s1_2 = s1+s1;
+ c2 = 1 - s1_2 * s1;
+ s2 = s1_2 * c1;
+ fi = fz + i;
+ gi = fz + k1 - i;
+ v_c1 = _mm_set_ps1(c1);
+ v_s1 = _mm_set_ps1(s1);
+ v_c2 = _mm_set_ps1(c2);
+ v_s2 = _mm_set_ps1(s2);
+ {
+ static const vecfloat_union sign_mask = {{0x80000000,0,0,0}};
+ v_c1 = _mm_xor_ps(sign_mask._m128, v_c1); /* v_c1 := {-c1, +c1, +c1, +c1} */
+ }
+ {
+ static const vecfloat_union sign_mask = {{0,0x80000000,0,0}};
+ v_s1 = _mm_xor_ps(sign_mask._m128, v_s1); /* v_s1 := {+s1, -s1, +s1, +s1} */
+ }
+ {
+ static const vecfloat_union sign_mask = {{0,0,0x80000000,0x80000000}};
+ v_c2 = _mm_xor_ps(sign_mask._m128, v_c2); /* v_c2 := {+c2, +c2, -c2, -c2} */
+ }
+ do {
+ __m128 p, q, r;
+
+ q = _mm_setr_ps(fi[k1], fi[k3], gi[k1], gi[k3]); /* Q := {fi_k1,fi_k3,gi_k1,gi_k3}*/
+ p = _mm_mul_ps(_mm_set_ps1(s2), q); /* P := s2 * Q */
+ q = _mm_mul_ps(v_c2, q); /* Q := c2 * Q */
+ q = _mm_shuffle_ps(q, q, _MM_SHUFFLE(1,0,3,2)); /* Q := {-c2*gi_k1,-c2*gi_k3,c2*fi_k1,c2*fi_k3} */
+ p = _mm_add_ps(p, q);
+
+ r = _mm_setr_ps(gi[0], gi[k2], fi[0], fi[k2]); /* R := {gi_0,gi_k2,fi_0,fi_k2} */
+ q = _mm_sub_ps(r, p); /* Q := {gi_0-p0,gi_k2-p1,fi_0-p2,fi_k2-p3} */
+ r = _mm_add_ps(r, p); /* R := {gi_0+p0,gi_k2+p1,fi_0+p2,fi_k2+p3} */
+ p = _mm_shuffle_ps(q, r, _MM_SHUFFLE(2,0,2,0)); /* P := {q0,q2,r0,r2} */
+ p = _mm_shuffle_ps(p, p, _MM_SHUFFLE(3,1,2,0)); /* P := {q0,r0,q2,r2} */
+ q = _mm_shuffle_ps(q, r, _MM_SHUFFLE(3,1,3,1)); /* Q := {q1,q3,r1,r3} */
+ r = _mm_mul_ps(v_c1, q);
+ q = _mm_mul_ps(v_s1, q);
+ q = _mm_shuffle_ps(q, q, _MM_SHUFFLE(0,1,2,3)); /* Q := {q3,q2,q1,q0} */
+ q = _mm_add_ps(q, r);
+
+ store4(_mm_sub_ps(p, q), &gi[k3], &gi[k2], &fi[k3], &fi[k2]);
+ store4(_mm_add_ps(p, q), &gi[k1], &gi[ 0], &fi[k1], &fi[ 0]);
+
+ gi += k4;
+ fi += k4;
+ } while (fi < fn);
+ c2 = c1;
+ c1 = c2 * tri[0] - s1 * tri[1];
+ s1 = c2 * tri[1] + s1 * tri[0];
+ }
+ tri += 2;
+ } while (k4 < n);
+}
+
+#endif /* HAVE_XMMINTRIN_H */
+
diff --git a/pkg/lame/lame.go b/pkg/lame/lame.go
new file mode 100644
index 0000000..4129ab0
--- /dev/null
+++ b/pkg/lame/lame.go
@@ -0,0 +1,239 @@
+package lame
+
+// http://www.leidinger.net/lame/doxy/html/lame_8h-source.html
+
+/*
+#cgo CFLAGS: -DHAVE_CONFIG_H -I./clame
+#cgo LDFLAGS: -lm
+#include "lame.h"
+*/
+import "C"
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+type Handle *C.struct_lame_global_struct
+
+const (
+ STEREO = C.STEREO
+ JOINT_STEREO = C.JOINT_STEREO
+ DUAL_CHANNEL = C.DUAL_CHANNEL /* LAME doesn't supports this! */
+ MONO = C.MONO
+ NOT_SET = C.NOT_SET
+ MAX_INDICATOR = C.MAX_INDICATOR
+ BIT_DEPTH = 16
+
+ VBR_OFF = C.vbr_off
+ VBR_RH = C.vbr_rh
+ VBR_ABR = C.vbr_abr
+ VBR_MTRH = C.vbr_mtrh
+ VBR_DEFAULT = C.vbr_default
+
+ MAX_FRAME_SIZE = 2880
+)
+
+const (
+ ABR_8 = C.ABR_8
+ ABR_320 = C.ABR_320
+ V9 = C.V9
+ VBR_10 = C.VBR_10
+ V8 = C.V8
+ VBR_20 = C.VBR_20
+ V7 = C.V7
+ VBR_30 = C.VBR_30
+ V6 = C.V6
+ VBR_40 = C.VBR_40
+ V5 = C.V5
+ VBR_50 = C.VBR_50
+ V4 = C.V4
+ VBR_60 = C.VBR_60
+ V3 = C.V3
+ VBR_70 = C.VBR_70
+ V2 = C.V2
+ VBR_80 = C.VBR_80
+ V1 = C.V1
+ VBR_90 = C.VBR_90
+ V0 = C.V0
+ VBR_100 = C.VBR_100
+)
+
+type Encoder struct {
+ handle Handle
+ remainder []byte
+ closed bool
+}
+
+func Init() *Encoder {
+ handle := C.lame_init()
+ encoder := &Encoder{handle, make([]byte, 0), false}
+ runtime.SetFinalizer(encoder, finalize)
+ return encoder
+}
+
+func (e *Encoder) SetVBR(mode C.vbr_mode) {
+ C.lame_set_VBR(e.handle, mode)
+}
+
+func (e *Encoder) SetVBRAverageBitRate(averageBitRate int) {
+ C.lame_set_VBR_mean_bitrate_kbps(e.handle, C.int(averageBitRate))
+}
+
+func (e *Encoder) SetVBRQuality(quality int) {
+ C.lame_set_VBR_q(e.handle, C.int(quality))
+}
+
+func (e *Encoder) SetLowPassFrequency(frequency int) {
+ // Frequency in Hz
+ C.lame_set_lowpassfreq(e.handle, C.int(frequency))
+}
+
+func (e *Encoder) SetNumChannels(num int) {
+ C.lame_set_num_channels(e.handle, C.int(num))
+}
+
+func (e *Encoder) SetInSamplerate(sampleRate int) {
+ C.lame_set_in_samplerate(e.handle, C.int(sampleRate))
+}
+
+func (e *Encoder) SetBitrate(bitRate int) {
+ C.lame_set_brate(e.handle, C.int(bitRate))
+}
+
+func (e *Encoder) SetMode(mode C.MPEG_mode) {
+ C.lame_set_mode(e.handle, mode)
+}
+
+func (e *Encoder) SetQuality(quality int) {
+ C.lame_set_quality(e.handle, C.int(quality))
+}
+
+func (e *Encoder) InitId3Tag() {
+ C.id3tag_init(e.handle)
+}
+
+func (e *Encoder) SetWriteId3tagAutomatic(automaticWriteTag int) {
+ C.lame_set_write_id3tag_automatic(e.handle, C.int(automaticWriteTag))
+}
+
+func (e *Encoder) ID3TagAddV2() {
+ C.id3tag_add_v2(e.handle)
+}
+
+func (e *Encoder) SetbWriteVbrTag(writeVbrTag int) {
+ C.lame_set_bWriteVbrTag(e.handle, C.int(writeVbrTag))
+}
+
+func (e *Encoder) GetLametagFrame() []byte {
+ tagFrame := make([]byte, MAX_FRAME_SIZE)
+ tagFrameLen := C.lame_get_lametag_frame(e.handle, (*C.uchar)(unsafe.Pointer(&tagFrame[0])), C.size_t(len(tagFrame)))
+
+ return tagFrame[0:tagFrameLen]
+}
+
+func (e *Encoder) InitParams() int {
+ retcode := C.lame_init_params(e.handle)
+ return int(retcode)
+}
+
+func (e *Encoder) NumChannels() int {
+ n := C.lame_get_num_channels(e.handle)
+ return int(n)
+}
+
+func (e *Encoder) Bitrate() int {
+ br := C.lame_get_brate(e.handle)
+ return int(br)
+}
+
+func (e *Encoder) Mode() int {
+ m := C.lame_get_mode(e.handle)
+ return int(m)
+}
+
+func (e *Encoder) Quality() int {
+ q := C.lame_get_quality(e.handle)
+ return int(q)
+}
+
+func (e *Encoder) InSamplerate() int {
+ sr := C.lame_get_in_samplerate(e.handle)
+ return int(sr)
+}
+
+func (e *Encoder) Encode(buf []byte) []byte {
+
+ if len(e.remainder) > 0 {
+ buf = append(e.remainder, buf...)
+ }
+
+ if len(buf) == 0 {
+ return make([]byte, 0)
+ }
+
+ blockAlign := BIT_DEPTH / 8 * e.NumChannels()
+
+ remainBytes := len(buf) % blockAlign
+ if remainBytes > 0 {
+ e.remainder = buf[len(buf)-remainBytes : len(buf)]
+ buf = buf[0 : len(buf)-remainBytes]
+ } else {
+ e.remainder = make([]byte, 0)
+ }
+
+ numSamples := len(buf) / blockAlign
+ estimatedSize := int(1.25*float64(numSamples) + 7200)
+ out := make([]byte, estimatedSize)
+
+ cBuf := (*C.short)(unsafe.Pointer(&buf[0]))
+ cOut := (*C.uchar)(unsafe.Pointer(&out[0]))
+
+ var bytesOut C.int
+
+ if e.NumChannels() == 1 {
+ bytesOut = C.int(C.lame_encode_buffer(
+ e.handle,
+ cBuf,
+ nil,
+ C.int(numSamples),
+ cOut,
+ C.int(estimatedSize),
+ ))
+ } else {
+ bytesOut = C.int(C.lame_encode_buffer_interleaved(
+ e.handle,
+ cBuf,
+ C.int(numSamples),
+ cOut,
+ C.int(estimatedSize),
+ ))
+ }
+ return out[0:bytesOut]
+
+}
+
+func (e *Encoder) Flush() []byte {
+ estimatedSize := 7200
+ out := make([]byte, estimatedSize)
+ cOut := (*C.uchar)(unsafe.Pointer(&out[0]))
+ bytesOut := C.int(C.lame_encode_flush(
+ e.handle,
+ cOut,
+ C.int(estimatedSize),
+ ))
+
+ return out[0:bytesOut]
+}
+
+func (e *Encoder) Close() {
+ if e.closed {
+ return
+ }
+ C.lame_close(e.handle)
+ e.closed = true
+}
+
+func finalize(e *Encoder) {
+ e.Close()
+}
diff --git a/pkg/lame/writer.go b/pkg/lame/writer.go
new file mode 100644
index 0000000..6f6b59e
--- /dev/null
+++ b/pkg/lame/writer.go
@@ -0,0 +1,41 @@
+package lame
+
+import (
+ "io"
+)
+
+type LameWriter struct {
+ output io.Writer
+ Encoder *Encoder
+ EncodedChunkSize int
+}
+
+func NewWriter(out io.Writer) *LameWriter {
+ writer := &LameWriter{out, Init(), 0}
+ return writer
+}
+
+func (lw *LameWriter) Write(p []byte) (int, error) {
+ // fmt.Println("lame Write len:", len(p))
+ out := lw.Encoder.Encode(p)
+ lw.EncodedChunkSize = len(out)
+
+ if lw.EncodedChunkSize > 0 {
+ _, err := lw.output.Write(out)
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ return len(p), nil
+}
+
+func (lw *LameWriter) Close() error {
+ out := lw.Encoder.Flush()
+ if len(out) == 0 {
+ return nil
+ }
+ lw.Encoder.Close()
+ _, err := lw.output.Write(out)
+ return err
+}
diff --git a/pkg/lame/z_link_lame_c.c b/pkg/lame/z_link_lame_c.c
new file mode 100644
index 0000000..830401d
--- /dev/null
+++ b/pkg/lame/z_link_lame_c.c
@@ -0,0 +1,21 @@
+#include "./clame/reservoir.c"
+#include "./clame/bitstream.c"
+#include "./clame/newmdct.c"
+#include "./clame/gain_analysis.c"
+#include "./clame/version.c"
+#include "./clame/mpglib_interface.c"
+#include "./clame/xmm_quantize_sub.c"
+#include "./clame/vbrquantize.c"
+#include "./clame/quantize_pvt.c"
+#include "./clame/VbrTag.c"
+#include "./clame/encoder.c"
+#include "./clame/quantize.c"
+#include "./clame/takehiro.c"
+#include "./clame/fft.c"
+#include "./clame/lame.c"
+#include "./clame/set_get.c"
+#include "./clame/id3tag.c"
+#include "./clame/tables.c"
+#include "./clame/util.c"
+#include "./clame/psymodel.c"
+#include "./clame/presets.c"
diff --git a/pkg/silk/csilk/Decoder_Api.c b/pkg/silk/csilk/Decoder_Api.c
new file mode 100644
index 0000000..b67207b
--- /dev/null
+++ b/pkg/silk/csilk/Decoder_Api.c
@@ -0,0 +1,80 @@
+
+#include
+#include
+#include
+#include "SKP_Silk_SDK_API.h"
+
+#define MAX_INPUT_FRAMES 5
+
+typedef struct silk_handle{
+ SKP_SILK_SDK_DecControlStruct dec_ctrl;
+ SKP_uint8 *dec_state;
+} * silk_handle_t;
+
+struct silk_handle *silk_decoder_init(void)
+{
+ silk_handle_t handle = calloc(1, sizeof(struct silk_handle));
+ if (NULL == handle)
+ return NULL;
+
+ handle->dec_ctrl.API_sampleRate = 24000;
+ handle->dec_ctrl.framesPerPacket = 1;
+
+ SKP_int32 dec_size;
+ SKP_Silk_SDK_Get_Decoder_Size(&dec_size);
+
+ handle->dec_state = calloc(1, dec_size);
+ if (NULL == handle->dec_state) {
+ free(handle);
+ return NULL;
+ }
+
+ SKP_Silk_SDK_InitDecoder(handle->dec_state);
+
+ return handle;
+}
+
+void silk_decoder_deinit(struct silk_handle *h) {
+ silk_handle_t handle = (silk_handle_t)h;
+
+ if (handle) {
+ if (handle->dec_state) {
+ free(handle->dec_state);
+ handle->dec_state = NULL;
+ }
+ free(handle);
+ }
+}
+
+int silk_decoder_process(struct silk_handle *h, unsigned char *frame, int frame_size, unsigned char *output_payload, int output_len)
+{
+ silk_handle_t handle = (silk_handle_t)h;
+ SKP_int16 *out_ptr = (SKP_int16 *)output_payload;
+ SKP_int16 len = 0, total_len = 0;
+ SKP_int32 frame_count = 0;
+ do {
+ SKP_Silk_SDK_Decode(handle->dec_state, &handle->dec_ctrl, 0, frame, frame_size, out_ptr, &len);
+ frame_count++;
+ out_ptr += len;
+ total_len += len;
+ if (frame_count > MAX_INPUT_FRAMES) {
+ printf("frame_count > MAX_INPUT_FRAMES frame_count %d, total_len %d\n", frame_count, total_len);
+ out_ptr = (SKP_int16 *)output_payload;
+ total_len = 0;
+ frame_count = 0;
+ }
+ } while (handle->dec_ctrl.moreInternalDecoderFrames);
+
+
+ return total_len * 2;
+}
+
+int silk_decoder_set_sample_rate(struct silk_handle *h, int rate)
+{
+ silk_handle_t handle = (silk_handle_t)h;
+ if (handle) {
+ handle->dec_ctrl.API_sampleRate = rate;
+ }
+
+ return 0;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_A2NLSF.c b/pkg/silk/csilk/SKP_Silk_A2NLSF.c
new file mode 100644
index 0000000..fd6918f
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_A2NLSF.c
@@ -0,0 +1,287 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* Conversion between prediction filter coefficients and NLSFs */
+/* Requires the order to be an even number */
+/* A piecewise linear approximation maps LSF <-> cos(LSF) */
+/* Therefore the result is not accurate NLSFs, but the two */
+/* function are accurate inverses of each other */
+
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Number of binary divisions */
+#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
+#define QPoly 16
+#define MAX_ITERATIONS_A2NLSF_FIX 30
+
+/* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */
+#define OVERSAMPLE_COSINE_TABLE 0
+
+/* Helper function for A2NLSF(..) */
+/* Transforms polynomials from cos(n*f) to cos(f)^n */
+SKP_INLINE void SKP_Silk_A2NLSF_trans_poly(
+ SKP_int32 *p, /* I/O Polynomial */
+ const SKP_int dd /* I Polynomial order (= filter order / 2 ) */
+)
+{
+ SKP_int k, n;
+
+ for( k = 2; k <= dd; k++ ) {
+ for( n = dd; n > k; n-- ) {
+ p[ n - 2 ] -= p[ n ];
+ }
+ p[ k - 2 ] -= SKP_LSHIFT( p[ k ], 1 );
+ }
+}
+#if EMBEDDED_ARM<6
+/* Helper function for A2NLSF(..) */
+/* Polynomial evaluation */
+SKP_INLINE SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */
+ SKP_int32 *p, /* I Polynomial, QPoly */
+ const SKP_int32 x, /* I Evaluation point, Q12 */
+ const SKP_int dd /* I Order */
+)
+{
+ SKP_int n;
+ SKP_int32 x_Q16, y32;
+
+ y32 = p[ dd ]; /* QPoly */
+ x_Q16 = SKP_LSHIFT( x, 4 );
+ for( n = dd - 1; n >= 0; n-- ) {
+ y32 = SKP_SMLAWW( p[ n ], y32, x_Q16 ); /* QPoly */
+ }
+ return y32;
+}
+#else
+SKP_int32 SKP_Silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly */
+ SKP_int32 *p, /* I Polynomial, QPoly */
+ const SKP_int32 x, /* I Evaluation point, Q12 */
+ const SKP_int dd /* I Order */
+);
+#endif
+
+SKP_INLINE void SKP_Silk_A2NLSF_init(
+ const SKP_int32 *a_Q16,
+ SKP_int32 *P,
+ SKP_int32 *Q,
+ const SKP_int dd
+)
+{
+ SKP_int k;
+
+ /* Convert filter coefs to even and odd polynomials */
+ P[dd] = SKP_LSHIFT( 1, QPoly );
+ Q[dd] = SKP_LSHIFT( 1, QPoly );
+ for( k = 0; k < dd; k++ ) {
+#if( QPoly < 16 )
+ P[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
+ Q[ k ] = SKP_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
+#elif( QPoly == 16 )
+ P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; // QPoly
+ Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; // QPoly
+#else
+ P[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
+ Q[ k ] = SKP_LSHIFT( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
+#endif
+ }
+
+ /* Divide out zeros as we have that for even filter orders, */
+ /* z = 1 is always a root in Q, and */
+ /* z = -1 is always a root in P */
+ for( k = dd; k > 0; k-- ) {
+ P[ k - 1 ] -= P[ k ];
+ Q[ k - 1 ] += Q[ k ];
+ }
+
+ /* Transform polynomials from cos(n*f) to cos(f)^n */
+ SKP_Silk_A2NLSF_trans_poly( P, dd );
+ SKP_Silk_A2NLSF_trans_poly( Q, dd );
+}
+
+/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
+/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
+void SKP_Silk_A2NLSF(
+ SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */
+ SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
+ const SKP_int d /* I Filter order (must be even) */
+)
+{
+ SKP_int i, k, m, dd, root_ix, ffrac;
+ SKP_int32 xlo, xhi, xmid;
+ SKP_int32 ylo, yhi, ymid;
+ SKP_int32 nom, den;
+ SKP_int32 P[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
+ SKP_int32 Q[ SKP_Silk_MAX_ORDER_LPC / 2 + 1 ];
+ SKP_int32 *PQ[ 2 ];
+ SKP_int32 *p;
+
+ /* Store pointers to array */
+ PQ[ 0 ] = P;
+ PQ[ 1 ] = Q;
+
+ dd = SKP_RSHIFT( d, 1 );
+
+ SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );
+
+ /* Find roots, alternating between P and Q */
+ p = P; /* Pointer to polynomial */
+
+ xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12
+ ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
+
+ if( ylo < 0 ) {
+ /* Set the first NLSF to zero and move on to the next */
+ NLSF[ 0 ] = 0;
+ p = Q; /* Pointer to polynomial */
+ ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
+ root_ix = 1; /* Index of current root */
+ } else {
+ root_ix = 0; /* Index of current root */
+ }
+ k = 1; /* Loop counter */
+ i = 0; /* Counter for bandwidth expansions applied */
+ while( 1 ) {
+ /* Evaluate polynomial */
+#if OVERSAMPLE_COSINE_TABLE
+ xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] +
+ ( ( SKP_Silk_LSFCosTab_FIX_Q12[ ( k + 1 ) >> 1 ] -
+ SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] ) >> 1 ); /* Q12 */
+#else
+ xhi = SKP_Silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */
+#endif
+ yhi = SKP_Silk_A2NLSF_eval_poly( p, xhi, dd );
+
+ /* Detect zero crossing */
+ if( ( ylo <= 0 && yhi >= 0 ) || ( ylo >= 0 && yhi <= 0 ) ) {
+ /* Binary division */
+#if OVERSAMPLE_COSINE_TABLE
+ ffrac = -128;
+#else
+ ffrac = -256;
+#endif
+ for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {
+ /* Evaluate polynomial */
+ xmid = SKP_RSHIFT_ROUND( xlo + xhi, 1 );
+ ymid = SKP_Silk_A2NLSF_eval_poly( p, xmid, dd );
+
+ /* Detect zero crossing */
+ if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {
+ /* Reduce frequency */
+ xhi = xmid;
+ yhi = ymid;
+ } else {
+ /* Increase frequency */
+ xlo = xmid;
+ ylo = ymid;
+#if OVERSAMPLE_COSINE_TABLE
+ ffrac = SKP_ADD_RSHIFT( ffrac, 64, m );
+#else
+ ffrac = SKP_ADD_RSHIFT( ffrac, 128, m );
+#endif
+ }
+ }
+
+ /* Interpolate */
+ if( SKP_abs( ylo ) < 65536 ) {
+ /* Avoid dividing by zero */
+ den = ylo - yhi;
+ nom = SKP_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + SKP_RSHIFT( den, 1 );
+ if( den != 0 ) {
+ ffrac += SKP_DIV32( nom, den );
+ }
+ } else {
+ /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */
+ ffrac += SKP_DIV32( ylo, SKP_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );
+ }
+#if OVERSAMPLE_COSINE_TABLE
+ NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 7 ) + ffrac, SKP_int16_MAX );
+#else
+ NLSF[ root_ix ] = (SKP_int)SKP_min_32( SKP_LSHIFT( (SKP_int32)k, 8 ) + ffrac, SKP_int16_MAX );
+#endif
+
+ SKP_assert( NLSF[ root_ix ] >= 0 );
+ SKP_assert( NLSF[ root_ix ] <= 32767 );
+
+ root_ix++; /* Next root */
+ if( root_ix >= d ) {
+ /* Found all roots */
+ break;
+ }
+ /* Alternate pointer to polynomial */
+ p = PQ[ root_ix & 1 ];
+
+ /* Evaluate polynomial */
+#if OVERSAMPLE_COSINE_TABLE
+ xlo = SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] +
+ ( ( SKP_Silk_LSFCosTab_FIX_Q12[ k >> 1 ] -
+ SKP_Silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] ) >> 1 ); // Q12
+#else
+ xlo = SKP_Silk_LSFCosTab_FIX_Q12[ k - 1 ]; // Q12
+#endif
+ ylo = SKP_LSHIFT( 1 - ( root_ix & 2 ), 12 );
+ } else {
+ /* Increment loop counter */
+ k++;
+ xlo = xhi;
+ ylo = yhi;
+
+#if OVERSAMPLE_COSINE_TABLE
+ if( k > 2 * LSF_COS_TAB_SZ_FIX ) {
+#else
+ if( k > LSF_COS_TAB_SZ_FIX ) {
+#endif
+ i++;
+ if( i > MAX_ITERATIONS_A2NLSF_FIX ) {
+ /* Set NLSFs to white spectrum and exit */
+ NLSF[ 0 ] = SKP_DIV32_16( 1 << 15, d + 1 );
+ for( k = 1; k < d; k++ ) {
+ NLSF[ k ] = SKP_SMULBB( k + 1, NLSF[ 0 ] );
+ }
+ return;
+ }
+
+ /* Error: Apply progressively more bandwidth expansion and run again */
+ SKP_Silk_bwexpander_32( a_Q16, d, 65536 - SKP_SMULBB( 10 + i, i ) ); // 10_Q16 = 0.00015
+
+ SKP_Silk_A2NLSF_init( a_Q16, P, Q, dd );
+ p = P; /* Pointer to polynomial */
+ xlo = SKP_Silk_LSFCosTab_FIX_Q12[ 0 ]; // Q12
+ ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
+ if( ylo < 0 ) {
+ /* Set the first NLSF to zero and move on to the next */
+ NLSF[ 0 ] = 0;
+ p = Q; /* Pointer to polynomial */
+ ylo = SKP_Silk_A2NLSF_eval_poly( p, xlo, dd );
+ root_ix = 1; /* Index of current root */
+ } else {
+ root_ix = 0; /* Index of current root */
+ }
+ k = 1; /* Reset loop counter */
+ }
+ }
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_AsmHelper.h b/pkg/silk/csilk/SKP_Silk_AsmHelper.h
new file mode 100644
index 0000000..4e8a69b
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_AsmHelper.h
@@ -0,0 +1,180 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/*
+ * SKP_Silk_AsmHelper.h
+ *
+ *
+ *
+ *
+ */
+
+
+#ifndef _SKP_ASM_HELPER_H_
+#define _SKP_ASM_HELPER_H_
+
+// Register bank
+#define _REG 0
+#define _DREG 1
+
+// Arg registers
+#define _R0 0
+#define _R1 1
+#define _R2 2
+#define _R3 3
+#define _R4 4
+// GP registers
+#define _R5 5
+#define _R6 6
+#define _R7 7
+#define _R8 8
+#define _SB 9
+#define _SL 10
+// fp and ip registers
+#define _FP 11
+#define _IP 12
+// lr and sp registers
+#define _SP 13
+#define _LR 14
+
+
+// Extension register bank
+#define _numDReg
+
+#define _Q0 0
+#define _Q1 1
+#define _Q2 2
+#define _Q3 3
+#define _Q4 4
+#define _Q5 5
+#define _Q6 6
+#define _Q7 7
+#define _Q8 8
+#define _Q9 9
+#define _Q10 10
+#define _Q11 11
+#define _Q12 12
+#define _Q13 13
+#define _Q14 14
+#define _Q15 15
+
+#if defined (_WINRT)
+#else
+#if defined (IPHONE)
+#define MACRO .macro
+#define END_MACRO .endmacro
+#define ARG0_in
+#define ARG1_in
+#define ARG2_in
+#define ARG3_in
+#define ARG4_in
+#define ARG5_in
+#define ARG6_in
+#define ARG7_in
+#define ARG0 $0
+#define ARG1 $1
+#define ARG2 $2
+#define ARG3 $3
+#define ARG4 $4
+#define ARG5 $5
+#define ARG6 $6
+#define ARG7 $7
+#define RARG0 r$0
+#define RARG1 r$1
+#define QARG0 q$0
+#define QARG1 q$1
+
+MACRO CHECK_ABS ARG0_in, ARG1_in
+ .abs is_abs, ARG1
+ .if is_abs==1
+ .set ARG0, ARG1
+ .else
+ .set ARG0, -1
+ .endif
+END_MACRO
+
+#else
+#define MACRO .macro
+#define END_MACRO .endm
+#define ARG0_in arg0=-1
+#define ARG1_in arg1=-1
+#define ARG2_in arg2=-1
+#define ARG3_in arg3=-1
+#define ARG4_in arg4=-1
+#define ARG5_in arg5=-1
+#define ARG6_in arg6=-1
+#define ARG7_in arg7=-1
+#define ARG0 \arg0
+#define ARG1 \arg1
+#define ARG2 \arg2
+#define ARG3 \arg3
+#define ARG4 \arg4
+#define ARG5 \arg5
+#define ARG6 \arg6
+#define ARG7 \arg7
+#define RARG0 r\arg0
+#define RARG1 r\arg1
+#define QARG0 q\arg0
+#define QARG1 q\arg1
+
+MACRO CHECK_ABS ARG0_in, ARG1_in
+ .set ARG0, ARG1
+END_MACRO
+#endif
+
+MACRO VARDEF ARG0_in, ARG1_in
+ARG0 .req ARG1
+END_MACRO
+
+MACRO VARDEFD ARG0_in, ARG1_in
+ARG0 .req ARG1
+END_MACRO
+
+MACRO VARDEFQ ARG0_in, ARG1_in
+ARG0 .req ARG1
+END_MACRO
+
+MACRO END
+END_MACRO
+
+MACRO EXTERN ARG0_in
+END_MACRO
+
+MACRO ALIGN ARG0_in
+.align ARG0
+END_MACRO
+
+MACRO DATA
+.data
+END_MACRO
+
+MACRO EXPORT ARG0_in
+.globl ARG0
+END_MACRO
+
+#endif
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_AsmPreproc.h b/pkg/silk/csilk/SKP_Silk_AsmPreproc.h
new file mode 100644
index 0000000..d2e47e8
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_AsmPreproc.h
@@ -0,0 +1,220 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* SKP_Silk_AsmPreProc.h
+ *
+ * General header for all ARM asms uses SigProcLib.
+ * It contains C preprocessor part and asm preprocessor part.
+ * C preprocessor part:
+ * * Interfacing makefile, arch, fpu and neon support
+ * * Interfacing different symbol styles and asm directives.
+ * * Interfacing compiling time standard output
+ * ASM preprocessor part:
+ * * Defining general asm header/footer for stack/return value
+ * * Allocating stack for local variables and nasted function
+ * * Defining simple syntax checking and debugging routines
+ */
+
+
+/*
+ * C preprocessor part
+ */
+#ifndef _SKP_ASM_PREPROC_H_
+#define _SKP_ASM_PREPROC_H_
+
+#include "SKP_Silk_AsmHelper.h"
+
+
+/* Checking compilier __ARMEL__ defines */
+#if !__ARMEL__ && (!defined(NO_ASM)) && (!defined(_WINRT))
+#error Currently SKP_Silk_AsmPreProc only supports little endian.
+// above line can be replaced by
+// #warning __ARMEL__=0
+// #define NOASM
+#endif
+
+/* Defining macro for different user label prefix. */
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__
+#endif
+
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+
+/* Remapping register for iphone. */
+
+#ifdef IPHONE
+# define _fp r7
+# define _r7 r11
+#else
+# define _fp fp
+# define _r7 r7
+#endif
+
+/* Checking compiler __ARM_EABI__ defines */
+
+#if __ARMEB__
+#define NO_ASM //remove asm optimization for ARM big endian.
+#else
+#define ARM_LITTLE_ENDIAN
+#endif
+
+/* Interfacing some asm directives to macros*/
+#define GBL .globl
+
+/* Legacy definition wrapper */
+#ifndef NO_ASM
+#if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__)
+#define EMBEDDED_ARM 4
+#define EMBEDDED_ARMv4
+#elif defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__)
+#define EMBEDDED_ARM 5
+#define EMBEDDED_ARMv5
+#elif defined (__ARM_ARCH_6__) ||defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
+#define EMBEDDED_ARM 6
+#define EMBEDDED_ARMv6
+#elif defined (__ARM_ARCH_7A__) && defined (__ARM_NEON__)
+#define EMBEDDED_ARM 7
+#define EMBEDDED_ARMv6
+#elif defined (__ARM_ARCH_7A__)
+#define EMBEDDED_ARM 6
+#define EMBEDDED_ARMv6
+#else
+#define EMBEDDED_ARM 0
+#endif
+#endif
+
+#ifdef _WINRT
+#define L(a) a
+#define LR(a,d) %##d##a
+
+#define TABLE(L, symbol) symbol
+#else
+#define L(a) a:
+#define LR(a,d) a##d
+#define DCD .long
+#define DCW .short
+#define TABLE(L, symbol) L
+#endif
+
+#ifdef _WINRT
+#define streqh strheq
+#define strneh strhne
+#define strgth strhgt
+#define strlth strhlt
+#define ldrgtsh ldrshgt
+#define ldmgtia ldmiagt
+#define ldmgtdb ldmdbgt
+#define ldrneh ldrhne
+#define ldmltia ldmialt
+#endif
+/*
+ * ASM preprocessor part:
+ */
+
+#ifdef _WINRT
+#else
+// AT&T Format
+#if EMBEDDED_ARM >= 7
+.set _ARCH, 7
+#elif EMBEDDED_ARM >= 6
+.set _ARCH, 6
+#elif EMBEDDED_ARM >= 5 // Should be re-considerred as ARMv5 != ARMv5E
+.set _ARCH, 5
+#elif EMBEDDED_ARM >= 4
+.set _ARCH, 4
+#else
+.set _ARCH, 0
+#endif
+
+#if NEON
+.set _NEON, 1
+#else
+.set _NEON, 0
+#endif
+
+MACRO SKP_TABLE ARG0_in, ARG1_in
+SYM(ARG0):
+END_MACRO
+
+
+
+MACRO SKP_SMLAD ARG0_in, ARG1_in, ARG2_in, ARG3_in
+#if EMBEDDED_ARM>=6
+ smlad ARG0, ARG1, ARG2, ARG3
+#elif EMBEDDED_ARM>=5
+ smlabb ARG0, ARG1, ARG2, ARG3
+ smlatt ARG0, ARG1, ARG2, ARG0
+#else
+ .abort "SKP_SMUAD can't be used for armv4 or lower device.."
+#endif
+END_MACRO
+
+MACRO SKP_SMUAD ARG0_in, ARG1_in, ARG2_in
+#if EMBEDDED_ARM>=6
+ smuad ARG0, ARG1, ARG2
+#elif EMBEDDED_ARM>=5
+ smulbb ARG0, ARG1, ARG2
+ smlatt ARG0, ARG1, ARG2, ARG0
+#else
+ .abort "SKP_SMUAD can't be used for armv4 or lower device.."
+#endif
+END_MACRO
+
+MACRO SKP_SMLALD ARG0_in, ARG1_in, ARG2_in, ARG3_in
+#if EMBEDDED_ARM>=6
+ smlald ARG0, ARG1, ARG2, ARG3
+#elif EMBEDDED_ARM>=5
+ smlalbb ARG0, ARG1, ARG2, ARG3
+ smlaltt ARG0, ARG1, ARG2, ARG3
+#else
+ .abort "SKP_SMLALD can't be used for armv4 or lower device.."
+#endif
+END_MACRO
+
+MACRO SKP_RSHIFT_ROUND ARG0_in, ARG1_in, ARG2_in
+#if EMBEDDED_ARM>=4
+ mov ARG0, ARG1, asr #(ARG2-1)
+ add ARG0, ARG0, #1
+ mov ARG0, ARG0, asr #1
+#else
+ .abort "SKP_RSHIFT_ROUND can't be used for armv3 or lower device.."
+#endif
+END_MACRO
+
+MACRO ADD_SHIFT ARG0_in, ARG1_in, ARG2_in, ARG3_in, ARG4_in
+ add ARG0, ARG1, ARG2, ARG3 ARG4
+END_MACRO
+
+MACRO POST_IR ARG0_in, ARG1_in, ARG2_in, ARG3_in
+ ARG0 ARG1, [ARG2], ARG3
+END_MACRO
+
+#endif
+#endif //_SKP_ASM_PREPROC_H_
diff --git a/pkg/silk/csilk/SKP_Silk_CNG.c b/pkg/silk/csilk/SKP_Silk_CNG.c
new file mode 100644
index 0000000..8d0e6a1
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_CNG.c
@@ -0,0 +1,149 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Generates excitation for CNG LPC synthesis */
+SKP_INLINE void SKP_Silk_CNG_exc(
+ SKP_int16 residual[], /* O CNG residual signal Q0 */
+ SKP_int32 exc_buf_Q10[], /* I Random samples buffer Q10 */
+ SKP_int32 Gain_Q16, /* I Gain to apply */
+ SKP_int length, /* I Length */
+ SKP_int32 *rand_seed /* I/O Seed to random index generator */
+)
+{
+ SKP_int32 seed;
+ SKP_int i, idx, exc_mask;
+
+ exc_mask = CNG_BUF_MASK_MAX;
+ while( exc_mask > length ) {
+ exc_mask = SKP_RSHIFT( exc_mask, 1 );
+ }
+
+ seed = *rand_seed;
+ for( i = 0; i < length; i++ ) {
+ seed = SKP_RAND( seed );
+ idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask );
+ SKP_assert( idx >= 0 );
+ SKP_assert( idx <= CNG_BUF_MASK_MAX );
+ residual[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) );
+ }
+ *rand_seed = seed;
+}
+
+void SKP_Silk_CNG_Reset(
+ SKP_Silk_decoder_state *psDec /* I/O Decoder state */
+)
+{
+ SKP_int i, NLSF_step_Q15, NLSF_acc_Q15;
+
+ NLSF_step_Q15 = SKP_DIV32_16( SKP_int16_MAX, psDec->LPC_order + 1 );
+ NLSF_acc_Q15 = 0;
+ for( i = 0; i < psDec->LPC_order; i++ ) {
+ NLSF_acc_Q15 += NLSF_step_Q15;
+ psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15;
+ }
+ psDec->sCNG.CNG_smth_Gain_Q16 = 0;
+ psDec->sCNG.rand_seed = 3176576;
+}
+
+/* Updates CNG estimate, and applies the CNG when packet was lost */
+void SKP_Silk_CNG(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[], /* I/O Signal */
+ SKP_int length /* I Length of residual */
+)
+{
+ SKP_int i, subfr;
+ SKP_int32 tmp_32, Gain_Q26, max_Gain_Q16;
+ SKP_int16 LPC_buf[ MAX_LPC_ORDER ];
+ SKP_int16 CNG_sig[ MAX_FRAME_LENGTH ];
+ SKP_Silk_CNG_struct *psCNG;
+ psCNG = &psDec->sCNG;
+
+ if( psDec->fs_kHz != psCNG->fs_kHz ) {
+ /* Reset state */
+ SKP_Silk_CNG_Reset( psDec );
+
+ psCNG->fs_kHz = psDec->fs_kHz;
+ }
+ if( psDec->lossCnt == 0 && psDec->vadFlag == NO_VOICE_ACTIVITY ) {
+ /* Update CNG parameters */
+
+ /* Smoothing of LSF's */
+ for( i = 0; i < psDec->LPC_order; i++ ) {
+ psCNG->CNG_smth_NLSF_Q15[ i ] += SKP_SMULWB( psDec->prevNLSF_Q15[ i ] - psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 );
+ }
+ /* Find the subframe with the highest gain */
+ max_Gain_Q16 = 0;
+ subfr = 0;
+ for( i = 0; i < NB_SUBFR; i++ ) {
+ if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) {
+ max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ];
+ subfr = i;
+ }
+ }
+ /* Update CNG excitation buffer with excitation from this subframe */
+ SKP_memmove( &psCNG->CNG_exc_buf_Q10[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q10, ( NB_SUBFR - 1 ) * psDec->subfr_length * sizeof( SKP_int32 ) );
+ SKP_memcpy( psCNG->CNG_exc_buf_Q10, &psDec->exc_Q10[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( SKP_int32 ) );
+
+ /* Smooth gains */
+ for( i = 0; i < NB_SUBFR; i++ ) {
+ psCNG->CNG_smth_Gain_Q16 += SKP_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 );
+ }
+ }
+
+ /* Add CNG when packet is lost and / or when low speech activity */
+ if( psDec->lossCnt ) {//|| psDec->vadFlag == NO_VOICE_ACTIVITY ) {
+
+ /* Generate CNG excitation */
+ SKP_Silk_CNG_exc( CNG_sig, psCNG->CNG_exc_buf_Q10,
+ psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
+
+ /* Convert CNG NLSF to filter representation */
+ SKP_Silk_NLSF2A_stable( LPC_buf, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
+
+ Gain_Q26 = ( SKP_int32 )1 << 26; /* 1.0 */
+
+ /* Generate CNG signal, by synthesis filtering */
+ if( psDec->LPC_order == 16 ) {
+ SKP_Silk_LPC_synthesis_order16( CNG_sig, LPC_buf,
+ Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length );
+ } else {
+ SKP_Silk_LPC_synthesis_filter( CNG_sig, LPC_buf,
+ Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length, psDec->LPC_order );
+ }
+ /* Mix with signal */
+ for( i = 0; i < length; i++ ) {
+ tmp_32 = signal[ i ] + CNG_sig[ i ];
+ signal[ i ] = SKP_SAT16( tmp_32 );
+ }
+ } else {
+ SKP_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( SKP_int32 ) );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_HP_variable_cutoff_FIX.c b/pkg/silk/csilk/SKP_Silk_HP_variable_cutoff_FIX.c
new file mode 100644
index 0000000..6a3b35a
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_HP_variable_cutoff_FIX.c
@@ -0,0 +1,120 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+#if HIGH_PASS_INPUT
+
+#define SKP_RADIANS_CONSTANT_Q19 1482 // 0.45f * 2.0f * 3.14159265359 / 1000
+#define SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 809 // log(80) in Q7
+
+/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
+void SKP_Silk_HP_variable_cutoff_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
+ SKP_int16 *out, /* O high-pass filtered output signal */
+ const SKP_int16 *in /* I input signal */
+)
+{
+ SKP_int quality_Q15;
+ SKP_int32 B_Q28[ 3 ], A_Q28[ 2 ];
+ SKP_int32 Fc_Q19, r_Q28, r_Q22;
+ SKP_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;
+
+ /*********************************************/
+ /* Estimate Low End of Pitch Frequency Range */
+ /*********************************************/
+ if( psEnc->sCmn.prev_sigtype == SIG_TYPE_VOICED ) {
+ /* difference, in log domain */
+ pitch_freq_Hz_Q16 = SKP_DIV32_16( SKP_LSHIFT( SKP_MUL( psEnc->sCmn.fs_kHz, 1000 ), 16 ), psEnc->sCmn.prevLag );
+ pitch_freq_log_Q7 = SKP_Silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); //0x70
+
+ /* adjustment based on quality */
+ quality_Q15 = psEncCtrl->input_quality_bands_Q15[ 0 ];
+ pitch_freq_log_Q7 = SKP_SUB32( pitch_freq_log_Q7, SKP_SMULWB( SKP_SMULWB( SKP_LSHIFT( quality_Q15, 2 ), quality_Q15 ),
+ pitch_freq_log_Q7 - SKP_LOG2_VARIABLE_HP_MIN_FREQ_Q7 ) );
+ pitch_freq_log_Q7 = SKP_ADD32( pitch_freq_log_Q7, SKP_RSHIFT( SKP_FIX_CONST( 0.6, 15 ) - quality_Q15, 9 ) );
+
+ //delta_freq = pitch_freq_log - psEnc->variable_HP_smth1;
+ delta_freq_Q7 = pitch_freq_log_Q7 - SKP_RSHIFT( psEnc->variable_HP_smth1_Q15, 8 );
+ if( delta_freq_Q7 < 0 ) {
+ /* less smoothing for decreasing pitch frequency, to track something close to the minimum */
+ delta_freq_Q7 = SKP_MUL( delta_freq_Q7, 3 );
+ }
+
+ /* limit delta, to reduce impact of outliers */
+ delta_freq_Q7 = SKP_LIMIT_32( delta_freq_Q7, -SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SKP_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) );
+
+ /* update smoother */
+ psEnc->variable_HP_smth1_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth1_Q15,
+ SKP_MUL( SKP_LSHIFT( psEnc->speech_activity_Q8, 1 ), delta_freq_Q7 ), SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) );
+ }
+ /* second smoother */
+ psEnc->variable_HP_smth2_Q15 = SKP_SMLAWB( psEnc->variable_HP_smth2_Q15,
+ psEnc->variable_HP_smth1_Q15 - psEnc->variable_HP_smth2_Q15, SKP_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) );
+
+ /* convert from log scale to Hertz */
+ psEncCtrl->pitch_freq_low_Hz = SKP_Silk_log2lin( SKP_RSHIFT( psEnc->variable_HP_smth2_Q15, 8 ) );
+
+ /* limit frequency range */
+ psEncCtrl->pitch_freq_low_Hz = SKP_LIMIT_32( psEncCtrl->pitch_freq_low_Hz,
+ SKP_FIX_CONST( VARIABLE_HP_MIN_FREQ, 0 ), SKP_FIX_CONST( VARIABLE_HP_MAX_FREQ, 0 ) );
+
+ /********************************/
+ /* Compute Filter Coefficients */
+ /********************************/
+ /* compute cut-off frequency, in radians */
+ //Fc_num = (SKP_float)( 0.45f * 2.0f * 3.14159265359 * psEncCtrl->pitch_freq_low_Hz );
+ //Fc_denom = (SKP_float)( 1e3f * psEnc->sCmn.fs_kHz );
+ SKP_assert( psEncCtrl->pitch_freq_low_Hz <= SKP_int32_MAX / SKP_RADIANS_CONSTANT_Q19 );
+ Fc_Q19 = SKP_DIV32_16( SKP_SMULBB( SKP_RADIANS_CONSTANT_Q19, psEncCtrl->pitch_freq_low_Hz ), psEnc->sCmn.fs_kHz ); // range: 3704 - 27787, 11-15 bits
+ SKP_assert( Fc_Q19 >= 3704 );
+ SKP_assert( Fc_Q19 <= 27787 );
+
+ r_Q28 = SKP_FIX_CONST( 1.0, 28 ) - SKP_MUL( SKP_FIX_CONST( 0.92, 9 ), Fc_Q19 );
+ SKP_assert( r_Q28 >= 255347779 );
+ SKP_assert( r_Q28 <= 266690872 );
+
+ /* b = r * [ 1; -2; 1 ]; */
+ /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */
+ B_Q28[ 0 ] = r_Q28;
+ B_Q28[ 1 ] = SKP_LSHIFT( -r_Q28, 1 );
+ B_Q28[ 2 ] = r_Q28;
+
+ // -r * ( 2 - Fc * Fc );
+ r_Q22 = SKP_RSHIFT( r_Q28, 6 );
+ A_Q28[ 0 ] = SKP_SMULWW( r_Q22, SKP_SMULWW( Fc_Q19, Fc_Q19 ) - SKP_FIX_CONST( 2.0, 22 ) );
+ A_Q28[ 1 ] = SKP_SMULWW( r_Q22, r_Q22 );
+
+ /********************************/
+ /* High-Pass Filter */
+ /********************************/
+ SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psEnc->sCmn.In_HP_State, out, psEnc->sCmn.frame_length );
+}
+
+#endif // HIGH_PASS_INPUT
diff --git a/pkg/silk/csilk/SKP_Silk_Inlines.h b/pkg/silk/csilk/SKP_Silk_Inlines.h
new file mode 100644
index 0000000..6810e86
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_Inlines.h
@@ -0,0 +1,278 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/*! \file SKP_Silk_Inlines.h
+ * \brief SKP_Silk_Inlines.h defines inline signal processing functions.
+ */
+
+#ifndef _SKP_SILK_FIX_INLINES_H_
+#define _SKP_SILK_FIX_INLINES_H_
+
+#include
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* count leading zeros of SKP_int64 */
+SKP_INLINE SKP_int32 SKP_Silk_CLZ64(SKP_int64 in)
+{
+ SKP_int32 in_upper;
+
+ in_upper = (SKP_int32)SKP_RSHIFT64(in, 32);
+ if (in_upper == 0) {
+ /* Search in the lower 32 bits */
+ return 32 + SKP_Silk_CLZ32( (SKP_int32) in );
+ } else {
+ /* Search in the upper 32 bits */
+ return SKP_Silk_CLZ32( in_upper );
+ }
+}
+
+/* get number of leading zeros and fractional part (the bits right after the leading one */
+SKP_INLINE void SKP_Silk_CLZ_FRAC(SKP_int32 in, /* I: input */
+ SKP_int32 *lz, /* O: number of leading zeros */
+ SKP_int32 *frac_Q7) /* O: the 7 bits right after the leading one */
+{
+ SKP_int32 lzeros = SKP_Silk_CLZ32(in);
+
+ * lz = lzeros;
+ * frac_Q7 = SKP_ROR32(in, 24 - lzeros) & 0x7f;
+}
+
+/* Approximation of square root */
+/* Accuracy: < +/- 10% for output values > 15 */
+/* < +/- 2.5% for output values > 120 */
+SKP_INLINE SKP_int32 SKP_Silk_SQRT_APPROX(SKP_int32 x)
+{
+ SKP_int32 y, lz, frac_Q7;
+
+ if( x <= 0 ) {
+ return 0;
+ }
+
+ SKP_Silk_CLZ_FRAC(x, &lz, &frac_Q7);
+
+ if( lz & 1 ) {
+ y = 32768;
+ } else {
+ y = 46214; /* 46214 = sqrt(2) * 32768 */
+ }
+
+ /* get scaling right */
+ y >>= SKP_RSHIFT(lz, 1);
+
+ /* increment using fractional part of input */
+ y = SKP_SMLAWB(y, y, SKP_SMULBB(213, frac_Q7));
+
+ return y;
+}
+
+/* returns the number of left shifts before overflow for a 16 bit number (ITU definition with norm(0)=0) */
+SKP_INLINE SKP_int32 SKP_Silk_norm16(SKP_int16 a) {
+
+ SKP_int32 a32;
+
+ /* if ((a == 0) || (a == SKP_int16_MIN)) return(0); */
+ if ((a << 1) == 0) return(0);
+
+ a32 = a;
+ /* if (a32 < 0) a32 = -a32 - 1; */
+ a32 ^= SKP_RSHIFT(a32, 31);
+
+ return SKP_Silk_CLZ32(a32) - 17;
+}
+
+/* returns the number of left shifts before overflow for a 32 bit number (ITU definition with norm(0)=0) */
+SKP_INLINE SKP_int32 SKP_Silk_norm32(SKP_int32 a) {
+
+ /* if ((a == 0) || (a == SKP_int32_MIN)) return(0); */
+ if ((a << 1) == 0) return(0);
+
+ /* if (a < 0) a = -a - 1; */
+ a ^= SKP_RSHIFT(a, 31);
+
+ return SKP_Silk_CLZ32(a) - 1;
+}
+
+/* Divide two int32 values and return result as int32 in a given Q-domain */
+SKP_INLINE SKP_int32 SKP_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */
+ const SKP_int32 a32, /* I numerator (Q0) */
+ const SKP_int32 b32, /* I denominator (Q0) */
+ const SKP_int Qres /* I Q-domain of result (>= 0) */
+)
+{
+ SKP_int a_headrm, b_headrm, lshift;
+ SKP_int32 b32_inv, a32_nrm, b32_nrm, result;
+
+ SKP_assert( b32 != 0 );
+ SKP_assert( Qres >= 0 );
+
+ /* Compute number of bits head room and normalize inputs */
+ a_headrm = SKP_Silk_CLZ32( SKP_abs(a32) ) - 1;
+ a32_nrm = SKP_LSHIFT(a32, a_headrm); /* Q: a_headrm */
+ b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
+ b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */
+
+ /* Inverse of b32, with 14 bits of precision */
+ b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
+
+ /* First approximation */
+ result = SKP_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
+
+ /* Compute residual by subtracting product of denominator and first approximation */
+ a32_nrm -= SKP_LSHIFT_ovflw( SKP_SMMUL(b32_nrm, result), 3 ); /* Q: a_headrm */
+
+ /* Refinement */
+ result = SKP_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
+
+ /* Convert to Qres domain */
+ lshift = 29 + a_headrm - b_headrm - Qres;
+ if( lshift <= 0 ) {
+ return SKP_LSHIFT_SAT32(result, -lshift);
+ } else {
+ if( lshift < 32){
+ return SKP_RSHIFT(result, lshift);
+ } else {
+ /* Avoid undefined result */
+ return 0;
+ }
+ }
+}
+
+/* Invert int32 value and return result as int32 in a given Q-domain */
+SKP_INLINE SKP_int32 SKP_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */
+ const SKP_int32 b32, /* I denominator (Q0) */
+ const SKP_int Qres /* I Q-domain of result (> 0) */
+)
+{
+ SKP_int b_headrm, lshift;
+ SKP_int32 b32_inv, b32_nrm, err_Q32, result;
+
+ SKP_assert( b32 != 0 );
+ SKP_assert( b32 != SKP_int32_MIN ); /* SKP_int32_MIN is not handled by SKP_abs */
+ SKP_assert( Qres > 0 );
+
+ /* Compute number of bits head room and normalize input */
+ b_headrm = SKP_Silk_CLZ32( SKP_abs(b32) ) - 1;
+ b32_nrm = SKP_LSHIFT(b32, b_headrm); /* Q: b_headrm */
+
+ /* Inverse of b32, with 14 bits of precision */
+ b32_inv = SKP_DIV32_16( SKP_int32_MAX >> 2, SKP_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
+
+ /* First approximation */
+ result = SKP_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */
+
+ /* Compute residual by subtracting product of denominator and first approximation from one */
+ err_Q32 = SKP_LSHIFT_ovflw( -SKP_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */
+
+ /* Refinement */
+ result = SKP_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */
+
+ /* Convert to Qres domain */
+ lshift = 61 - b_headrm - Qres;
+ if( lshift <= 0 ) {
+ return SKP_LSHIFT_SAT32(result, -lshift);
+ } else {
+ if( lshift < 32){
+ return SKP_RSHIFT(result, lshift);
+ }else{
+ /* Avoid undefined result */
+ return 0;
+ }
+ }
+}
+
+#define SKP_SIN_APPROX_CONST0 (1073735400)
+#define SKP_SIN_APPROX_CONST1 (-82778932)
+#define SKP_SIN_APPROX_CONST2 (1059577)
+#define SKP_SIN_APPROX_CONST3 (-5013)
+
+/* Sine approximation; an input of 65536 corresponds to 2 * pi */
+/* Uses polynomial expansion of the input to the power 0, 2, 4 and 6 */
+/* The relative error is below 1e-5 */
+SKP_INLINE SKP_int32 SKP_Silk_SIN_APPROX_Q24( /* O returns approximately 2^24 * sin(x * 2 * pi / 65536) */
+ SKP_int32 x
+)
+{
+ SKP_int y_Q30;
+
+ /* Keep only bottom 16 bits (the function repeats itself with period 65536) */
+ x &= 65535;
+
+ /* Split range in four quadrants */
+ if( x <= 32768 ) {
+ if( x < 16384 ) {
+ /* Return cos(pi/2 - x) */
+ x = 16384 - x;
+ } else {
+ /* Return cos(x - pi/2) */
+ x -= 16384;
+ }
+ if( x < 1100 ) {
+ /* Special case: high accuracy */
+ return SKP_SMLAWB( 1 << 24, SKP_MUL( x, x ), -5053 );
+ }
+ x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */
+ y_Q30 = SKP_SMLAWB( SKP_SIN_APPROX_CONST2, x, SKP_SIN_APPROX_CONST3 );
+ y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST1, x, y_Q30 );
+ y_Q30 = SKP_SMLAWW( SKP_SIN_APPROX_CONST0 + 66, x, y_Q30 );
+ } else {
+ if( x < 49152 ) {
+ /* Return -cos(3*pi/2 - x) */
+ x = 49152 - x;
+ } else {
+ /* Return -cos(x - 3*pi/2) */
+ x -= 49152;
+ }
+ if( x < 1100 ) {
+ /* Special case: high accuracy */
+ return SKP_SMLAWB( -(1 << 24), SKP_MUL( x, x ), 5053 );
+ }
+ x = SKP_SMULWB( SKP_LSHIFT( x, 8 ), x ); /* contains x^2 in Q20 */
+ y_Q30 = SKP_SMLAWB( -SKP_SIN_APPROX_CONST2, x, -SKP_SIN_APPROX_CONST3 );
+ y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST1, x, y_Q30 );
+ y_Q30 = SKP_SMLAWW( -SKP_SIN_APPROX_CONST0, x, y_Q30 );
+ }
+ return SKP_RSHIFT_ROUND( y_Q30, 6 );
+}
+
+/* Cosine approximation; an input of 65536 corresponds to 2 * pi */
+/* The relative error is below 1e-5 */
+SKP_INLINE SKP_int32 SKP_Silk_COS_APPROX_Q24( /* O returns approximately 2^24 * cos(x * 2 * pi / 65536) */
+ SKP_int32 x
+)
+{
+ return SKP_Silk_SIN_APPROX_Q24( x + 16384 );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_SKP_SILK_FIX_INLINES_H_*/
diff --git a/pkg/silk/csilk/SKP_Silk_LBRR_reset.c b/pkg/silk/csilk/SKP_Silk_LBRR_reset.c
new file mode 100644
index 0000000..f9ef0e6
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LBRR_reset.c
@@ -0,0 +1,40 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Resets LBRR buffer, used if packet size changes */
+void SKP_Silk_LBRR_reset(
+ SKP_Silk_encoder_state *psEncC /* I/O state */
+)
+{
+ SKP_int i;
+
+ for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
+ psEncC->LBRR_buffer[ i ].usage = SKP_SILK_NO_LBRR;
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_LPC_inv_pred_gain.c b/pkg/silk/csilk/SKP_Silk_LPC_inv_pred_gain.c
new file mode 100644
index 0000000..3f8de6f
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LPC_inv_pred_gain.c
@@ -0,0 +1,154 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_LPC_inverse_pred_gain.c *
+ * *
+ * Compute inverse of LPC prediction gain, and *
+ * test if LPC coefficients are stable (all poles within unit circle) *
+ * *
+ * Copyright 2008 (c), Skype Limited *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+#undef QA
+#define QA 16
+#define A_LIMIT SKP_FIX_CONST( 0.99975, QA )
+
+/* Compute inverse of LPC prediction gain, and */
+/* test if LPC coefficients are stable (all poles within unit circle) */
+static SKP_int LPC_inverse_pred_gain_QA( /* O: Returns 1 if unstable, otherwise 0 */
+ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
+ SKP_int32 A_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ],
+ /* I: Prediction coefficients */
+ const SKP_int order /* I: Prediction order */
+)
+{
+ SKP_int k, n, headrm;
+ SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16, tmp_QA;
+ SKP_int32 *Aold_QA, *Anew_QA;
+
+ Anew_QA = A_QA[ order & 1 ];
+
+ *invGain_Q30 = ( 1 << 30 );
+ for( k = order - 1; k > 0; k-- ) {
+ /* Check for stability */
+ if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
+ return 1;
+ }
+
+ /* Set RC equal to negated AR coef */
+ rc_Q31 = -SKP_LSHIFT( Anew_QA[ k ], 31 - QA );
+
+ /* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */
+ rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );
+ SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
+ SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) );
+
+ /* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */
+ rc_mult2_Q16 = SKP_INVERSE32_varQ( rc_mult1_Q30, 46 ); /* 16 = 46 - 30 */
+
+ /* Update inverse gain */
+ /* invGain_Q30 range: [ 0 : 2^30 ] */
+ *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
+ SKP_assert( *invGain_Q30 >= 0 );
+ SKP_assert( *invGain_Q30 <= ( 1 << 30 ) );
+
+ /* Swap pointers */
+ Aold_QA = Anew_QA;
+ Anew_QA = A_QA[ k & 1 ];
+
+ /* Update AR coefficient */
+ headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1;
+ rc_mult2_Q16 = SKP_LSHIFT( rc_mult2_Q16, headrm ); /* Q: 16 + headrm */
+ for( n = 0; n < k; n++ ) {
+ tmp_QA = Aold_QA[ n ] - SKP_LSHIFT( SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ), 1 );
+ Anew_QA[ n ] = SKP_LSHIFT( SKP_SMMUL( tmp_QA, rc_mult2_Q16 ), 16 - headrm );
+ }
+ }
+
+ /* Check for stability */
+ if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
+ return 1;
+ }
+
+ /* Set RC equal to negated AR coef */
+ rc_Q31 = -SKP_LSHIFT( Anew_QA[ 0 ], 31 - QA );
+
+ /* Range: [ 1 : 2^30 ] */
+ rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );
+
+ /* Update inverse gain */
+ /* Range: [ 0 : 2^30 ] */
+ *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );
+ SKP_assert( *invGain_Q30 >= 0 );
+ SKP_assert( *invGain_Q30 <= 1<<30 );
+
+ return 0;
+}
+/* For input in Q12 domain */
+SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */
+ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
+ const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */
+ const SKP_int order /* I: Prediction order */
+)
+{
+ SKP_int k;
+ SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];
+ SKP_int32 *Anew_QA;
+
+ Anew_QA = Atmp_QA[ order & 1 ];
+
+ /* Increase Q domain of the AR coefficients */
+ for( k = 0; k < order; k++ ) {
+ Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q12[ k ], QA - 12 );
+ }
+
+ return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
+}
+
+/* For input in Q24 domain */
+SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
+ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
+ const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */
+ const SKP_int order /* I: Prediction order */
+)
+{
+ SKP_int k;
+ SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];
+ SKP_int32 *Anew_QA;
+
+ Anew_QA = Atmp_QA[ order & 1 ];
+
+ /* Increase Q domain of the AR coefficients */
+ for( k = 0; k < order; k++ ) {
+ Anew_QA[ k ] = SKP_RSHIFT_ROUND( A_Q24[ k ], 24 - QA );
+ }
+
+ return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_LPC_synthesis_filter.c b/pkg/silk/csilk/SKP_Silk_LPC_synthesis_filter.c
new file mode 100644
index 0000000..9121e58
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LPC_synthesis_filter.c
@@ -0,0 +1,117 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_LPC_synthesis_filter.c *
+ * Coefficients are in Q12 *
+ * *
+ * even order AR filter *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* even order AR filter */
+void SKP_Silk_LPC_synthesis_filter(
+ const SKP_int16 *in, /* I: excitation signal */
+ const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
+ const SKP_int32 Gain_Q26, /* I: gain */
+ SKP_int32 *S, /* I/O: state vector [Order] */
+ SKP_int16 *out, /* O: output signal */
+ const SKP_int32 len, /* I: signal length */
+ const SKP_int Order /* I: filter order, must be even */
+)
+{
+ SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
+ SKP_int32 SA, SB, out32_Q10, out32;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 Atmp, A_align_Q12[ SKP_Silk_MAX_ORDER_LPC >> 1 ];
+
+ /* combine two A_Q12 values and ensure 32-bit alignment */
+ for( k = 0; k < Order_half; k++ ) {
+ idx = SKP_SMULBB( 2, k );
+ A_align_Q12[ k ] = ( ( ( SKP_int32 )A_Q12[ idx ] ) & 0x0000ffff ) | SKP_LSHIFT( ( SKP_int32 )A_Q12[ idx + 1 ], 16 );
+ }
+#endif
+
+ /* Order must be even */
+ SKP_assert( 2 * Order_half == Order );
+
+ /* S[] values are in Q14 */
+ for( k = 0; k < len; k++ ) {
+ SA = S[ Order - 1 ];
+ out32_Q10 = 0;
+ for( j = 0; j < ( Order_half - 1 ); j++ ) {
+ idx = SKP_SMULBB( 2, j ) + 1;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* multiply-add two prediction coefficients for each loop */
+ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
+ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
+ /* loaded in reverse order and the code will give the wrong result. In that case swapping */
+ /* the SMLAWB and SMLAWT instructions should solve the problem. */
+ Atmp = A_align_Q12[ j ];
+ SB = S[ Order - 1 - idx ];
+ S[ Order - 1 - idx ] = SA;
+ out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp );
+ SA = S[ Order - 2 - idx ];
+ S[ Order - 2 - idx ] = SB;
+#else
+ SB = S[ Order - 1 - idx ];
+ S[ Order - 1 - idx ] = SA;
+ out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] );
+ out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] );
+ SA = S[ Order - 2 - idx ];
+ S[ Order - 2 - idx ] = SB;
+#endif
+ }
+
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* unrolled loop: epilog */
+ Atmp = A_align_Q12[ Order_half - 1 ];
+ SB = S[ 0 ];
+ S[ 0 ] = SA;
+ out32_Q10 = SKP_SMLAWB( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT( out32_Q10, SB, Atmp );
+#else
+ /* unrolled loop: epilog */
+ SB = S[ 0 ];
+ S[ 0 ] = SA;
+ out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] );
+ out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] );
+#endif
+ /* apply gain to excitation signal and add to prediction */
+ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
+
+ /* scale to Q0 */
+ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
+
+ /* saturate output */
+ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
+
+ /* move result into delay line */
+ S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_LPC_synthesis_order16.c b/pkg/silk/csilk/SKP_Silk_LPC_synthesis_order16.c
new file mode 100644
index 0000000..eae2435
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LPC_synthesis_order16.c
@@ -0,0 +1,216 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_LPC_synthesis_order16.c *
+ * Coefficients are in Q12 *
+ * *
+ * 16th order AR filter *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* 16th order AR filter */
+void SKP_Silk_LPC_synthesis_order16(const SKP_int16 *in, /* I: excitation signal */
+ const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
+ const SKP_int32 Gain_Q26, /* I: gain */
+ SKP_int32 *S, /* I/O: state vector [16] */
+ SKP_int16 *out, /* O: output signal */
+ const SKP_int32 len /* I: signal length, must be multiple of 16 */
+)
+{
+ SKP_int k;
+ SKP_int32 SA, SB, out32_Q10, out32;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 Atmp, A_align_Q12[ 8 ];
+ /* combine two A_Q12 values and ensure 32-bit alignment */
+ for( k = 0; k < 8; k++ ) {
+ A_align_Q12[ k ] = ( ( ( SKP_int32 )A_Q12[ 2 * k ] ) & 0x0000ffff ) | SKP_LSHIFT( ( SKP_int32 )A_Q12[ 2 * k + 1 ], 16 );
+ }
+ /* S[] values are in Q14 */
+ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
+ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
+ /* loaded in reverse order and the code will give the wrong result. In that case swapping */
+ /* the SMLAWB and SMLAWT instructions should solve the problem. */
+ for( k = 0; k < len; k++ ) {
+ /* unrolled loop: prolog */
+ /* multiply-add two prediction coefficients per iteration */
+ SA = S[ 15 ];
+ Atmp = A_align_Q12[ 0 ];
+ SB = S[ 14 ];
+ S[ 14 ] = SA;
+ out32_Q10 = SKP_SMULWB( SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+ SA = S[ 13 ];
+ S[ 13 ] = SB;
+
+ /* unrolled loop: main loop */
+ Atmp = A_align_Q12[ 1 ];
+ SB = S[ 12 ];
+ S[ 12 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+ SA = S[ 11 ];
+ S[ 11 ] = SB;
+
+ Atmp = A_align_Q12[ 2 ];
+ SB = S[ 10 ];
+ S[ 10 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+ SA = S[ 9 ];
+ S[ 9 ] = SB;
+
+ Atmp = A_align_Q12[ 3 ];
+ SB = S[ 8 ];
+ S[ 8 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+ SA = S[ 7 ];
+ S[ 7 ] = SB;
+
+ Atmp = A_align_Q12[ 4 ];
+ SB = S[ 6 ];
+ S[ 6 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+ SA = S[ 5 ];
+ S[ 5 ] = SB;
+
+ Atmp = A_align_Q12[ 5 ];
+ SB = S[ 4 ];
+ S[ 4 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+ SA = S[ 3 ];
+ S[ 3 ] = SB;
+
+ Atmp = A_align_Q12[ 6 ];
+ SB = S[ 2 ];
+ S[ 2 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+ SA = S[ 1 ];
+ S[ 1 ] = SB;
+
+ /* unrolled loop: epilog */
+ Atmp = A_align_Q12[ 7 ];
+ SB = S[ 0 ];
+ S[ 0 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, Atmp );
+ out32_Q10 = SKP_SMLAWT_ovflw( out32_Q10, SB, Atmp );
+
+ /* unrolled loop: end */
+ /* apply gain to excitation signal and add to prediction */
+ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
+
+ /* scale to Q0 */
+ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
+
+ /* saturate output */
+ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
+
+ /* move result into delay line */
+ S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
+ }
+#else
+ for( k = 0; k < len; k++ ) {
+ /* unrolled loop: prolog */
+ /* multiply-add two prediction coefficients per iteration */
+ SA = S[ 15 ];
+ SB = S[ 14 ];
+ S[ 14 ] = SA;
+ out32_Q10 = SKP_SMULWB( SA, A_Q12[ 0 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 1 ] );
+ SA = S[ 13 ];
+ S[ 13 ] = SB;
+
+ /* unrolled loop: main loop */
+ SB = S[ 12 ];
+ S[ 12 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 2 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 3 ] );
+ SA = S[ 11 ];
+ S[ 11 ] = SB;
+
+ SB = S[ 10 ];
+ S[ 10 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 4 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 5 ] );
+ SA = S[ 9 ];
+ S[ 9 ] = SB;
+
+ SB = S[ 8 ];
+ S[ 8 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 6 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 7 ] );
+ SA = S[ 7 ];
+ S[ 7 ] = SB;
+
+ SB = S[ 6 ];
+ S[ 6 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 8 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 9 ] );
+ SA = S[ 5 ];
+ S[ 5 ] = SB;
+
+ SB = S[ 4 ];
+ S[ 4 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 10 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 11 ] );
+ SA = S[ 3 ];
+ S[ 3 ] = SB;
+
+ SB = S[ 2 ];
+ S[ 2 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 12 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 13 ] );
+ SA = S[ 1 ];
+ S[ 1 ] = SB;
+
+ /* unrolled loop: epilog */
+ SB = S[ 0 ];
+ S[ 0 ] = SA;
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 14 ] );
+ out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 15 ] );
+
+ /* unrolled loop: end */
+ /* apply gain to excitation signal and add to prediction */
+ out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
+
+ /* scale to Q0 */
+ out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
+
+ /* saturate output */
+ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
+
+ /* move result into delay line */
+ S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
+ }
+#endif
+}
+
+
diff --git a/pkg/silk/csilk/SKP_Silk_LP_variable_cutoff.c b/pkg/silk/csilk/SKP_Silk_LP_variable_cutoff.c
new file mode 100644
index 0000000..ed19466
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LP_variable_cutoff.c
@@ -0,0 +1,194 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/*
+
+ Elliptic/Cauer filters designed with 0.1 dB passband ripple,
+ 80 dB minimum stopband attenuation, and
+ [0.95 : 0.15 : 0.35] normalized cut off frequencies.
+
+*/
+#include "SKP_Silk_main.h"
+
+#if SWITCH_TRANSITION_FILTERING
+
+/* Helper function, that interpolates the filter taps */
+SKP_INLINE void SKP_Silk_LP_interpolate_filter_taps(
+ SKP_int32 B_Q28[ TRANSITION_NB ],
+ SKP_int32 A_Q28[ TRANSITION_NA ],
+ const SKP_int ind,
+ const SKP_int32 fac_Q16
+)
+{
+ SKP_int nb, na;
+
+ if( ind < TRANSITION_INT_NUM - 1 ) {
+ if( fac_Q16 > 0 ) {
+ if( fac_Q16 == SKP_SAT16( fac_Q16 ) ) { /* fac_Q16 is in range of a 16-bit int */
+ /* Piece-wise linear interpolation of B and A */
+ for( nb = 0; nb < TRANSITION_NB; nb++ ) {
+ B_Q28[ nb ] = SKP_SMLAWB(
+ SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ],
+ SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
+ SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ],
+ fac_Q16 );
+ }
+ for( na = 0; na < TRANSITION_NA; na++ ) {
+ A_Q28[ na ] = SKP_SMLAWB(
+ SKP_Silk_Transition_LP_A_Q28[ ind ][ na ],
+ SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
+ SKP_Silk_Transition_LP_A_Q28[ ind ][ na ],
+ fac_Q16 );
+ }
+ } else if( fac_Q16 == ( 1 << 15 ) ) { /* Neither fac_Q16 nor ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */
+
+ /* Piece-wise linear interpolation of B and A */
+ for( nb = 0; nb < TRANSITION_NB; nb++ ) {
+ B_Q28[ nb ] = SKP_RSHIFT(
+ SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] +
+ SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
+ 1 );
+ }
+ for( na = 0; na < TRANSITION_NA; na++ ) {
+ A_Q28[ na ] = SKP_RSHIFT(
+ SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] +
+ SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
+ 1 );
+ }
+ } else { /* ( ( 1 << 16 ) - fac_Q16 ) is in range of a 16-bit int */
+
+ SKP_assert( ( ( 1 << 16 ) - fac_Q16 ) == SKP_SAT16( ( ( 1 << 16 ) - fac_Q16) ) );
+ /* Piece-wise linear interpolation of B and A */
+ for( nb = 0; nb < TRANSITION_NB; nb++ ) {
+ B_Q28[ nb ] = SKP_SMLAWB(
+ SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
+ SKP_Silk_Transition_LP_B_Q28[ ind ][ nb ] -
+ SKP_Silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
+ ( 1 << 16 ) - fac_Q16 );
+ }
+ for( na = 0; na < TRANSITION_NA; na++ ) {
+ A_Q28[ na ] = SKP_SMLAWB(
+ SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
+ SKP_Silk_Transition_LP_A_Q28[ ind ][ na ] -
+ SKP_Silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
+ ( 1 << 16 ) - fac_Q16 );
+ }
+ }
+ } else {
+ SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( SKP_int32 ) );
+ SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( SKP_int32 ) );
+ }
+ } else {
+ SKP_memcpy( B_Q28, SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( SKP_int32 ) );
+ SKP_memcpy( A_Q28, SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( SKP_int32 ) );
+ }
+}
+
+/* Low-pass filter with variable cutoff frequency based on */
+/* piece-wise linear interpolation between elliptic filters */
+/* Start by setting psEncC->transition_frame_no = 1; */
+/* Deactivate by setting psEncC->transition_frame_no = 0; */
+void SKP_Silk_LP_variable_cutoff(
+ SKP_Silk_LP_state *psLP, /* I/O LP filter state */
+ SKP_int16 *out, /* O Low-pass filtered output signal */
+ const SKP_int16 *in, /* I Input signal */
+ const SKP_int frame_length /* I Frame length */
+)
+{
+ SKP_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;
+ SKP_int ind = 0;
+
+ SKP_assert( psLP->transition_frame_no >= 0 );
+ SKP_assert( ( ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_DOWN ) && ( psLP->mode == 0 ) ) ||
+ ( ( psLP->transition_frame_no <= TRANSITION_FRAMES_UP ) && ( psLP->mode == 1 ) ) ) );
+
+ /* Interpolate filter coefficients if needed */
+ if( psLP->transition_frame_no > 0 ) {
+ if( psLP->mode == 0 ) {
+ if( psLP->transition_frame_no < TRANSITION_FRAMES_DOWN ) {
+ /* Calculate index and interpolation factor for interpolation */
+#if( TRANSITION_INT_STEPS_DOWN == 32 )
+ fac_Q16 = SKP_LSHIFT( psLP->transition_frame_no, 16 - 5 );
+#else
+ fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_DOWN );
+#endif
+ ind = SKP_RSHIFT( fac_Q16, 16 );
+ fac_Q16 -= SKP_LSHIFT( ind, 16 );
+
+ SKP_assert( ind >= 0 );
+ SKP_assert( ind < TRANSITION_INT_NUM );
+
+ /* Interpolate filter coefficients */
+ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
+
+ /* Increment transition frame number for next frame */
+ psLP->transition_frame_no++;
+
+ } else {
+ SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_DOWN );
+ /* End of transition phase */
+ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, TRANSITION_INT_NUM - 1, 0 );
+ }
+ } else {
+ SKP_assert( psLP->mode == 1 );
+ if( psLP->transition_frame_no < TRANSITION_FRAMES_UP ) {
+ /* Calculate index and interpolation factor for interpolation */
+#if( TRANSITION_INT_STEPS_UP == 64 )
+ fac_Q16 = SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 - 6 );
+#else
+ fac_Q16 = SKP_DIV32_16( SKP_LSHIFT( TRANSITION_FRAMES_UP - psLP->transition_frame_no, 16 ), TRANSITION_INT_STEPS_UP );
+#endif
+ ind = SKP_RSHIFT( fac_Q16, 16 );
+ fac_Q16 -= SKP_LSHIFT( ind, 16 );
+
+ SKP_assert( ind >= 0 );
+ SKP_assert( ind < TRANSITION_INT_NUM );
+
+ /* Interpolate filter coefficients */
+ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
+
+ /* Increment transition frame number for next frame */
+ psLP->transition_frame_no++;
+
+ } else {
+ SKP_assert( psLP->transition_frame_no == TRANSITION_FRAMES_UP );
+ /* End of transition phase */
+ SKP_Silk_LP_interpolate_filter_taps( B_Q28, A_Q28, 0, 0 );
+ }
+ }
+ }
+
+ if( psLP->transition_frame_no > 0 ) {
+ /* ARMA low-pass filtering */
+ SKP_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
+ SKP_Silk_biquad_alt( in, B_Q28, A_Q28, psLP->In_LP_State, out, frame_length );
+ } else {
+ /* Instead of using the filter, copy input directly to output */
+ SKP_memcpy( out, in, frame_length * sizeof( SKP_int16 ) );
+ }
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_LSF_cos_table.c b/pkg/silk/csilk/SKP_Silk_LSF_cos_table.c
new file mode 100644
index 0000000..4d9ffe5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LSF_cos_table.c
@@ -0,0 +1,65 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SigProc_FIX.h"
+
+// Q12 values (even)
+const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[LSF_COS_TAB_SZ_FIX + 1] = {
+ 8192, 8190, 8182, 8170,
+ 8152, 8130, 8104, 8072,
+ 8034, 7994, 7946, 7896,
+ 7840, 7778, 7714, 7644,
+ 7568, 7490, 7406, 7318,
+ 7226, 7128, 7026, 6922,
+ 6812, 6698, 6580, 6458,
+ 6332, 6204, 6070, 5934,
+ 5792, 5648, 5502, 5352,
+ 5198, 5040, 4880, 4718,
+ 4552, 4382, 4212, 4038,
+ 3862, 3684, 3502, 3320,
+ 3136, 2948, 2760, 2570,
+ 2378, 2186, 1990, 1794,
+ 1598, 1400, 1202, 1002,
+ 802, 602, 402, 202,
+ 0, -202, -402, -602,
+ -802, -1002, -1202, -1400,
+ -1598, -1794, -1990, -2186,
+ -2378, -2570, -2760, -2948,
+ -3136, -3320, -3502, -3684,
+ -3862, -4038, -4212, -4382,
+ -4552, -4718, -4880, -5040,
+ -5198, -5352, -5502, -5648,
+ -5792, -5934, -6070, -6204,
+ -6332, -6458, -6580, -6698,
+ -6812, -6922, -7026, -7128,
+ -7226, -7318, -7406, -7490,
+ -7568, -7644, -7714, -7778,
+ -7840, -7896, -7946, -7994,
+ -8034, -8072, -8104, -8130,
+ -8152, -8170, -8182, -8190,
+ -8192
+};
diff --git a/pkg/silk/csilk/SKP_Silk_LTP_analysis_filter_FIX.c b/pkg/silk/csilk/SKP_Silk_LTP_analysis_filter_FIX.c
new file mode 100644
index 0000000..612124c
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LTP_analysis_filter_FIX.c
@@ -0,0 +1,80 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+void SKP_Silk_LTP_analysis_filter_FIX(
+ SKP_int16 *LTP_res, /* O: LTP residual signal of length NB_SUBFR * ( pre_length + subfr_length ) */
+ const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */
+ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each NB_SUBFR subframe */
+ const SKP_int pitchL[ NB_SUBFR ], /* I: Pitch lag, one for each subframe */
+ const SKP_int32 invGains_Q16[ NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */
+ const SKP_int subfr_length, /* I: Length of each subframe */
+ const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */
+)
+{
+ const SKP_int16 *x_ptr, *x_lag_ptr;
+ SKP_int16 Btmp_Q14[ LTP_ORDER ];
+ SKP_int16 *LTP_res_ptr;
+ SKP_int k, i, j;
+ SKP_int32 LTP_est;
+
+ x_ptr = x;
+ LTP_res_ptr = LTP_res;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+
+ x_lag_ptr = x_ptr - pitchL[ k ];
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ];
+ }
+
+ /* LTP analysis FIR filter */
+ for( i = 0; i < subfr_length + pre_length; i++ ) {
+ LTP_res_ptr[ i ] = x_ptr[ i ];
+
+ /* Long-term prediction */
+ LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
+ for( j = 1; j < LTP_ORDER; j++ ) {
+ LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] );
+ }
+ LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0
+
+ /* Subtract long-term prediction */
+ LTP_res_ptr[ i ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )x_ptr[ i ] - LTP_est );
+
+ /* Scale residual */
+ LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
+
+ x_lag_ptr++;
+ }
+
+ /* Update pointers */
+ LTP_res_ptr += subfr_length + pre_length;
+ x_ptr += subfr_length;
+ }
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_LTP_scale_ctrl_FIX.c b/pkg/silk/csilk/SKP_Silk_LTP_scale_ctrl_FIX.c
new file mode 100644
index 0000000..51283b5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_LTP_scale_ctrl_FIX.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+#define NB_THRESHOLDS 11
+
+/* Table containing trained thresholds for LTP scaling */
+static const SKP_int16 LTPScaleThresholds_Q15[ NB_THRESHOLDS ] =
+{
+ 31129, 26214, 16384, 13107, 9830, 6554,
+ 4915, 3276, 2621, 2458, 0
+};
+
+void SKP_Silk_LTP_scale_ctrl_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state FIX */
+ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control FIX */
+)
+{
+ SKP_int round_loss, frames_per_packet;
+ SKP_int g_out_Q5, g_limit_Q15, thrld1_Q15, thrld2_Q15;
+
+ /* 1st order high-pass filter */
+ psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - psEnc->prevLTPredCodGain_Q7, 0 )
+ + SKP_RSHIFT_ROUND( psEnc->HPLTPredCodGain_Q7, 1 );
+
+ psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7;
+
+ /* combine input and filtered input */
+ g_out_Q5 = SKP_RSHIFT_ROUND( SKP_RSHIFT( psEncCtrl->LTPredCodGain_Q7, 1 ) + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 ), 3 );
+ g_limit_Q15 = SKP_Silk_sigm_Q15( g_out_Q5 - ( 3 << 5 ) );
+
+ /* Default is minimum scaling */
+ psEncCtrl->sCmn.LTP_scaleIndex = 0;
+
+ /* Round the loss measure to whole pct */
+ round_loss = ( SKP_int )psEnc->sCmn.PacketLoss_perc;
+
+ /* Only scale if first frame in packet 0% */
+ if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
+
+ frames_per_packet = SKP_DIV32_16( psEnc->sCmn.PacketSize_ms, FRAME_LENGTH_MS );
+
+ round_loss += frames_per_packet - 1;
+ thrld1_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss, NB_THRESHOLDS - 1 ) ];
+ thrld2_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss + 1, NB_THRESHOLDS - 1 ) ];
+
+ if( g_limit_Q15 > thrld1_Q15 ) {
+ /* Maximum scaling */
+ psEncCtrl->sCmn.LTP_scaleIndex = 2;
+ } else if( g_limit_Q15 > thrld2_Q15 ) {
+ /* Medium scaling */
+ psEncCtrl->sCmn.LTP_scaleIndex = 1;
+ }
+ }
+ psEncCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ];
+}
diff --git a/pkg/silk/csilk/SKP_Silk_MA.c b/pkg/silk/csilk/SKP_Silk_MA.c
new file mode 100644
index 0000000..fcdce14
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_MA.c
@@ -0,0 +1,120 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_MA.c *
+ * *
+ * Variable order MA filter *
+ * *
+ * Copyright 2006 (c), Skype Limited *
+ * Date: 060221 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+#if EMBEDDED_ARM<5
+/* Variable order MA prediction error filter */
+void SKP_Silk_MA_Prediction(
+ const SKP_int16 *in, /* I: Input signal */
+ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
+ SKP_int32 *S, /* I/O: State vector [order] */
+ SKP_int16 *out, /* O: Output signal */
+ const SKP_int32 len, /* I: Signal length */
+ const SKP_int32 order /* I: Filter order */
+)
+{
+ SKP_int k, d, in16;
+ SKP_int32 out32;
+
+ for( k = 0; k < len; k++ ) {
+ in16 = in[ k ];
+ out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
+ out32 = SKP_RSHIFT_ROUND( out32, 12 );
+
+ for( d = 0; d < order - 1; d++ ) {
+ S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );
+ }
+ S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );
+
+ /* Limit */
+ out[ k ] = (SKP_int16)SKP_SAT16( out32 );
+ }
+}
+#endif
+
+#if EMBEDDED_ARM<5
+
+void SKP_Silk_LPC_analysis_filter(
+ const SKP_int16 *in, /* I: Input signal */
+ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
+ SKP_int16 *S, /* I/O: State vector [order] */
+ SKP_int16 *out, /* O: Output signal */
+ const SKP_int32 len, /* I: Signal length */
+ const SKP_int32 Order /* I: Filter order */
+)
+{
+ SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
+ SKP_int32 out32_Q12, out32;
+ SKP_int16 SA, SB;
+ /* Order must be even */
+ SKP_assert( 2 * Order_half == Order );
+
+ /* S[] values are in Q0 */
+ for( k = 0; k < len; k++ ) {
+ SA = S[ 0 ];
+ out32_Q12 = 0;
+ for( j = 0; j < ( Order_half - 1 ); j++ ) {
+ idx = SKP_SMULBB( 2, j ) + 1;
+ /* Multiply-add two prediction coefficients for each loop */
+ SB = S[ idx ];
+ S[ idx ] = SA;
+ out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ idx - 1 ] );
+ out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ idx ] );
+ SA = S[ idx + 1 ];
+ S[ idx + 1 ] = SB;
+ }
+
+ /* Unrolled loop: epilog */
+ SB = S[ Order - 1 ];
+ S[ Order - 1 ] = SA;
+ out32_Q12 = SKP_SMLABB( out32_Q12, SA, B[ Order - 2 ] );
+ out32_Q12 = SKP_SMLABB( out32_Q12, SB, B[ Order - 1 ] );
+
+ /* Subtract prediction */
+ out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT( (SKP_int32)in[ k ], 12 ), out32_Q12 );
+
+ /* Scale to Q0 */
+ out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 );
+
+ /* Saturate output */
+ out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
+
+ /* Move input line */
+ S[ 0 ] = in[ k ];
+ }
+}
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF2A.c b/pkg/silk/csilk/SKP_Silk_NLSF2A.c
new file mode 100644
index 0000000..732b0f9
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF2A.c
@@ -0,0 +1,151 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* conversion between prediction filter coefficients and LSFs */
+/* order should be even */
+/* a piecewise linear approximation maps LSF <-> cos(LSF) */
+/* therefore the result is not accurate LSFs, but the two */
+/* function are accurate inverses of each other */
+
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* helper function for NLSF2A(..) */
+SKP_INLINE void SKP_Silk_NLSF2A_find_poly(
+ SKP_int32 *out, /* o intermediate polynomial, Q20 */
+ const SKP_int32 *cLSF, /* i vector of interleaved 2*cos(LSFs), Q20 */
+ SKP_int dd /* i polynomial order (= 1/2 * filter order) */
+)
+{
+ SKP_int k, n;
+ SKP_int32 ftmp;
+
+ out[0] = SKP_LSHIFT( 1, 20 );
+ out[1] = -cLSF[0];
+ for( k = 1; k < dd; k++ ) {
+ ftmp = cLSF[2*k]; // Q20
+ out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), 20 );
+ for( n = k; n > 1; n-- ) {
+ out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), 20 );
+ }
+ out[1] -= ftmp;
+ }
+}
+
+/* compute whitening filter coefficients from normalized line spectral frequencies */
+void SKP_Silk_NLSF2A(
+ SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
+ const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
+ const SKP_int d /* i filter order (should be even) */
+)
+{
+ SKP_int k, i, dd;
+ SKP_int32 cos_LSF_Q20[SKP_Silk_MAX_ORDER_LPC];
+ SKP_int32 P[SKP_Silk_MAX_ORDER_LPC/2+1], Q[SKP_Silk_MAX_ORDER_LPC/2+1];
+ SKP_int32 Ptmp, Qtmp;
+ SKP_int32 f_int;
+ SKP_int32 f_frac;
+ SKP_int32 cos_val, delta;
+ SKP_int32 a_int32[SKP_Silk_MAX_ORDER_LPC];
+ SKP_int32 maxabs, absval, idx=0, sc_Q16;
+
+ SKP_assert(LSF_COS_TAB_SZ_FIX == 128);
+
+ /* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */
+ for( k = 0; k < d; k++ ) {
+ SKP_assert(NLSF[k] >= 0 );
+ SKP_assert(NLSF[k] <= 32767 );
+
+ /* f_int on a scale 0-127 (rounded down) */
+ f_int = SKP_RSHIFT( NLSF[k], 15 - 7 );
+
+ /* f_frac, range: 0..255 */
+ f_frac = NLSF[k] - SKP_LSHIFT( f_int, 15 - 7 );
+
+ SKP_assert(f_int >= 0);
+ SKP_assert(f_int < LSF_COS_TAB_SZ_FIX );
+
+ /* Read start and end value from table */
+ cos_val = SKP_Silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */
+ delta = SKP_Silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */
+
+ /* Linear interpolation */
+ cos_LSF_Q20[k] = SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ); /* Q20 */
+ }
+
+ dd = SKP_RSHIFT( d, 1 );
+
+ /* generate even and odd polynomials using convolution */
+ SKP_Silk_NLSF2A_find_poly( P, &cos_LSF_Q20[0], dd );
+ SKP_Silk_NLSF2A_find_poly( Q, &cos_LSF_Q20[1], dd );
+
+ /* convert even and odd polynomials to SKP_int32 Q12 filter coefs */
+ for( k = 0; k < dd; k++ ) {
+ Ptmp = P[k+1] + P[k];
+ Qtmp = Q[k+1] - Q[k];
+
+ /* the Ptmp and Qtmp values at this stage need to fit in int32 */
+
+ a_int32[k] = -SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */
+ a_int32[d-k-1] = SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */
+ }
+
+ /* Limit the maximum absolute value of the prediction coefficients */
+ for( i = 0; i < 10; i++ ) {
+ /* Find maximum absolute value and its index */
+ maxabs = 0;
+ for( k = 0; k < d; k++ ) {
+ absval = SKP_abs( a_int32[k] );
+ if( absval > maxabs ) {
+ maxabs = absval;
+ idx = k;
+ }
+ }
+
+ if( maxabs > SKP_int16_MAX ) {
+ /* Reduce magnitude of prediction coefficients */
+ maxabs = SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369
+ sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ),
+ SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );
+ SKP_Silk_bwexpander_32( a_int32, d, sc_Q16 );
+ } else {
+ break;
+ }
+ }
+
+ /* Reached the last iteration */
+ if( i == 10 ) {
+ SKP_assert(0);
+ for( k = 0; k < d; k++ ) {
+ a_int32[k] = SKP_SAT16( a_int32[k] );
+ }
+ }
+
+ /* Return as SKP_int16 Q12 coefficients */
+ for( k = 0; k < d; k++ ) {
+ a[k] = (SKP_int16)a_int32[k];
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF2A_stable.c b/pkg/silk/csilk/SKP_Silk_NLSF2A_stable.c
new file mode 100644
index 0000000..63da339
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF2A_stable.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Convert NLSF parameters to stable AR prediction filter coefficients */
+void SKP_Silk_NLSF2A_stable(
+ SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */
+ const SKP_int pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */
+ const SKP_int LPC_order /* I LPC/LSF order */
+)
+{
+ SKP_int i;
+ SKP_int32 invGain_Q30;
+
+ SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order );
+
+ /* Ensure stable LPCs */
+ for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
+ if( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) {
+ SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015 */
+ } else {
+ break;
+ }
+ }
+
+ /* Reached the last iteration */
+ if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
+ SKP_assert( 0 );
+ for( i = 0; i < LPC_order; i++ ) {
+ pAR_Q12[ i ] = 0;
+ }
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF_MSVQ_decode.c b/pkg/silk/csilk/SKP_Silk_NLSF_MSVQ_decode.c
new file mode 100644
index 0000000..aa3983f
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF_MSVQ_decode.c
@@ -0,0 +1,91 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* NLSF vector decoder */
+void SKP_Silk_NLSF_MSVQ_decode(
+ SKP_int *pNLSF_Q15, /* O Pointer to decoded output vector [LPC_ORDER x 1] */
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Pointer to NLSF codebook struct */
+ const SKP_int *NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */
+ const SKP_int LPC_order /* I LPC order used */
+)
+{
+ const SKP_int16 *pCB_element;
+ SKP_int s;
+ SKP_int i;
+
+ /* Check that each index is within valid range */
+ SKP_assert( 0 <= NLSFIndices[ 0 ] && NLSFIndices[ 0 ] < psNLSF_CB->CBStages[ 0 ].nVectors );
+
+ /* Point to the first vector element */
+ pCB_element = &psNLSF_CB->CBStages[ 0 ].CB_NLSF_Q15[ SKP_MUL( NLSFIndices[ 0 ], LPC_order ) ];
+
+ /* Initialize with the codebook vector from stage 0 */
+ for( i = 0; i < LPC_order; i++ ) {
+ pNLSF_Q15[ i ] = ( SKP_int )pCB_element[ i ];
+ }
+
+ for( s = 1; s < psNLSF_CB->nStages; s++ ) {
+ /* Check that each index is within valid range */
+ SKP_assert( 0 <= NLSFIndices[ s ] && NLSFIndices[ s ] < psNLSF_CB->CBStages[ s ].nVectors );
+
+ if( LPC_order == 16 ) {
+ /* Point to the first vector element */
+ pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_LSHIFT( NLSFIndices[ s ], 4 ) ];
+
+ /* Add the codebook vector from the current stage */
+ pNLSF_Q15[ 0 ] += pCB_element[ 0 ];
+ pNLSF_Q15[ 1 ] += pCB_element[ 1 ];
+ pNLSF_Q15[ 2 ] += pCB_element[ 2 ];
+ pNLSF_Q15[ 3 ] += pCB_element[ 3 ];
+ pNLSF_Q15[ 4 ] += pCB_element[ 4 ];
+ pNLSF_Q15[ 5 ] += pCB_element[ 5 ];
+ pNLSF_Q15[ 6 ] += pCB_element[ 6 ];
+ pNLSF_Q15[ 7 ] += pCB_element[ 7 ];
+ pNLSF_Q15[ 8 ] += pCB_element[ 8 ];
+ pNLSF_Q15[ 9 ] += pCB_element[ 9 ];
+ pNLSF_Q15[ 10 ] += pCB_element[ 10 ];
+ pNLSF_Q15[ 11 ] += pCB_element[ 11 ];
+ pNLSF_Q15[ 12 ] += pCB_element[ 12 ];
+ pNLSF_Q15[ 13 ] += pCB_element[ 13 ];
+ pNLSF_Q15[ 14 ] += pCB_element[ 14 ];
+ pNLSF_Q15[ 15 ] += pCB_element[ 15 ];
+ } else {
+ /* Point to the first vector element */
+ pCB_element = &psNLSF_CB->CBStages[ s ].CB_NLSF_Q15[ SKP_SMULBB( NLSFIndices[ s ], LPC_order ) ];
+
+ /* Add the codebook vector from the current stage */
+ for( i = 0; i < LPC_order; i++ ) {
+ pNLSF_Q15[ i ] += pCB_element[ i ];
+ }
+ }
+ }
+
+ /* NLSF stabilization */
+ SKP_Silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->NDeltaMin_Q15, LPC_order );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF_MSVQ_encode_FIX.c b/pkg/silk/csilk/SKP_Silk_NLSF_MSVQ_encode_FIX.c
new file mode 100644
index 0000000..5bae4de
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF_MSVQ_encode_FIX.c
@@ -0,0 +1,239 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/***********************/
+/* NLSF vector encoder */
+/***********************/
+void SKP_Silk_NLSF_MSVQ_encode_FIX(
+ SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */
+ SKP_int *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
+ const SKP_int *pNLSF_q_Q15_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */
+ const SKP_int *pW_Q6, /* I NLSF weight vector [ LPC_ORDER ] */
+ const SKP_int NLSF_mu_Q15, /* I Rate weight for the RD optimization */
+ const SKP_int NLSF_mu_fluc_red_Q16, /* I Fluctuation reduction error weight */
+ const SKP_int NLSF_MSVQ_Survivors, /* I Max survivors from each stage */
+ const SKP_int LPC_order, /* I LPC order */
+ const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */
+)
+{
+ SKP_int i, s, k, cur_survivors = 0, prev_survivors, min_survivors, input_index, cb_index, bestIndex;
+ SKP_int32 rateDistThreshold_Q18;
+#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 )
+ SKP_int32 se_Q15, wsse_Q20, bestRateDist_Q20;
+#endif
+
+#if( LOW_COMPLEXITY_ONLY == 1 )
+ SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE ];
+ SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
+ SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
+ SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ];
+ SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];
+ SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_CB_STAGES ];
+ SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];
+ SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * MAX_LPC_ORDER ];
+#else
+ SKP_int32 pRateDist_Q18[ NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED ];
+ SKP_int32 pRate_Q5[ MAX_NLSF_MSVQ_SURVIVORS ];
+ SKP_int32 pRate_new_Q5[ MAX_NLSF_MSVQ_SURVIVORS ];
+ SKP_int pTempIndices[ MAX_NLSF_MSVQ_SURVIVORS ];
+ SKP_int pPath[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];
+ SKP_int pPath_new[ MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_CB_STAGES ];
+ SKP_int pRes_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];
+ SKP_int pRes_new_Q15[ MAX_NLSF_MSVQ_SURVIVORS * MAX_LPC_ORDER ];
+#endif
+
+ const SKP_int *pConstInt;
+ SKP_int *pInt;
+ const SKP_int16 *pCB_element;
+ const SKP_Silk_NLSF_CBS *pCurrentCBStage;
+
+#ifdef USE_UNQUANTIZED_LSFS
+ SKP_int NLSF_orig[ MAX_LPC_ORDER ];
+ SKP_memcpy( NLSF_orig, pNLSF_Q15, LPC_order * sizeof( SKP_int ) );
+#endif
+
+ SKP_assert( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS );
+ SKP_assert( ( LOW_COMPLEXITY_ONLY == 0 ) || ( NLSF_MSVQ_Survivors <= MAX_NLSF_MSVQ_SURVIVORS_LC_MODE ) );
+
+
+ /****************************************************/
+ /* Tree search for the multi-stage vector quantizer */
+ /****************************************************/
+
+ /* Clear accumulated rates */
+ SKP_memset( pRate_Q5, 0, NLSF_MSVQ_Survivors * sizeof( SKP_int32 ) );
+
+ /* Copy NLSFs into residual signal vector */
+ for( i = 0; i < LPC_order; i++ ) {
+ pRes_Q15[ i ] = pNLSF_Q15[ i ];
+ }
+
+ /* Set first stage values */
+ prev_survivors = 1;
+
+ /* Minimum number of survivors */
+ min_survivors = NLSF_MSVQ_Survivors / 2;
+
+ /* Loop over all stages */
+ for( s = 0; s < psNLSF_CB->nStages; s++ ) {
+
+ /* Set a pointer to the current stage codebook */
+ pCurrentCBStage = &psNLSF_CB->CBStages[ s ];
+
+ /* Calculate the number of survivors in the current stage */
+ cur_survivors = SKP_min_32( NLSF_MSVQ_Survivors, SKP_SMULBB( prev_survivors, pCurrentCBStage->nVectors ) );
+
+#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 0 )
+ /* Find a single best survivor in the last stage, if we */
+ /* do not need candidates for fluctuation reduction */
+ if( s == psNLSF_CB->nStages - 1 ) {
+ cur_survivors = 1;
+ }
+#endif
+
+ /* Nearest neighbor clustering for multiple input data vectors */
+ SKP_Silk_NLSF_VQ_rate_distortion_FIX( pRateDist_Q18, pCurrentCBStage, pRes_Q15, pW_Q6,
+ pRate_Q5, NLSF_mu_Q15, prev_survivors, LPC_order );
+
+ /* Sort the rate-distortion errors */
+ SKP_Silk_insertion_sort_increasing( pRateDist_Q18, pTempIndices,
+ prev_survivors * pCurrentCBStage->nVectors, cur_survivors );
+
+ /* Discard survivors with rate-distortion values too far above the best one */
+ if( pRateDist_Q18[ 0 ] < SKP_int32_MAX / MAX_NLSF_MSVQ_SURVIVORS ) {
+ rateDistThreshold_Q18 = SKP_SMLAWB( pRateDist_Q18[ 0 ],
+ SKP_MUL( NLSF_MSVQ_Survivors, pRateDist_Q18[ 0 ] ), SKP_FIX_CONST( NLSF_MSVQ_SURV_MAX_REL_RD, 16 ) );
+ while( pRateDist_Q18[ cur_survivors - 1 ] > rateDistThreshold_Q18 && cur_survivors > min_survivors ) {
+ cur_survivors--;
+ }
+ }
+ /* Update accumulated codebook contributions for the 'cur_survivors' best codebook indices */
+ for( k = 0; k < cur_survivors; k++ ) {
+ if( s > 0 ) {
+ /* Find the indices of the input and the codebook vector */
+ if( pCurrentCBStage->nVectors == 8 ) {
+ input_index = SKP_RSHIFT( pTempIndices[ k ], 3 );
+ cb_index = pTempIndices[ k ] & 7;
+ } else {
+ input_index = SKP_DIV32_16( pTempIndices[ k ], pCurrentCBStage->nVectors );
+ cb_index = pTempIndices[ k ] - SKP_SMULBB( input_index, pCurrentCBStage->nVectors );
+ }
+ } else {
+ /* Find the indices of the input and the codebook vector */
+ input_index = 0;
+ cb_index = pTempIndices[ k ];
+ }
+
+ /* Subtract new contribution from the previous residual vector for each of 'cur_survivors' */
+ pConstInt = &pRes_Q15[ SKP_SMULBB( input_index, LPC_order ) ];
+ pCB_element = &pCurrentCBStage->CB_NLSF_Q15[ SKP_SMULBB( cb_index, LPC_order ) ];
+ pInt = &pRes_new_Q15[ SKP_SMULBB( k, LPC_order ) ];
+ for( i = 0; i < LPC_order; i++ ) {
+ pInt[ i ] = pConstInt[ i ] - ( SKP_int )pCB_element[ i ];
+ }
+
+ /* Update accumulated rate for stage 1 to the current */
+ pRate_new_Q5[ k ] = pRate_Q5[ input_index ] + pCurrentCBStage->Rates_Q5[ cb_index ];
+
+ /* Copy paths from previous matrix, starting with the best path */
+ pConstInt = &pPath[ SKP_SMULBB( input_index, psNLSF_CB->nStages ) ];
+ pInt = &pPath_new[ SKP_SMULBB( k, psNLSF_CB->nStages ) ];
+ for( i = 0; i < s; i++ ) {
+ pInt[ i ] = pConstInt[ i ];
+ }
+ /* Write the current stage indices for the 'cur_survivors' to the best path matrix */
+ pInt[ s ] = cb_index;
+ }
+
+ if( s < psNLSF_CB->nStages - 1 ) {
+ /* Copy NLSF residual matrix for next stage */
+ SKP_memcpy( pRes_Q15, pRes_new_Q15, SKP_SMULBB( cur_survivors, LPC_order ) * sizeof( SKP_int ) );
+
+ /* Copy rate vector for next stage */
+ SKP_memcpy( pRate_Q5, pRate_new_Q5, cur_survivors * sizeof( SKP_int32 ) );
+
+ /* Copy best path matrix for next stage */
+ SKP_memcpy( pPath, pPath_new, SKP_SMULBB( cur_survivors, psNLSF_CB->nStages ) * sizeof( SKP_int ) );
+ }
+
+ prev_survivors = cur_survivors;
+ }
+
+ /* (Preliminary) index of the best survivor, later to be decoded */
+ bestIndex = 0;
+
+#if( NLSF_MSVQ_FLUCTUATION_REDUCTION == 1 )
+ /******************************/
+ /* NLSF fluctuation reduction */
+ /******************************/
+ if( deactivate_fluc_red != 1 ) {
+
+ /* Search among all survivors, now taking also weighted fluctuation errors into account */
+ bestRateDist_Q20 = SKP_int32_MAX;
+ for( s = 0; s < cur_survivors; s++ ) {
+ /* Decode survivor to compare with previous quantized NLSF vector */
+ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, &pPath_new[ SKP_SMULBB( s, psNLSF_CB->nStages ) ], LPC_order );
+
+ /* Compare decoded NLSF vector with the previously quantized vector */
+ wsse_Q20 = 0;
+ for( i = 0; i < LPC_order; i += 2 ) {
+ /* Compute weighted squared quantization error for index i */
+ se_Q15 = pNLSF_Q15[ i ] - pNLSF_q_Q15_prev[ i ]; // range: [ -32767 : 32767 ]
+ wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i ] );
+
+ /* Compute weighted squared quantization error for index i + 1 */
+ se_Q15 = pNLSF_Q15[ i + 1 ] - pNLSF_q_Q15_prev[ i + 1 ]; // range: [ -32767 : 32767 ]
+ wsse_Q20 = SKP_SMLAWB( wsse_Q20, SKP_SMULBB( se_Q15, se_Q15 ), pW_Q6[ i + 1 ] );
+ }
+ SKP_assert( wsse_Q20 >= 0 );
+
+ /* Add the fluctuation reduction penalty to the rate distortion error */
+ wsse_Q20 = SKP_ADD_POS_SAT32( pRateDist_Q18[ s ], SKP_SMULWB( wsse_Q20, NLSF_mu_fluc_red_Q16 ) );
+
+ /* Keep index of best survivor */
+ if( wsse_Q20 < bestRateDist_Q20 ) {
+ bestRateDist_Q20 = wsse_Q20;
+ bestIndex = s;
+ }
+ }
+ }
+#endif
+
+ /* Copy best path to output argument */
+ SKP_memcpy( NLSFIndices, &pPath_new[ SKP_SMULBB( bestIndex, psNLSF_CB->nStages ) ], psNLSF_CB->nStages * sizeof( SKP_int ) );
+
+ /* Decode and stabilize the best survivor */
+ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, LPC_order );
+
+#ifdef USE_UNQUANTIZED_LSFS
+ SKP_memcpy( pNLSF_Q15, NLSF_orig, LPC_order * sizeof( SKP_int ) );
+#endif
+
+}
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c b/pkg/silk/csilk/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c
new file mode 100644
index 0000000..8b5704d
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/* Rate-Distortion calculations for multiple input data vectors */
+void SKP_Silk_NLSF_VQ_rate_distortion_FIX(
+ SKP_int32 *pRD_Q20, /* O Rate-distortion values [psNLSF_CBS->nVectors*N] */
+ const SKP_Silk_NLSF_CBS *psNLSF_CBS, /* I NLSF codebook stage struct */
+ const SKP_int *in_Q15, /* I Input vectors to be quantized */
+ const SKP_int *w_Q6, /* I Weight vector */
+ const SKP_int32 *rate_acc_Q5, /* I Accumulated rates from previous stage */
+ const SKP_int mu_Q15, /* I Weight between weighted error and rate */
+ const SKP_int N, /* I Number of input vectors to be quantized */
+ const SKP_int LPC_order /* I LPC order */
+)
+{
+ SKP_int i, n;
+ SKP_int32 *pRD_vec_Q20;
+
+ /* Compute weighted quantization errors for all input vectors over one codebook stage */
+ SKP_Silk_NLSF_VQ_sum_error_FIX( pRD_Q20, in_Q15, w_Q6, psNLSF_CBS->CB_NLSF_Q15,
+ N, psNLSF_CBS->nVectors, LPC_order );
+
+ /* Loop over input vectors */
+ pRD_vec_Q20 = pRD_Q20;
+ for( n = 0; n < N; n++ ) {
+ /* Add rate cost to error for each codebook vector */
+ for( i = 0; i < psNLSF_CBS->nVectors; i++ ) {
+ SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] >= 0 );
+ SKP_assert( rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ] <= SKP_int16_MAX );
+ pRD_vec_Q20[ i ] = SKP_SMLABB( pRD_vec_Q20[ i ], rate_acc_Q5[ n ] + psNLSF_CBS->Rates_Q5[ i ], mu_Q15 );
+ SKP_assert( pRD_vec_Q20[ i ] >= 0 );
+ }
+ pRD_vec_Q20 += psNLSF_CBS->nVectors;
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF_VQ_sum_error_FIX.c b/pkg/silk/csilk/SKP_Silk_NLSF_VQ_sum_error_FIX.c
new file mode 100644
index 0000000..05d90d0
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF_VQ_sum_error_FIX.c
@@ -0,0 +1,83 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+#if (!defined(__mips__)) && (EMBEDDED_ARM < 6)
+
+/* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */
+void SKP_Silk_NLSF_VQ_sum_error_FIX(
+ SKP_int32 *err_Q20, /* O Weighted quantization errors [N*K] */
+ const SKP_int *in_Q15, /* I Input vectors to be quantized [N*LPC_order] */
+ const SKP_int *w_Q6, /* I Weighting vectors [N*LPC_order] */
+ const SKP_int16 *pCB_Q15, /* I Codebook vectors [K*LPC_order] */
+ const SKP_int N, /* I Number of input vectors */
+ const SKP_int K, /* I Number of codebook vectors */
+ const SKP_int LPC_order /* I Number of LPCs */
+)
+{
+ SKP_int i, n, m;
+ SKP_int32 diff_Q15, sum_error, Wtmp_Q6;
+ SKP_int32 Wcpy_Q6[ MAX_LPC_ORDER / 2 ];
+ const SKP_int16 *cb_vec_Q15;
+
+ SKP_assert( LPC_order <= 16 );
+ SKP_assert( ( LPC_order & 1 ) == 0 );
+
+ /* Copy to local stack and pack two weights per int32 */
+ for( m = 0; m < SKP_RSHIFT( LPC_order, 1 ); m++ ) {
+ Wcpy_Q6[ m ] = w_Q6[ 2 * m ] | SKP_LSHIFT( ( SKP_int32 )w_Q6[ 2 * m + 1 ], 16 );
+ }
+
+ /* Loop over input vectors */
+ for( n = 0; n < N; n++ ) {
+ /* Loop over codebook */
+ cb_vec_Q15 = pCB_Q15;
+ for( i = 0; i < K; i++ ) {
+ sum_error = 0;
+ for( m = 0; m < LPC_order; m += 2 ) {
+ /* Get two weights packed in an int32 */
+ Wtmp_Q6 = Wcpy_Q6[ SKP_RSHIFT( m, 1 ) ];
+
+ /* Compute weighted squared quantization error for index m */
+ diff_Q15 = in_Q15[ m ] - *cb_vec_Q15++; // range: [ -32767 : 32767 ]
+ sum_error = SKP_SMLAWB( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 );
+
+ /* Compute weighted squared quantization error for index m + 1 */
+ diff_Q15 = in_Q15[m + 1] - *cb_vec_Q15++; // range: [ -32767 : 32767 ]
+ sum_error = SKP_SMLAWT( sum_error, SKP_SMULBB( diff_Q15, diff_Q15 ), Wtmp_Q6 );
+ }
+ SKP_assert( sum_error >= 0 );
+ err_Q20[ i ] = sum_error;
+ }
+ err_Q20 += K;
+ in_Q15 += LPC_order;
+ }
+}
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF_VQ_weights_laroia.c b/pkg/silk/csilk/SKP_Silk_NLSF_VQ_weights_laroia.c
new file mode 100644
index 0000000..71c3f23
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF_VQ_weights_laroia.c
@@ -0,0 +1,79 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SigProc_FIX.h"
+
+/*
+R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP
+Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech,
+Signal Processing, pp. 641-644, 1991.
+*/
+
+#define Q_OUT 6
+#define MIN_NDELTA 3
+
+/* Laroia low complexity NLSF weights */
+void SKP_Silk_NLSF_VQ_weights_laroia(
+ SKP_int *pNLSFW_Q6, /* O: Pointer to input vector weights [D x 1] */
+ const SKP_int *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
+ const SKP_int D /* I: Input vector dimension (even) */
+)
+{
+ SKP_int k;
+ SKP_int32 tmp1_int, tmp2_int;
+
+ /* Check that we are guaranteed to end up within the required range */
+ SKP_assert( D > 0 );
+ SKP_assert( ( D & 1 ) == 0 );
+
+ /* First value */
+ tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], MIN_NDELTA );
+ tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
+ tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], MIN_NDELTA );
+ tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
+ pNLSFW_Q6[ 0 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
+ SKP_assert( pNLSFW_Q6[ 0 ] > 0 );
+
+ /* Main loop */
+ for( k = 1; k < D - 1; k += 2 ) {
+ tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], MIN_NDELTA );
+ tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
+ pNLSFW_Q6[ k ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
+ SKP_assert( pNLSFW_Q6[ k ] > 0 );
+
+ tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], MIN_NDELTA );
+ tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
+ pNLSFW_Q6[ k + 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
+ SKP_assert( pNLSFW_Q6[ k + 1 ] > 0 );
+ }
+
+ /* Last value */
+ tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], MIN_NDELTA );
+ tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
+ pNLSFW_Q6[ D - 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
+ SKP_assert( pNLSFW_Q6[ D - 1 ] > 0 );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_NLSF_stabilize.c b/pkg/silk/csilk/SKP_Silk_NLSF_stabilize.c
new file mode 100644
index 0000000..9fc2f61
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NLSF_stabilize.c
@@ -0,0 +1,139 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* NLSF stabilizer: */
+/* */
+/* - Moves NLSFs futher apart if they are too close */
+/* - Moves NLSFs away from borders if they are too close */
+/* - High effort to achieve a modification with minimum */
+/* Euclidean distance to input vector */
+/* - Output are sorted NLSF coefficients */
+/* */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Constant Definitions */
+#define MAX_LOOPS 20
+
+/* NLSF stabilizer, for a single input data vector */
+void SKP_Silk_NLSF_stabilize(
+ SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */
+ const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
+ const SKP_int L /* I: Number of NLSF parameters in the input vector */
+)
+{
+ SKP_int center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15;
+ SKP_int32 min_diff_Q15;
+ SKP_int loops;
+ SKP_int i, I=0, k;
+
+ /* This is necessary to ensure an output within range of a SKP_int16 */
+ SKP_assert( NDeltaMin_Q15[L] >= 1 );
+
+ for( loops = 0; loops < MAX_LOOPS; loops++ ) {
+ /**************************/
+ /* Find smallest distance */
+ /**************************/
+ /* First element */
+ min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
+ I = 0;
+ /* Middle elements */
+ for( i = 1; i <= L-1; i++ ) {
+ diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
+ if( diff_Q15 < min_diff_Q15 ) {
+ min_diff_Q15 = diff_Q15;
+ I = i;
+ }
+ }
+ /* Last element */
+ diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
+ if( diff_Q15 < min_diff_Q15 ) {
+ min_diff_Q15 = diff_Q15;
+ I = L;
+ }
+
+ /***************************************************/
+ /* Now check if the smallest distance non-negative */
+ /***************************************************/
+ if (min_diff_Q15 >= 0) {
+ return;
+ }
+
+ if( I == 0 ) {
+ /* Move away from lower limit */
+ NLSF_Q15[0] = NDeltaMin_Q15[0];
+
+ } else if( I == L) {
+ /* Move away from higher limit */
+ NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L];
+
+ } else {
+ /* Find the lower extreme for the location of the current center frequency */
+ min_center_Q15 = 0;
+ for( k = 0; k < I; k++ ) {
+ min_center_Q15 += NDeltaMin_Q15[k];
+ }
+ min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
+
+ /* Find the upper extreme for the location of the current center frequency */
+ max_center_Q15 = (1<<15);
+ for( k = L; k > I; k-- ) {
+ max_center_Q15 -= NDeltaMin_Q15[k];
+ }
+ max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) );
+
+ /* Move apart, sorted by value, keeping the same center frequency */
+ center_freq_Q15 = SKP_LIMIT_32( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),
+ min_center_Q15, max_center_Q15 );
+ NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
+ NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];
+ }
+ }
+
+ /* Safe and simple fall back method, which is less ideal than the above */
+ if( loops == MAX_LOOPS )
+ {
+ /* Insertion sort (fast for already almost sorted arrays): */
+ /* Best case: O(n) for an already sorted array */
+ /* Worst case: O(n^2) for an inversely sorted array */
+ SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L);
+
+ /* First NLSF should be no less than NDeltaMin[0] */
+ NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
+
+ /* Keep delta_min distance between the NLSFs */
+ for( i = 1; i < L; i++ )
+ NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
+
+ /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
+ NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
+
+ /* Keep NDeltaMin distance between the NLSFs */
+ for( i = L-2; i >= 0; i-- )
+ NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
+ }
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_NSQ.c b/pkg/silk/csilk/SKP_Silk_NSQ.c
new file mode 100644
index 0000000..3655cfe
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NSQ.c
@@ -0,0 +1,454 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+SKP_INLINE void SKP_Silk_nsq_scale_states(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ const SKP_int16 x[], /* I input in Q0 */
+ SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
+ SKP_int subfr_length, /* I length of input */
+ const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */
+ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
+ SKP_int subfr, /* I subframe number */
+ const SKP_int LTP_scale_Q14, /* I */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int pitchL[ NB_SUBFR ] /* I */
+);
+
+SKP_INLINE void SKP_Silk_noise_shape_quantizer(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ SKP_int sigtype, /* I Signal type */
+ const SKP_int32 x_sc_Q10[], /* I */
+ SKP_int8 q[], /* O */
+ SKP_int16 xq[], /* O */
+ SKP_int32 sLTP_Q16[], /* I/O LTP state */
+ const SKP_int16 a_Q12[], /* I Short term prediction coefs */
+ const SKP_int16 b_Q14[], /* I Long term prediction coefs */
+ const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
+ SKP_int lag, /* I Pitch lag */
+ SKP_int32 HarmShapeFIRPacked_Q14, /* I */
+ SKP_int Tilt_Q14, /* I Spectral tilt */
+ SKP_int32 LF_shp_Q14, /* I */
+ SKP_int32 Gain_Q16, /* I */
+ SKP_int Lambda_Q10, /* I */
+ SKP_int offset_Q10, /* I */
+ SKP_int length, /* I Input length */
+ SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */
+ SKP_int predictLPCOrder /* I Prediction filter order */
+);
+
+void SKP_Silk_NSQ(
+ SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
+ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ const SKP_int16 x[], /* I prefiltered input signal */
+ SKP_int8 q[], /* O quantized qulse signal */
+ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
+ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefficients */
+ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I Long term prediction coefficients */
+ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
+ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
+ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
+ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int Lambda_Q10, /* I */
+ const SKP_int LTP_scale_Q14 /* I LTP state scaling */
+)
+{
+ SKP_int k, lag, start_idx, LSF_interpolation_flag;
+ const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
+ SKP_int16 *pxq;
+ SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
+ SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
+ SKP_int32 HarmShapeFIRPacked_Q14;
+ SKP_int offset_Q10;
+ SKP_int32 FiltState[ MAX_LPC_ORDER ];
+ SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
+
+ NSQ->rand_seed = psEncCtrlC->Seed;
+ /* Set unvoiced lag to the previous one, overwrite later for voiced */
+ lag = NSQ->lagPrev;
+
+ SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );
+
+ offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];
+
+ if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {
+ LSF_interpolation_flag = 0;
+ } else {
+ LSF_interpolation_flag = 1;
+ }
+
+ /* Setup pointers to start of sub frame */
+ NSQ->sLTP_shp_buf_idx = psEncC->frame_length;
+ NSQ->sLTP_buf_idx = psEncC->frame_length;
+ pxq = &NSQ->xq[ psEncC->frame_length ];
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
+ B_Q14 = <PCoef_Q14[ k * LTP_ORDER ];
+ AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
+
+ /* Noise shape parameters */
+ SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );
+ HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
+ HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
+
+ NSQ->rewhite_flag = 0;
+ if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
+ /* Voiced */
+ lag = psEncCtrlC->pitchL[ k ];
+
+ /* Re-whitening */
+ if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
+
+ /* Rewhiten with new A coefs */
+ start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
+ SKP_assert( start_idx >= 0 );
+ SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder );
+
+ SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );
+ SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * ( psEncC->frame_length >> 2 ) ],
+ A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );
+
+ NSQ->rewhite_flag = 1;
+ NSQ->sLTP_buf_idx = psEncC->frame_length;
+ }
+ }
+
+ SKP_Silk_nsq_scale_states( NSQ, x, x_sc_Q10, psEncC->subfr_length, sLTP,
+ sLTP_Q16, k, LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );
+
+ SKP_Silk_noise_shape_quantizer( NSQ, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16, A_Q12, B_Q14,
+ AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
+ offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder
+ );
+
+ x += psEncC->subfr_length;
+ q += psEncC->subfr_length;
+ pxq += psEncC->subfr_length;
+ }
+
+ /* Update lagPrev for next frame */
+ NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];
+
+ /* Save quantized speech and noise shaping signals */
+ SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );
+ SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );
+
+#ifdef USE_UNQUANTIZED_LSFS
+ DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) );
+#endif
+
+}
+
+/***********************************/
+/* SKP_Silk_noise_shape_quantizer */
+/***********************************/
+SKP_INLINE void SKP_Silk_noise_shape_quantizer(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ SKP_int sigtype, /* I Signal type */
+ const SKP_int32 x_sc_Q10[], /* I */
+ SKP_int8 q[], /* O */
+ SKP_int16 xq[], /* O */
+ SKP_int32 sLTP_Q16[], /* I/O LTP state */
+ const SKP_int16 a_Q12[], /* I Short term prediction coefs */
+ const SKP_int16 b_Q14[], /* I Long term prediction coefs */
+ const SKP_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
+ SKP_int lag, /* I Pitch lag */
+ SKP_int32 HarmShapeFIRPacked_Q14, /* I */
+ SKP_int Tilt_Q14, /* I Spectral tilt */
+ SKP_int32 LF_shp_Q14, /* I */
+ SKP_int32 Gain_Q16, /* I */
+ SKP_int Lambda_Q10, /* I */
+ SKP_int offset_Q10, /* I */
+ SKP_int length, /* I Input length */
+ SKP_int shapingLPCOrder, /* I Noise shaping AR filter order */
+ SKP_int predictLPCOrder /* I Prediction filter order */
+)
+{
+ SKP_int i, j;
+ SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
+ SKP_int32 n_LF_Q10, r_Q10, q_Q0, q_Q10;
+ SKP_int32 thr1_Q10, thr2_Q10, thr3_Q10;
+ SKP_int32 dither, exc_Q10, LPC_exc_Q10, xq_Q10;
+ SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10;
+ SKP_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 a_Q12_tmp[ MAX_LPC_ORDER / 2 ], Atmp;
+ /* Preload LPC coefficients to array on stack. Gives small performance gain */
+ SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) );
+#endif
+
+ shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
+ pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
+
+ /* Setup short term AR state */
+ psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
+
+ /* Quantization thresholds */
+ thr1_Q10 = SKP_SUB_RSHIFT32( -1536, Lambda_Q10, 1 );
+ thr2_Q10 = SKP_SUB_RSHIFT32( -512, Lambda_Q10, 1 );
+ thr2_Q10 = SKP_ADD_RSHIFT32( thr2_Q10, SKP_SMULBB( offset_Q10, Lambda_Q10 ), 10 );
+ thr3_Q10 = SKP_ADD_RSHIFT32( 512, Lambda_Q10, 1 );
+
+ for( i = 0; i < length; i++ ) {
+ /* Generate dither */
+ NSQ->rand_seed = SKP_RAND( NSQ->rand_seed );
+
+ /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
+ dither = SKP_RSHIFT( NSQ->rand_seed, 31 );
+
+ /* Short-term prediction */
+ SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
+ /* check that array starts at 4-byte aligned address */
+ SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )a_Q12 - ( SKP_int8* )0 ) & 3 ) == 0 );
+ SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
+ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
+ /* loaded in reverse order and the code will give the wrong result. In that case swapping */
+ /* the SMLAWB and SMLAWT instructions should solve the problem. */
+ /* Partially unrolled */
+ Atmp = a_Q12_tmp[ 0 ]; /* read two coefficients at once */
+ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp );
+ Atmp = a_Q12_tmp[ 1 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp );
+ Atmp = a_Q12_tmp[ 2 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp );
+ Atmp = a_Q12_tmp[ 3 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp );
+ Atmp = a_Q12_tmp[ 4 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp );
+ for( j = 10; j < predictLPCOrder; j += 2 ) {
+ Atmp = a_Q12_tmp[ j >> 1 ]; /* read two coefficients at once */
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp );
+ }
+#else
+ /* Partially unrolled */
+ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
+ for( j = 10; j < predictLPCOrder; j ++ ) {
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
+ }
+#endif
+ /* Long-term prediction */
+ if( sigtype == SIG_TYPE_VOICED ) {
+ /* Unrolled loop */
+ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
+ pred_lag_ptr++;
+ } else {
+ LTP_pred_Q14 = 0;
+ }
+
+ /* Noise shape feedback */
+ SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
+ tmp2 = psLPC_Q14[ 0 ];
+ tmp1 = NSQ->sAR2_Q14[ 0 ];
+ NSQ->sAR2_Q14[ 0 ] = tmp2;
+ n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] );
+ for( j = 2; j < shapingLPCOrder; j += 2 ) {
+ tmp2 = NSQ->sAR2_Q14[ j - 1 ];
+ NSQ->sAR2_Q14[ j - 1 ] = tmp1;
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] );
+ tmp1 = NSQ->sAR2_Q14[ j + 0 ];
+ NSQ->sAR2_Q14[ j + 0 ] = tmp2;
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] );
+ }
+ NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
+
+ n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, NSQ->sLF_AR_shp_Q12, Tilt_Q14 );
+
+ n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ), 2 );
+ n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, NSQ->sLF_AR_shp_Q12, LF_shp_Q14 );
+
+ SKP_assert( lag > 0 || sigtype == SIG_TYPE_UNVOICED );
+
+ /* Long-term shaping */
+ if( lag > 0 ) {
+ /* Symmetric, packed FIR coefficients */
+ n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
+ n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
+ n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );
+ shp_lag_ptr++;
+ } else {
+ n_LTP_Q14 = 0;
+ }
+
+ /* Input minus prediction plus noise feedback */
+ //r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP;
+ tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */
+ tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */
+ tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
+ tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
+ tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */
+ r_Q10 = SKP_SUB32( x_sc_Q10[ i ], tmp1 );
+
+ /* Flip sign depending on dither */
+ r_Q10 = ( r_Q10 ^ dither ) - dither;
+ r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );
+ r_Q10 = SKP_LIMIT_32( r_Q10, -(64 << 10), 64 << 10 );
+
+ /* Quantize */
+ q_Q0 = 0;
+ q_Q10 = 0;
+ if( r_Q10 < thr2_Q10 ) {
+ if( r_Q10 < thr1_Q10 ) {
+ q_Q0 = SKP_RSHIFT_ROUND( SKP_ADD_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );
+ q_Q10 = SKP_LSHIFT( q_Q0, 10 );
+ } else {
+ q_Q0 = -1;
+ q_Q10 = -1024;
+ }
+ } else {
+ if( r_Q10 > thr3_Q10 ) {
+ q_Q0 = SKP_RSHIFT_ROUND( SKP_SUB_RSHIFT32( r_Q10, Lambda_Q10, 1 ), 10 );
+ q_Q10 = SKP_LSHIFT( q_Q0, 10 );
+ }
+ }
+ q[ i ] = ( SKP_int8 )q_Q0; /* No saturation needed because max is 64 */
+
+ /* Excitation */
+ exc_Q10 = SKP_ADD32( q_Q10, offset_Q10 );
+ exc_Q10 = ( exc_Q10 ^ dither ) - dither;
+
+ /* Add predictions */
+ LPC_exc_Q10 = SKP_ADD32( exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
+ xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
+
+ /* Scale XQ back to normal level before saving */
+ xq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( xq_Q10, Gain_Q16 ), 10 ) );
+
+
+ /* Update states */
+ psLPC_Q14++;
+ *psLPC_Q14 = SKP_LSHIFT( xq_Q10, 4 );
+ sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
+ NSQ->sLF_AR_shp_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
+
+ NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx ] = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
+ sLTP_Q16[ NSQ->sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 );
+ NSQ->sLTP_shp_buf_idx++;
+ NSQ->sLTP_buf_idx++;
+
+ /* Make dither dependent on quantized signal */
+ NSQ->rand_seed += q[ i ];
+ }
+
+ /* Update LPC synth buffer */
+ SKP_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
+}
+
+SKP_INLINE void SKP_Silk_nsq_scale_states(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ const SKP_int16 x[], /* I input in Q0 */
+ SKP_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
+ SKP_int subfr_length, /* I length of input */
+ const SKP_int16 sLTP[], /* I re-whitened LTP state in Q0 */
+ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
+ SKP_int subfr, /* I subframe number */
+ const SKP_int LTP_scale_Q14, /* I */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int pitchL[ NB_SUBFR ] /* I */
+)
+{
+ SKP_int i, lag;
+ SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
+
+ inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 );
+ inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
+ lag = pitchL[ subfr ];
+
+ /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
+ if( NSQ->rewhite_flag ) {
+ inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
+ if( subfr == 0 ) {
+ /* Do LTP downscaling */
+ inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
+ }
+ for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
+ SKP_assert( i < MAX_FRAME_LENGTH );
+ sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );
+ }
+ }
+
+ /* Adjust for changing gain */
+ if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {
+ gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );
+
+ /* Scale long-term shaping state */
+ for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) {
+ NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );
+ }
+
+ /* Scale long-term prediction state */
+ if( NSQ->rewhite_flag == 0 ) {
+ for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
+ sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
+ }
+ }
+
+ NSQ->sLF_AR_shp_Q12 = SKP_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q12 );
+
+ /* Scale short-term prediction and shaping states */
+ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
+ NSQ->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
+ }
+ for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
+ NSQ->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
+ }
+ }
+
+ /* Scale input */
+ for( i = 0; i < subfr_length; i++ ) {
+ x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );
+ }
+
+ /* save inv_gain */
+ SKP_assert( inv_gain_Q16 != 0 );
+ NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_NSQ_del_dec.c b/pkg/silk/csilk/SKP_Silk_NSQ_del_dec.c
new file mode 100644
index 0000000..16d0b20
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_NSQ_del_dec.c
@@ -0,0 +1,733 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+typedef struct {
+ SKP_int32 RandState[ DECISION_DELAY ];
+ SKP_int32 Q_Q10[ DECISION_DELAY ];
+ SKP_int32 Xq_Q10[ DECISION_DELAY ];
+ SKP_int32 Pred_Q16[ DECISION_DELAY ];
+ SKP_int32 Shape_Q10[ DECISION_DELAY ];
+ SKP_int32 Gain_Q16[ DECISION_DELAY ];
+ SKP_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
+ SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + NSQ_LPC_BUF_LENGTH ];
+ SKP_int32 LF_AR_Q12;
+ SKP_int32 Seed;
+ SKP_int32 SeedInit;
+ SKP_int32 RD_Q10;
+} NSQ_del_dec_struct;
+
+typedef struct {
+ SKP_int32 Q_Q10;
+ SKP_int32 RD_Q10;
+ SKP_int32 xq_Q14;
+ SKP_int32 LF_AR_Q12;
+ SKP_int32 sLTP_shp_Q10;
+ SKP_int32 LPC_exc_Q16;
+} NSQ_sample_struct;
+
+SKP_INLINE void SKP_Silk_copy_del_dec_state(
+ NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */
+ NSQ_del_dec_struct *DD_src, /* I Src del dec state */
+ SKP_int LPC_state_idx /* I Index to LPC buffer */
+);
+
+SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
+ const SKP_int16 x[], /* I Input in Q0 */
+ SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
+ SKP_int subfr_length, /* I Length of input */
+ const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
+ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
+ SKP_int subfr, /* I Subframe number */
+ SKP_int nStatesDelayedDecision, /* I Number of del dec states */
+ SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */
+ const SKP_int LTP_scale_Q14, /* I LTP state scaling */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */
+);
+
+/******************************************/
+/* Noise shape quantizer for one subframe */
+/******************************************/
+SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
+ SKP_int sigtype, /* I Signal type */
+ const SKP_int32 x_Q10[], /* I */
+ SKP_int8 q[], /* O */
+ SKP_int16 xq[], /* O */
+ SKP_int32 sLTP_Q16[], /* I/O LTP filter state */
+ const SKP_int16 a_Q12[], /* I Short term prediction coefs */
+ const SKP_int16 b_Q14[], /* I Long term prediction coefs */
+ const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */
+ SKP_int lag, /* I Pitch lag */
+ SKP_int32 HarmShapeFIRPacked_Q14, /* I */
+ SKP_int Tilt_Q14, /* I Spectral tilt */
+ SKP_int32 LF_shp_Q14, /* I */
+ SKP_int32 Gain_Q16, /* I */
+ SKP_int Lambda_Q10, /* I */
+ SKP_int offset_Q10, /* I */
+ SKP_int length, /* I Input length */
+ SKP_int subfr, /* I Subframe number */
+ SKP_int shapingLPCOrder, /* I Shaping LPC filter order */
+ SKP_int predictLPCOrder, /* I Prediction filter order */
+ SKP_int warping_Q16, /* I */
+ SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */
+ SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */
+ SKP_int decisionDelay /* I */
+);
+
+void SKP_Silk_NSQ_del_dec(
+ SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
+ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ const SKP_int16 x[], /* I Prefiltered input signal */
+ SKP_int8 q[], /* O Quantized pulse signal */
+ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
+ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Prediction coefs */
+ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I LT prediction coefs */
+ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
+ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
+ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
+ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int Lambda_Q10, /* I */
+ const SKP_int LTP_scale_Q14 /* I LTP state scaling */
+)
+{
+ SKP_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
+ SKP_int last_smple_idx, smpl_buf_idx, decisionDelay, subfr_length;
+ const SKP_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
+ SKP_int16 *pxq;
+ SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
+ SKP_int16 sLTP[ 2 * MAX_FRAME_LENGTH ];
+ SKP_int32 HarmShapeFIRPacked_Q14;
+ SKP_int offset_Q10;
+ SKP_int32 FiltState[ MAX_LPC_ORDER ], RDmin_Q10;
+ SKP_int32 x_sc_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
+ NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ];
+ NSQ_del_dec_struct *psDD;
+
+ subfr_length = psEncC->frame_length / NB_SUBFR;
+
+ /* Set unvoiced lag to the previous one, overwrite later for voiced */
+ lag = NSQ->lagPrev;
+
+ SKP_assert( NSQ->prev_inv_gain_Q16 != 0 );
+
+ /* Initialize delayed decision states */
+ SKP_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
+ for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
+ psDD = &psDelDec[ k ];
+ psDD->Seed = ( k + psEncCtrlC->Seed ) & 3;
+ psDD->SeedInit = psDD->Seed;
+ psDD->RD_Q10 = 0;
+ psDD->LF_AR_Q12 = NSQ->sLF_AR_shp_Q12;
+ psDD->Shape_Q10[ 0 ] = NSQ->sLTP_shp_Q10[ psEncC->frame_length - 1 ];
+ SKP_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
+ SKP_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
+ }
+
+ offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrlC->sigtype ][ psEncCtrlC->QuantOffsetType ];
+ smpl_buf_idx = 0; /* index of oldest samples */
+
+ decisionDelay = SKP_min_int( DECISION_DELAY, subfr_length );
+
+ /* For voiced frames limit the decision delay to lower than the pitch lag */
+ if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ decisionDelay = SKP_min_int( decisionDelay, psEncCtrlC->pitchL[ k ] - LTP_ORDER / 2 - 1 );
+ }
+ } else {
+ if( lag > 0 ) {
+ decisionDelay = SKP_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
+ }
+ }
+
+ if( LSFInterpFactor_Q2 == ( 1 << 2 ) ) {
+ LSF_interpolation_flag = 0;
+ } else {
+ LSF_interpolation_flag = 1;
+ }
+
+ /* Setup pointers to start of sub frame */
+ pxq = &NSQ->xq[ psEncC->frame_length ];
+ NSQ->sLTP_shp_buf_idx = psEncC->frame_length;
+ NSQ->sLTP_buf_idx = psEncC->frame_length;
+ subfr = 0;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
+ B_Q14 = <PCoef_Q14[ k * LTP_ORDER ];
+ AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
+
+ /* Noise shape parameters */
+ SKP_assert( HarmShapeGain_Q14[ k ] >= 0 );
+ HarmShapeFIRPacked_Q14 = SKP_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
+ HarmShapeFIRPacked_Q14 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
+
+ NSQ->rewhite_flag = 0;
+ if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
+ /* Voiced */
+ lag = psEncCtrlC->pitchL[ k ];
+
+ /* Re-whitening */
+ if( ( k & ( 3 - SKP_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
+ if( k == 2 ) {
+ /* RESET DELAYED DECISIONS */
+ /* Find winner */
+ RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
+ Winner_ind = 0;
+ for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
+ if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
+ RDmin_Q10 = psDelDec[ i ].RD_Q10;
+ Winner_ind = i;
+ }
+ }
+ for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
+ if( i != Winner_ind ) {
+ psDelDec[ i ].RD_Q10 += ( SKP_int32_MAX >> 4 );
+ SKP_assert( psDelDec[ i ].RD_Q10 >= 0 );
+ }
+ }
+
+ /* Copy final part of signals from winner state to output and long-term filter states */
+ psDD = &psDelDec[ Winner_ind ];
+ last_smple_idx = smpl_buf_idx + decisionDelay;
+ for( i = 0; i < decisionDelay; i++ ) {
+ last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
+ q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
+ pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
+ SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ],
+ psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
+ NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
+ }
+
+ subfr = 0;
+ }
+
+ /* Rewhiten with new A coefs */
+ start_idx = psEncC->frame_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
+ SKP_assert( start_idx >= 0 );
+ SKP_assert( start_idx <= psEncC->frame_length - psEncC->predictLPCOrder );
+
+ SKP_memset( FiltState, 0, psEncC->predictLPCOrder * sizeof( SKP_int32 ) );
+ SKP_Silk_MA_Prediction( &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
+ A_Q12, FiltState, sLTP + start_idx, psEncC->frame_length - start_idx, psEncC->predictLPCOrder );
+
+ NSQ->sLTP_buf_idx = psEncC->frame_length;
+ NSQ->rewhite_flag = 1;
+ }
+ }
+
+ SKP_Silk_nsq_del_dec_scale_states( NSQ, psDelDec, x, x_sc_Q10,
+ subfr_length, sLTP, sLTP_Q16, k, psEncC->nStatesDelayedDecision, smpl_buf_idx,
+ LTP_scale_Q14, Gains_Q16, psEncCtrlC->pitchL );
+
+ SKP_Silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psEncCtrlC->sigtype, x_sc_Q10, q, pxq, sLTP_Q16,
+ A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ],
+ Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder,
+ psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
+
+ x += psEncC->subfr_length;
+ q += psEncC->subfr_length;
+ pxq += psEncC->subfr_length;
+ }
+
+ /* Find winner */
+ RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
+ Winner_ind = 0;
+ for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
+ if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
+ RDmin_Q10 = psDelDec[ k ].RD_Q10;
+ Winner_ind = k;
+ }
+ }
+
+ /* Copy final part of signals from winner state to output and long-term filter states */
+ psDD = &psDelDec[ Winner_ind ];
+ psEncCtrlC->Seed = psDD->SeedInit;
+ last_smple_idx = smpl_buf_idx + decisionDelay;
+ for( i = 0; i < decisionDelay; i++ ) {
+ last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
+ q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
+ pxq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
+ SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
+ NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q10[ last_smple_idx ];
+ sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay + i ] = psDD->Pred_Q16[ last_smple_idx ];
+ }
+ SKP_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
+ SKP_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
+
+ /* Update states */
+ NSQ->sLF_AR_shp_Q12 = psDD->LF_AR_Q12;
+ NSQ->lagPrev = psEncCtrlC->pitchL[ NB_SUBFR - 1 ];
+
+ /* Save quantized speech and noise shaping signals */
+ SKP_memcpy( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int16 ) );
+ SKP_memcpy( NSQ->sLTP_shp_Q10, &NSQ->sLTP_shp_Q10[ psEncC->frame_length ], psEncC->frame_length * sizeof( SKP_int32 ) );
+
+#ifdef USE_UNQUANTIZED_LSFS
+ DEBUG_STORE_DATA( xq_unq_lsfs.pcm, NSQ->xq, psEncC->frame_length * sizeof( SKP_int16 ) );
+#endif
+
+}
+
+/******************************************/
+/* Noise shape quantizer for one subframe */
+/******************************************/
+SKP_INLINE void SKP_Silk_noise_shape_quantizer_del_dec(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
+ SKP_int sigtype, /* I Signal type */
+ const SKP_int32 x_Q10[], /* I */
+ SKP_int8 q[], /* O */
+ SKP_int16 xq[], /* O */
+ SKP_int32 sLTP_Q16[], /* I/O LTP filter state */
+ const SKP_int16 a_Q12[], /* I Short term prediction coefs */
+ const SKP_int16 b_Q14[], /* I Long term prediction coefs */
+ const SKP_int16 AR_shp_Q13[], /* I Noise shaping coefs */
+ SKP_int lag, /* I Pitch lag */
+ SKP_int32 HarmShapeFIRPacked_Q14, /* I */
+ SKP_int Tilt_Q14, /* I Spectral tilt */
+ SKP_int32 LF_shp_Q14, /* I */
+ SKP_int32 Gain_Q16, /* I */
+ SKP_int Lambda_Q10, /* I */
+ SKP_int offset_Q10, /* I */
+ SKP_int length, /* I Input length */
+ SKP_int subfr, /* I Subframe number */
+ SKP_int shapingLPCOrder, /* I Shaping LPC filter order */
+ SKP_int predictLPCOrder, /* I Prediction filter order */
+ SKP_int warping_Q16, /* I */
+ SKP_int nStatesDelayedDecision, /* I Number of states in decision tree */
+ SKP_int *smpl_buf_idx, /* I Index to newest samples in buffers */
+ SKP_int decisionDelay /* I */
+)
+{
+ SKP_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
+ SKP_int32 Winner_rand_state;
+ SKP_int32 LTP_pred_Q14, LPC_pred_Q10, n_AR_Q10, n_LTP_Q14;
+ SKP_int32 n_LF_Q10, r_Q10, rr_Q20, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
+ SKP_int32 q1_Q10, q2_Q10, dither, exc_Q10, LPC_exc_Q10, xq_Q10;
+ SKP_int32 tmp1, tmp2, sLF_AR_shp_Q10;
+ SKP_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
+ NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
+ NSQ_del_dec_struct *psDD;
+ NSQ_sample_struct *psSS;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 a_Q12_tmp[ MAX_LPC_ORDER / 2 ], Atmp;
+
+ /* Preload LPC coeficients to array on stack. Gives small performance gain */
+ SKP_memcpy( a_Q12_tmp, a_Q12, predictLPCOrder * sizeof( SKP_int16 ) );
+#endif
+
+ shp_lag_ptr = &NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
+ pred_lag_ptr = &sLTP_Q16[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
+
+ for( i = 0; i < length; i++ ) {
+ /* Perform common calculations used in all states */
+
+ /* Long-term prediction */
+ if( sigtype == SIG_TYPE_VOICED ) {
+ /* Unrolled loop */
+ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
+ pred_lag_ptr++;
+ } else {
+ LTP_pred_Q14 = 0;
+ }
+
+ /* Long-term shaping */
+ if( lag > 0 ) {
+ /* Symmetric, packed FIR coefficients */
+ n_LTP_Q14 = SKP_SMULWB( SKP_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
+ n_LTP_Q14 = SKP_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
+ n_LTP_Q14 = SKP_LSHIFT( n_LTP_Q14, 6 );
+ shp_lag_ptr++;
+ } else {
+ n_LTP_Q14 = 0;
+ }
+
+ for( k = 0; k < nStatesDelayedDecision; k++ ) {
+ /* Delayed decision state */
+ psDD = &psDelDec[ k ];
+
+ /* Sample state */
+ psSS = psSampleState[ k ];
+
+ /* Generate dither */
+ psDD->Seed = SKP_RAND( psDD->Seed );
+
+ /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
+ dither = SKP_RSHIFT( psDD->Seed, 31 );
+
+ /* Pointer used in short term prediction and shaping */
+ psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
+ /* Short-term prediction */
+ SKP_assert( predictLPCOrder >= 10 ); /* check that unrolling works */
+ SKP_assert( ( predictLPCOrder & 1 ) == 0 ); /* check that order is even */
+ SKP_assert( ( ( ( int )( ( char* )( a_Q12 ) - ( ( char* ) 0 ) ) ) & 3 ) == 0 ); /* check that array starts at 4-byte aligned address */
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* Partially unrolled */
+ Atmp = a_Q12_tmp[ 0 ]; /* read two coefficients at once */
+ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -1 ], Atmp );
+ Atmp = a_Q12_tmp[ 1 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -3 ], Atmp );
+ Atmp = a_Q12_tmp[ 2 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -5 ], Atmp );
+ Atmp = a_Q12_tmp[ 3 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -7 ], Atmp );
+ Atmp = a_Q12_tmp[ 4 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -9 ], Atmp );
+ for( j = 10; j < predictLPCOrder; j += 2 ) {
+ Atmp = a_Q12_tmp[ j >> 1 ]; /* read two coefficients at once */
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psLPC_Q14[ -j - 1 ], Atmp );
+ }
+#else
+ /* Partially unrolled */
+ LPC_pred_Q10 = SKP_SMULWB( psLPC_Q14[ 0 ], a_Q12[ 0 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
+ for( j = 10; j < predictLPCOrder; j ++ ) {
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -j ], a_Q12[ j ] );
+ }
+#endif
+
+ /* Noise shape feedback */
+ SKP_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
+ /* Output of lowpass section */
+ tmp2 = SKP_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
+ /* Output of allpass section */
+ tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
+ psDD->sAR2_Q14[ 0 ] = tmp2;
+ n_AR_Q10 = SKP_SMULWB( tmp2, AR_shp_Q13[ 0 ] );
+ /* Loop over allpass sections */
+ for( j = 2; j < shapingLPCOrder; j += 2 ) {
+ /* Output of allpass section */
+ tmp2 = SKP_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
+ psDD->sAR2_Q14[ j - 1 ] = tmp1;
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ j - 1 ] );
+ /* Output of allpass section */
+ tmp1 = SKP_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
+ psDD->sAR2_Q14[ j + 0 ] = tmp2;
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp2, AR_shp_Q13[ j ] );
+ }
+ psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
+
+ n_AR_Q10 = SKP_RSHIFT( n_AR_Q10, 1 ); /* Q11 -> Q10 */
+ n_AR_Q10 = SKP_SMLAWB( n_AR_Q10, psDD->LF_AR_Q12, Tilt_Q14 );
+
+ n_LF_Q10 = SKP_LSHIFT( SKP_SMULWB( psDD->Shape_Q10[ *smpl_buf_idx ], LF_shp_Q14 ), 2 );
+ n_LF_Q10 = SKP_SMLAWT( n_LF_Q10, psDD->LF_AR_Q12, LF_shp_Q14 );
+
+ /* Input minus prediction plus noise feedback */
+ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
+ tmp1 = SKP_SUB32( LTP_pred_Q14, n_LTP_Q14 ); /* Add Q14 stuff */
+ tmp1 = SKP_RSHIFT( tmp1, 4 ); /* convert to Q10 */
+ tmp1 = SKP_ADD32( tmp1, LPC_pred_Q10 ); /* add Q10 stuff */
+ tmp1 = SKP_SUB32( tmp1, n_AR_Q10 ); /* subtract Q10 stuff */
+ tmp1 = SKP_SUB32( tmp1, n_LF_Q10 ); /* subtract Q10 stuff */
+ r_Q10 = SKP_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
+
+ /* Flip sign depending on dither */
+ r_Q10 = ( r_Q10 ^ dither ) - dither;
+ r_Q10 = SKP_SUB32( r_Q10, offset_Q10 );
+ r_Q10 = SKP_LIMIT_32( r_Q10, -(64 << 10), 64 << 10 );
+
+ /* Find two quantization level candidates and measure their rate-distortion */
+ if( r_Q10 < -1536 ) {
+ q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );
+ r_Q10 = SKP_SUB32( r_Q10, q1_Q10 );
+ rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( -SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );
+ rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );
+ rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );
+ q2_Q10 = SKP_ADD32( q1_Q10, 1024 );
+ } else if( r_Q10 > 512 ) {
+ q1_Q10 = SKP_LSHIFT( SKP_RSHIFT_ROUND( r_Q10, 10 ), 10 );
+ r_Q10 = SKP_SUB32( r_Q10, q1_Q10 );
+ rd1_Q10 = SKP_RSHIFT( SKP_SMLABB( SKP_MUL( SKP_ADD32( q1_Q10, offset_Q10 ), Lambda_Q10 ), r_Q10, r_Q10 ), 10 );
+ rd2_Q10 = SKP_ADD32( rd1_Q10, 1024 );
+ rd2_Q10 = SKP_SUB32( rd2_Q10, SKP_SUB_LSHIFT32( Lambda_Q10, r_Q10, 1 ) );
+ q2_Q10 = SKP_SUB32( q1_Q10, 1024 );
+ } else { /* r_Q10 >= -1536 && q1_Q10 <= 512 */
+ rr_Q20 = SKP_SMULBB( offset_Q10, Lambda_Q10 );
+ rd2_Q10 = SKP_RSHIFT( SKP_SMLABB( rr_Q20, r_Q10, r_Q10 ), 10 );
+ rd1_Q10 = SKP_ADD32( rd2_Q10, 1024 );
+ rd1_Q10 = SKP_ADD32( rd1_Q10, SKP_SUB_RSHIFT32( SKP_ADD_LSHIFT32( Lambda_Q10, r_Q10, 1 ), rr_Q20, 9 ) );
+ q1_Q10 = -1024;
+ q2_Q10 = 0;
+ }
+
+ if( rd1_Q10 < rd2_Q10 ) {
+ psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 );
+ psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );
+ psSS[ 0 ].Q_Q10 = q1_Q10;
+ psSS[ 1 ].Q_Q10 = q2_Q10;
+ } else {
+ psSS[ 0 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd2_Q10 );
+ psSS[ 1 ].RD_Q10 = SKP_ADD32( psDD->RD_Q10, rd1_Q10 );
+ psSS[ 0 ].Q_Q10 = q2_Q10;
+ psSS[ 1 ].Q_Q10 = q1_Q10;
+ }
+
+ /* Update states for best quantization */
+
+ /* Quantized excitation */
+ exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 0 ].Q_Q10 );
+ exc_Q10 = ( exc_Q10 ^ dither ) - dither;
+
+ /* Add predictions */
+ LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );
+ xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
+
+ /* Update states */
+ sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
+ psSS[ 0 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
+ psSS[ 0 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
+ psSS[ 0 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 );
+ psSS[ 0 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 );
+
+ /* Update states for second best quantization */
+
+ /* Quantized excitation */
+ exc_Q10 = SKP_ADD32( offset_Q10, psSS[ 1 ].Q_Q10 );
+ exc_Q10 = ( exc_Q10 ^ dither ) - dither;
+
+ /* Add predictions */
+ LPC_exc_Q10 = exc_Q10 + SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 );
+ xq_Q10 = SKP_ADD32( LPC_exc_Q10, LPC_pred_Q10 );
+
+ /* Update states */
+ sLF_AR_shp_Q10 = SKP_SUB32( xq_Q10, n_AR_Q10 );
+ psSS[ 1 ].sLTP_shp_Q10 = SKP_SUB32( sLF_AR_shp_Q10, n_LF_Q10 );
+ psSS[ 1 ].LF_AR_Q12 = SKP_LSHIFT( sLF_AR_shp_Q10, 2 );
+ psSS[ 1 ].xq_Q14 = SKP_LSHIFT( xq_Q10, 4 );
+ psSS[ 1 ].LPC_exc_Q16 = SKP_LSHIFT( LPC_exc_Q10, 6 );
+ }
+
+ *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
+ last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
+
+ /* Find winner */
+ RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
+ Winner_ind = 0;
+ for( k = 1; k < nStatesDelayedDecision; k++ ) {
+ if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
+ RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
+ Winner_ind = k;
+ }
+ }
+
+ /* Increase RD values of expired states */
+ Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
+ for( k = 0; k < nStatesDelayedDecision; k++ ) {
+ if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
+ psSampleState[ k ][ 0 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 0 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );
+ psSampleState[ k ][ 1 ].RD_Q10 = SKP_ADD32( psSampleState[ k ][ 1 ].RD_Q10, ( SKP_int32_MAX >> 4 ) );
+ SKP_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
+ }
+ }
+
+ /* Find worst in first set and best in second set */
+ RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
+ RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
+ RDmax_ind = 0;
+ RDmin_ind = 0;
+ for( k = 1; k < nStatesDelayedDecision; k++ ) {
+ /* find worst in first set */
+ if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
+ RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
+ RDmax_ind = k;
+ }
+ /* find best in second set */
+ if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
+ RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
+ RDmin_ind = k;
+ }
+ }
+
+ /* Replace a state if best from second set outperforms worst in first set */
+ if( RDmin_Q10 < RDmax_Q10 ) {
+ SKP_Silk_copy_del_dec_state( &psDelDec[ RDmax_ind ], &psDelDec[ RDmin_ind ], i );
+ SKP_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
+ }
+
+ /* Write samples from winner to output and long-term filter states */
+ psDD = &psDelDec[ Winner_ind ];
+ if( subfr > 0 || i >= decisionDelay ) {
+ q[ i - decisionDelay ] = ( SKP_int8 )SKP_RSHIFT( psDD->Q_Q10[ last_smple_idx ], 10 );
+ xq[ i - decisionDelay ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND(
+ SKP_SMULWW( psDD->Xq_Q10[ last_smple_idx ], psDD->Gain_Q16[ last_smple_idx ] ), 10 ) );
+ NSQ->sLTP_shp_Q10[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q10[ last_smple_idx ];
+ sLTP_Q16[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q16[ last_smple_idx ];
+ }
+ NSQ->sLTP_shp_buf_idx++;
+ NSQ->sLTP_buf_idx++;
+
+ /* Update states */
+ for( k = 0; k < nStatesDelayedDecision; k++ ) {
+ psDD = &psDelDec[ k ];
+ psSS = &psSampleState[ k ][ 0 ];
+ psDD->LF_AR_Q12 = psSS->LF_AR_Q12;
+ psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
+ psDD->Xq_Q10[ *smpl_buf_idx ] = SKP_RSHIFT( psSS->xq_Q14, 4 );
+ psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
+ psDD->Pred_Q16[ *smpl_buf_idx ] = psSS->LPC_exc_Q16;
+ psDD->Shape_Q10[ *smpl_buf_idx ] = psSS->sLTP_shp_Q10;
+ psDD->Seed = SKP_ADD_RSHIFT32( psDD->Seed, psSS->Q_Q10, 10 );
+ psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
+ psDD->RD_Q10 = psSS->RD_Q10;
+ psDD->Gain_Q16[ *smpl_buf_idx ] = Gain_Q16;
+ }
+ }
+ /* Update LPC states */
+ for( k = 0; k < nStatesDelayedDecision; k++ ) {
+ psDD = &psDelDec[ k ];
+ SKP_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
+ }
+}
+
+SKP_INLINE void SKP_Silk_nsq_del_dec_scale_states(
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
+ const SKP_int16 x[], /* I Input in Q0 */
+ SKP_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
+ SKP_int subfr_length, /* I Length of input */
+ const SKP_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
+ SKP_int32 sLTP_Q16[], /* O LTP state matching scaled input */
+ SKP_int subfr, /* I Subframe number */
+ SKP_int nStatesDelayedDecision, /* I Number of del dec states */
+ SKP_int smpl_buf_idx, /* I Index to newest samples in buffers */
+ const SKP_int LTP_scale_Q14, /* I LTP state scaling */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int pitchL[ NB_SUBFR ] /* I Pitch lag */
+)
+{
+ SKP_int i, k, lag;
+ SKP_int32 inv_gain_Q16, gain_adj_Q16, inv_gain_Q32;
+ NSQ_del_dec_struct *psDD;
+
+ inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gains_Q16[ subfr ], 1 ), 32 );
+ inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
+ lag = pitchL[ subfr ];
+
+ /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
+ if( NSQ->rewhite_flag ) {
+ inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
+ if( subfr == 0 ) {
+ /* Do LTP downscaling */
+ inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, LTP_scale_Q14 ), 2 );
+ }
+ for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
+ SKP_assert( i < MAX_FRAME_LENGTH );
+ sLTP_Q16[ i ] = SKP_SMULWB( inv_gain_Q32, sLTP[ i ] );
+ }
+ }
+
+ /* Adjust for changing gain */
+ if( inv_gain_Q16 != NSQ->prev_inv_gain_Q16 ) {
+ gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, NSQ->prev_inv_gain_Q16, 16 );
+
+ /* Scale long-term shaping state */
+ for( i = NSQ->sLTP_shp_buf_idx - subfr_length * NB_SUBFR; i < NSQ->sLTP_shp_buf_idx; i++ ) {
+ NSQ->sLTP_shp_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q10[ i ] );
+ }
+
+ /* Scale long-term prediction state */
+ if( NSQ->rewhite_flag == 0 ) {
+ for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
+ sLTP_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, sLTP_Q16[ i ] );
+ }
+ }
+
+ for( k = 0; k < nStatesDelayedDecision; k++ ) {
+ psDD = &psDelDec[ k ];
+
+ /* Scale scalar states */
+ psDD->LF_AR_Q12 = SKP_SMULWW( gain_adj_Q16, psDD->LF_AR_Q12 );
+
+ /* Scale short-term prediction and shaping states */
+ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
+ psDD->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
+ }
+ for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
+ psDD->sAR2_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
+ }
+ for( i = 0; i < DECISION_DELAY; i++ ) {
+ psDD->Pred_Q16[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Pred_Q16[ i ] );
+ psDD->Shape_Q10[ i ] = SKP_SMULWW( gain_adj_Q16, psDD->Shape_Q10[ i ] );
+ }
+ }
+ }
+
+ /* Scale input */
+ for( i = 0; i < subfr_length; i++ ) {
+ x_sc_Q10[ i ] = SKP_RSHIFT( SKP_SMULBB( x[ i ], ( SKP_int16 )inv_gain_Q16 ), 6 );
+ }
+
+ /* save inv_gain */
+ SKP_assert( inv_gain_Q16 != 0 );
+ NSQ->prev_inv_gain_Q16 = inv_gain_Q16;
+}
+
+SKP_INLINE void SKP_Silk_copy_del_dec_state(
+ NSQ_del_dec_struct *DD_dst, /* I Dst del dec state */
+ NSQ_del_dec_struct *DD_src, /* I Src del dec state */
+ SKP_int LPC_state_idx /* I Index to LPC buffer */
+)
+{
+ SKP_memcpy( DD_dst->RandState, DD_src->RandState, sizeof( DD_src->RandState ) );
+ SKP_memcpy( DD_dst->Q_Q10, DD_src->Q_Q10, sizeof( DD_src->Q_Q10 ) );
+ SKP_memcpy( DD_dst->Pred_Q16, DD_src->Pred_Q16, sizeof( DD_src->Pred_Q16 ) );
+ SKP_memcpy( DD_dst->Shape_Q10, DD_src->Shape_Q10, sizeof( DD_src->Shape_Q10 ) );
+ SKP_memcpy( DD_dst->Xq_Q10, DD_src->Xq_Q10, sizeof( DD_src->Xq_Q10 ) );
+ SKP_memcpy( DD_dst->sAR2_Q14, DD_src->sAR2_Q14, sizeof( DD_src->sAR2_Q14 ) );
+ SKP_memcpy( &DD_dst->sLPC_Q14[ LPC_state_idx ], &DD_src->sLPC_Q14[ LPC_state_idx ], NSQ_LPC_BUF_LENGTH * sizeof( SKP_int32 ) );
+ DD_dst->LF_AR_Q12 = DD_src->LF_AR_Q12;
+ DD_dst->Seed = DD_src->Seed;
+ DD_dst->SeedInit = DD_src->SeedInit;
+ DD_dst->RD_Q10 = DD_src->RD_Q10;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_PLC.c b/pkg/silk/csilk/SKP_Silk_PLC.c
new file mode 100644
index 0000000..8058610
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_PLC.c
@@ -0,0 +1,418 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+#include "SKP_Silk_PLC.h"
+
+#define NB_ATT 2
+static const SKP_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */
+static const SKP_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */
+static const SKP_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */
+
+void SKP_Silk_PLC_Reset(
+ SKP_Silk_decoder_state *psDec /* I/O Decoder state */
+)
+{
+ psDec->sPLC.pitchL_Q8 = SKP_RSHIFT( psDec->frame_length, 1 );
+}
+
+void SKP_Silk_PLC(
+ SKP_Silk_decoder_state *psDec, /* I Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
+ SKP_int16 signal[], /* O Concealed signal */
+ SKP_int length, /* I length of residual */
+ SKP_int lost /* I Loss flag */
+)
+{
+ /* PLC control function */
+ if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) {
+ SKP_Silk_PLC_Reset( psDec );
+ psDec->sPLC.fs_kHz = psDec->fs_kHz;
+ }
+
+ if( lost ) {
+ /****************************/
+ /* Generate Signal */
+ /****************************/
+ SKP_Silk_PLC_conceal( psDec, psDecCtrl, signal, length );
+
+ psDec->lossCnt++;
+ } else {
+ /****************************/
+ /* Update state */
+ /****************************/
+ SKP_Silk_PLC_update( psDec, psDecCtrl, signal, length );
+ }
+}
+
+/**************************************************/
+/* Update state of PLC */
+/**************************************************/
+void SKP_Silk_PLC_update(
+ SKP_Silk_decoder_state *psDec, /* (I/O) Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* (I/O) Decoder control */
+ SKP_int16 signal[],
+ SKP_int length
+)
+{
+ SKP_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14;
+ SKP_int i, j;
+ SKP_Silk_PLC_struct *psPLC;
+
+ psPLC = &psDec->sPLC;
+
+ /* Update parameters used in case of packet loss */
+ psDec->prev_sigtype = psDecCtrl->sigtype;
+ LTP_Gain_Q14 = 0;
+ if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) {
+ /* Find the parameters for the last subframe which contains a pitch pulse */
+ for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ NB_SUBFR - 1 ]; j++ ) {
+ temp_LTP_Gain_Q14 = 0;
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( NB_SUBFR - 1 - j ) * LTP_ORDER + i ];
+ }
+ if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) {
+ LTP_Gain_Q14 = temp_LTP_Gain_Q14;
+ SKP_memcpy( psPLC->LTPCoef_Q14,
+ &psDecCtrl->LTPCoef_Q14[ SKP_SMULBB( NB_SUBFR - 1 - j, LTP_ORDER ) ],
+ LTP_ORDER * sizeof( SKP_int16 ) );
+
+ psPLC->pitchL_Q8 = SKP_LSHIFT( psDecCtrl->pitchL[ NB_SUBFR - 1 - j ], 8 );
+ }
+ }
+
+#if USE_SINGLE_TAP
+ SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) );
+ psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14;
+#endif
+
+ /* Limit LT coefs */
+ if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) {
+ SKP_int scale_Q10;
+ SKP_int32 tmp;
+
+ tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 );
+ scale_Q10 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) );
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 );
+ }
+ } else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) {
+ SKP_int scale_Q14;
+ SKP_int32 tmp;
+
+ tmp = SKP_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 );
+ scale_Q14 = SKP_DIV32( tmp, SKP_max( LTP_Gain_Q14, 1 ) );
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ psPLC->LTPCoef_Q14[ i ] = SKP_RSHIFT( SKP_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 );
+ }
+ }
+ } else {
+ psPLC->pitchL_Q8 = SKP_LSHIFT( SKP_SMULBB( psDec->fs_kHz, 18 ), 8 );
+ SKP_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ));
+ }
+
+ /* Save LPC coeficients */
+ SKP_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( SKP_int16 ) );
+ psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14;
+
+ /* Save Gains */
+ SKP_memcpy( psPLC->prevGain_Q16, psDecCtrl->Gains_Q16, NB_SUBFR * sizeof( SKP_int32 ) );
+}
+
+void SKP_Silk_PLC_conceal(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[], /* O concealed signal */
+ SKP_int length /* I length of residual */
+)
+{
+ SKP_int i, j, k;
+ SKP_int16 *B_Q14, exc_buf[ MAX_FRAME_LENGTH ], *exc_buf_ptr;
+ SKP_int16 rand_scale_Q14;
+ union {
+ SKP_int16 as_int16[ MAX_LPC_ORDER ];
+ SKP_int32 as_int32[ MAX_LPC_ORDER / 2 ];
+ } A_Q12_tmp;
+ SKP_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15;
+ SKP_int lag, idx, sLTP_buf_idx, shift1, shift2;
+ SKP_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr;
+ SKP_int32 sig_Q10[ MAX_FRAME_LENGTH ], *sig_Q10_ptr, LPC_exc_Q10, LPC_pred_Q10, LTP_pred_Q14;
+ SKP_Silk_PLC_struct *psPLC;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 Atmp;
+#endif
+ psPLC = &psDec->sPLC;
+
+ /* Update LTP buffer */
+ SKP_memcpy( psDec->sLTP_Q16, &psDec->sLTP_Q16[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int32 ) );
+
+ /* LPC concealment. Apply BWE to previous LPC */
+ SKP_Silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, BWE_COEF_Q16 );
+
+ /* Find random noise component */
+ /* Scale previous excitation signal */
+ exc_buf_ptr = exc_buf;
+ for( k = ( NB_SUBFR >> 1 ); k < NB_SUBFR; k++ ) {
+ for( i = 0; i < psDec->subfr_length; i++ ) {
+ exc_buf_ptr[ i ] = ( SKP_int16 )SKP_RSHIFT(
+ SKP_SMULWW( psDec->exc_Q10[ i + k * psDec->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
+ }
+ exc_buf_ptr += psDec->subfr_length;
+ }
+ /* Find the subframe with lowest energy of the last two and use that as random noise generator */
+ SKP_Silk_sum_sqr_shift( &energy1, &shift1, exc_buf, psDec->subfr_length );
+ SKP_Silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psDec->subfr_length ], psDec->subfr_length );
+
+ if( SKP_RSHIFT( energy1, shift2 ) < SKP_RSHIFT( energy2, shift1 ) ) {
+ /* First sub-frame has lowest energy */
+ rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, 3 * psDec->subfr_length - RAND_BUF_SIZE ) ];
+ } else {
+ /* Second sub-frame has lowest energy */
+ rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, psDec->frame_length - RAND_BUF_SIZE ) ];
+ }
+
+ /* Setup Gain to random noise component */
+ B_Q14 = psPLC->LTPCoef_Q14;
+ rand_scale_Q14 = psPLC->randScale_Q14;
+
+ /* Setup attenuation gains */
+ harm_Gain_Q15 = HARM_ATT_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
+ if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
+ rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
+ } else {
+ rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
+ }
+
+ /* First Lost frame */
+ if( psDec->lossCnt == 0 ) {
+ rand_scale_Q14 = (1 << 14 );
+
+ /* Reduce random noise Gain for voiced frames */
+ if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ rand_scale_Q14 -= B_Q14[ i ];
+ }
+ rand_scale_Q14 = SKP_max_16( 3277, rand_scale_Q14 ); /* 0.2 */
+ rand_scale_Q14 = ( SKP_int16 )SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );
+ }
+
+ /* Reduce random noise for unvoiced frames with high LPC gain */
+ if( psDec->prev_sigtype == SIG_TYPE_UNVOICED ) {
+ SKP_int32 invGain_Q30, down_scale_Q30;
+
+ SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, psPLC->prevLPC_Q12, psDec->LPC_order );
+
+ down_scale_Q30 = SKP_min_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
+ down_scale_Q30 = SKP_max_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
+ down_scale_Q30 = SKP_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES );
+
+ rand_Gain_Q15 = SKP_RSHIFT( SKP_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 );
+ }
+ }
+
+ rand_seed = psPLC->rand_seed;
+ lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
+ sLTP_buf_idx = psDec->frame_length;
+
+ /***************************/
+ /* LTP synthesis filtering */
+ /***************************/
+ sig_Q10_ptr = sig_Q10;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ /* Setup pointer */
+ pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
+ for( i = 0; i < psDec->subfr_length; i++ ) {
+ rand_seed = SKP_RAND( rand_seed );
+ idx = SKP_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK;
+
+ /* Unrolled loop */
+ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
+ pred_lag_ptr++;
+
+ /* Generate LPC residual */
+ LPC_exc_Q10 = SKP_LSHIFT( SKP_SMULWB( rand_ptr[ idx ], rand_scale_Q14 ), 2 ); /* Random noise part */
+ LPC_exc_Q10 = SKP_ADD32( LPC_exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) ); /* Harmonic part */
+
+ /* Update states */
+ psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 );
+ sLTP_buf_idx++;
+
+ /* Save LPC residual */
+ sig_Q10_ptr[ i ] = LPC_exc_Q10;
+ }
+ sig_Q10_ptr += psDec->subfr_length;
+ /* Gradually reduce LTP gain */
+ for( j = 0; j < LTP_ORDER; j++ ) {
+ B_Q14[ j ] = SKP_RSHIFT( SKP_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
+ }
+ /* Gradually reduce excitation gain */
+ rand_scale_Q14 = SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
+
+ /* Slowly increase pitch lag */
+ psPLC->pitchL_Q8 += SKP_SMULWB( psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
+ psPLC->pitchL_Q8 = SKP_min_32( psPLC->pitchL_Q8, SKP_LSHIFT( SKP_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) );
+ lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
+ }
+
+ /***************************/
+ /* LPC synthesis filtering */
+ /***************************/
+ sig_Q10_ptr = sig_Q10;
+ /* Preload LPC coeficients to array on stack. Gives small performance gain */
+ SKP_memcpy( A_Q12_tmp.as_int16, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( SKP_int16 ) );
+ SKP_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ for( i = 0; i < psDec->subfr_length; i++ ){
+ /* partly unrolled */
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
+ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
+ /* loaded in reverse order and the code will give the wrong result. In that case swapping */
+ /* the SMLAWB and SMLAWT instructions should solve the problem. */
+ Atmp = A_Q12_tmp.as_int32[ 0 ]; /* read two coefficients at once */
+ LPC_pred_Q10 = SKP_SMULWB( psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp );
+ Atmp = A_Q12_tmp.as_int32[ 1 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp );
+ Atmp = A_Q12_tmp.as_int32[ 2 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp );
+ Atmp = A_Q12_tmp.as_int32[ 3 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp );
+ Atmp = A_Q12_tmp.as_int32[ 4 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );
+ for( j = 10 ; j < psDec->LPC_order ; j+=2 ) {
+ Atmp = A_Q12_tmp.as_int32[ j / 2 ];
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 - j ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 - j ], Atmp );
+ }
+#else
+ LPC_pred_Q10 = SKP_SMULWB( psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp.as_int16[ 0 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp.as_int16[ 1 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp.as_int16[ 2 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp.as_int16[ 3 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp.as_int16[ 4 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp.as_int16[ 5 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp.as_int16[ 6 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp.as_int16[ 7 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp.as_int16[ 8 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp.as_int16[ 9 ] );
+
+ for( j = 10; j < psDec->LPC_order; j++ ) {
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp.as_int16[ j ] );
+ }
+#endif
+ /* Add prediction to LPC residual */
+ sig_Q10_ptr[ i ] = SKP_ADD32( sig_Q10_ptr[ i ], LPC_pred_Q10 );
+
+ /* Update states */
+ psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( sig_Q10_ptr[ i ], 4 );
+ }
+ sig_Q10_ptr += psDec->subfr_length;
+ /* Update LPC filter state */
+ SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
+ }
+
+ /* Scale with Gain */
+ for( i = 0; i < psDec->frame_length; i++ ) {
+ signal[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( sig_Q10[ i ], psPLC->prevGain_Q16[ NB_SUBFR - 1 ] ), 10 ) );
+ }
+
+ /**************************************/
+ /* Update states */
+ /**************************************/
+ psPLC->rand_seed = rand_seed;
+ psPLC->randScale_Q14 = rand_scale_Q14;
+ for( i = 0; i < NB_SUBFR; i++ ) {
+ psDecCtrl->pitchL[ i ] = lag;
+ }
+}
+
+/* Glues concealed frames with new good recieved frames */
+void SKP_Silk_PLC_glue_frames(
+ SKP_Silk_decoder_state *psDec, /* I/O decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[], /* I/O signal */
+ SKP_int length /* I length of residual */
+)
+{
+ SKP_int i, energy_shift;
+ SKP_int32 energy;
+ SKP_Silk_PLC_struct *psPLC;
+ psPLC = &psDec->sPLC;
+
+ if( psDec->lossCnt ) {
+ /* Calculate energy in concealed residual */
+ SKP_Silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, signal, length );
+
+ psPLC->last_frame_lost = 1;
+ } else {
+ if( psDec->sPLC.last_frame_lost ) {
+ /* Calculate residual in decoded signal if last frame was lost */
+ SKP_Silk_sum_sqr_shift( &energy, &energy_shift, signal, length );
+
+ /* Normalize energies */
+ if( energy_shift > psPLC->conc_energy_shift ) {
+ psPLC->conc_energy = SKP_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift );
+ } else if( energy_shift < psPLC->conc_energy_shift ) {
+ energy = SKP_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift );
+ }
+
+ /* Fade in the energy difference */
+ if( energy > psPLC->conc_energy ) {
+ SKP_int32 frac_Q24, LZ;
+ SKP_int32 gain_Q12, slope_Q12;
+
+ LZ = SKP_Silk_CLZ32( psPLC->conc_energy );
+ LZ = LZ - 1;
+ psPLC->conc_energy = SKP_LSHIFT( psPLC->conc_energy, LZ );
+ energy = SKP_RSHIFT( energy, SKP_max_32( 24 - LZ, 0 ) );
+
+ frac_Q24 = SKP_DIV32( psPLC->conc_energy, SKP_max( energy, 1 ) );
+
+ gain_Q12 = SKP_Silk_SQRT_APPROX( frac_Q24 );
+ slope_Q12 = SKP_DIV32_16( ( 1 << 12 ) - gain_Q12, length );
+
+ for( i = 0; i < length; i++ ) {
+ signal[ i ] = SKP_RSHIFT( SKP_MUL( gain_Q12, signal[ i ] ), 12 );
+ gain_Q12 += slope_Q12;
+ gain_Q12 = SKP_min( gain_Q12, ( 1 << 12 ) );
+ }
+ }
+ }
+ psPLC->last_frame_lost = 0;
+
+ }
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_PLC.h b/pkg/silk/csilk/SKP_Silk_PLC.h
new file mode 100644
index 0000000..1723943
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_PLC.h
@@ -0,0 +1,79 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_PLC_FIX_H
+#define SKP_SILK_PLC_FIX_H
+
+#include "SKP_Silk_main.h"
+
+#define BWE_COEF_Q16 64880 /* 0.99 in Q16 */
+#define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */
+#define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */
+#define MAX_PITCH_LAG_MS 18
+#define SA_THRES_Q8 50
+#define USE_SINGLE_TAP 1
+#define RAND_BUF_SIZE 128
+#define RAND_BUF_MASK (RAND_BUF_SIZE - 1)
+#define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */
+#define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */
+#define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */
+
+void SKP_Silk_PLC_Reset(
+ SKP_Silk_decoder_state *psDec /* I/O Decoder state */
+);
+
+void SKP_Silk_PLC(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[], /* I/O signal */
+ SKP_int length, /* I length of residual */
+ SKP_int lost /* I Loss flag */
+);
+
+void SKP_Silk_PLC_update(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[],
+ SKP_int length
+);
+
+void SKP_Silk_PLC_conceal(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[], /* O LPC residual signal */
+ SKP_int length /* I length of signal */
+);
+
+void SKP_Silk_PLC_glue_frames(
+ SKP_Silk_decoder_state *psDec, /* I/O decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[], /* I/O signal */
+ SKP_int length /* I length of signal */
+);
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_SDK_API.h b/pkg/silk/csilk/SKP_Silk_SDK_API.h
new file mode 100644
index 0000000..0e9041b
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_SDK_API.h
@@ -0,0 +1,152 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_SDK_API_H
+#define SKP_SILK_SDK_API_H
+
+#include "SKP_Silk_control.h"
+#include "SKP_Silk_typedef.h"
+#include "SKP_Silk_errors.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SILK_MAX_FRAMES_PER_PACKET 5
+
+/* Struct for TOC (Table of Contents) */
+typedef struct {
+ SKP_int framesInPacket; /* Number of 20 ms frames in packet */
+ SKP_int fs_kHz; /* Sampling frequency in packet */
+ SKP_int inbandLBRR; /* Does packet contain LBRR information */
+ SKP_int corrupt; /* Packet is corrupt */
+ SKP_int vadFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet */
+ SKP_int sigtypeFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */
+} SKP_Silk_TOC_struct;
+
+/****************************************/
+/* Encoder functions */
+/****************************************/
+
+/***********************************************/
+/* Get size in bytes of the Silk encoder state */
+/***********************************************/
+SKP_int SKP_Silk_SDK_Get_Encoder_Size(
+ SKP_int32 *encSizeBytes /* O: Number of bytes in SILK encoder state */
+);
+
+/*************************/
+/* Init or reset encoder */
+/*************************/
+SKP_int SKP_Silk_SDK_InitEncoder(
+ void *encState, /* I/O: State */
+ SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
+);
+
+/***************************************/
+/* Read control structure from encoder */
+/***************************************/
+SKP_int SKP_Silk_SDK_QueryEncoder(
+ const void *encState, /* I: State */
+ SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
+);
+
+/**************************/
+/* Encode frame with Silk */
+/**************************/
+SKP_int SKP_Silk_SDK_Encode(
+ void *encState, /* I/O: State */
+ const SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control status */
+ const SKP_int16 *samplesIn, /* I: Speech sample input vector */
+ SKP_int nSamplesIn, /* I: Number of samples in input vector */
+ SKP_uint8 *outData, /* O: Encoded output vector */
+ SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
+);
+
+/****************************************/
+/* Decoder functions */
+/****************************************/
+
+/***********************************************/
+/* Get size in bytes of the Silk decoder state */
+/***********************************************/
+SKP_int SKP_Silk_SDK_Get_Decoder_Size(
+ SKP_int32 *decSizeBytes /* O: Number of bytes in SILK decoder state */
+);
+
+/*************************/
+/* Init or Reset decoder */
+/*************************/
+SKP_int SKP_Silk_SDK_InitDecoder(
+ void *decState /* I/O: State */
+);
+
+/******************/
+/* Decode a frame */
+/******************/
+SKP_int SKP_Silk_SDK_Decode(
+ void* decState, /* I/O: State */
+ SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control Structure */
+ SKP_int lostFlag, /* I: 0: no loss, 1 loss */
+ const SKP_uint8 *inData, /* I: Encoded input vector */
+ const SKP_int nBytesIn, /* I: Number of input bytes */
+ SKP_int16 *samplesOut, /* O: Decoded output speech vector */
+ SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
+);
+
+/***************************************************************/
+/* Find Low Bit Rate Redundancy (LBRR) information in a packet */
+/***************************************************************/
+void SKP_Silk_SDK_search_for_LBRR(
+ const SKP_uint8 *inData, /* I: Encoded input vector */
+ const SKP_int nBytesIn, /* I: Number of input Bytes */
+ SKP_int lost_offset, /* I: Offset from lost packet */
+ SKP_uint8 *LBRRData, /* O: LBRR payload */
+ SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
+);
+
+/**************************************/
+/* Get table of contents for a packet */
+/**************************************/
+void SKP_Silk_SDK_get_TOC(
+ const SKP_uint8 *inData, /* I: Encoded input vector */
+ const SKP_int nBytesIn, /* I: Number of input bytes */
+ SKP_Silk_TOC_struct *Silk_TOC /* O: Table of contents */
+);
+
+/**************************/
+/* Get the version number */
+/**************************/
+/* Return a pointer to string specifying the version */
+const char *SKP_Silk_SDK_get_version(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_SigProc_FIX.h b/pkg/silk/csilk/SKP_Silk_SigProc_FIX.h
new file mode 100644
index 0000000..d53cb40
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_SigProc_FIX.h
@@ -0,0 +1,663 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 _SKP_SILK_SIGPROC_FIX_H_
+#define _SKP_SILK_SIGPROC_FIX_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SKP_Silk_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */
+#define SKP_Silk_MAX_CORRELATION_LENGTH 640 /* max input length to the correlation */
+#include "SKP_Silk_typedef.h"
+#include
+#include /* for abs() */
+#include "SKP_Silk_resampler_structs.h"
+
+#ifndef NO_ASM
+# if defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5T__)
+# define EMBEDDED_ARM 4
+# define EMBEDDED_ARMv4
+# include "SKP_Silk_macros_arm.h"
+# elif defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5TEJ__)
+# define EMBEDDED_ARM 5
+# define EMBEDDED_ARMv5
+# include "SKP_Silk_macros_arm.h"
+# elif defined (__ARM_ARCH_6__) ||defined (__ARM_ARCH_6J__) || defined (__ARM_ARCH_6Z__) || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
+# define EMBEDDED_ARM 6
+# define EMBEDDED_ARMv6
+# include "SKP_Silk_macros_arm.h"
+# elif defined (__ARM_ARCH_7A__) && defined (__ARM_NEON__)
+# define EMBEDDED_ARM 7
+# define EMBEDDED_ARMv6
+# include "SKP_Silk_macros_arm.h"
+# elif defined (__ARM_ARCH_7A__)
+# define EMBEDDED_ARM 6
+# define EMBEDDED_ARMv6
+# include "SKP_Silk_macros_arm.h"
+# else
+# include "SKP_Silk_macros.h"
+# endif
+#else
+# define EMBEDDED_ARM 0
+# include "SKP_Silk_macros.h"
+#endif
+
+
+
+/********************************************************************/
+/* SIGNAL PROCESSING FUNCTIONS */
+/********************************************************************/
+
+/*!
+ * Initialize/reset the resampler state for a given pair of input/output sampling rates
+*/
+SKP_int SKP_Silk_resampler_init(
+ SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
+ SKP_int32 Fs_Hz_in, /* I: Input sampling rate (Hz) */
+ SKP_int32 Fs_Hz_out /* I: Output sampling rate (Hz) */
+);
+
+
+/*!
+ * Clear the states of all resampling filters, without resetting sampling rate ratio
+ */
+SKP_int SKP_Silk_resampler_clear(
+ SKP_Silk_resampler_state_struct *S /* I/O: Resampler state */
+);
+
+/*!
+ * Resampler: convert from one sampling rate to another
+ */
+SKP_int SKP_Silk_resampler(
+ SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+/*!
+ Upsample 2x, low quality
+ */
+void SKP_Silk_resampler_up2(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ 2 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of input samples */
+);
+
+/*!
+* Downsample 2x, mediocre quality
+*/
+void SKP_Silk_resampler_down2(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ len ] */
+ const SKP_int16 *in, /* I: Input signal [ floor(len/2) ] */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+
+/*!
+ * Downsample by a factor 2/3, low quality
+*/
+void SKP_Silk_resampler_down2_3(
+ SKP_int32 *S, /* I/O: State vector [ 6 ] */
+ SKP_int16 *out, /* O: Output signal [ floor(2*inLen/3) ] */
+ const SKP_int16 *in, /* I: Input signal [ inLen ] */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+/*!
+ * Downsample by a factor 3, low quality
+*/
+void SKP_Silk_resampler_down3(
+ SKP_int32 *S, /* I/O: State vector [ 8 ] */
+ SKP_int16 *out, /* O: Output signal [ floor(inLen/3) ] */
+ const SKP_int16 *in, /* I: Input signal [ inLen ] */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+/*!
+ * second order ARMA filter
+ * can handle (slowly) varying coefficients
+ */
+void SKP_Silk_biquad(
+ const SKP_int16 *in, /* I: input signal */
+ const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */
+ const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */
+ SKP_int32 *S, /* I/O: state vector [2] */
+ SKP_int16 *out, /* O: output signal */
+ const SKP_int32 len /* I: signal length */
+);
+/*!
+ * Second order ARMA filter;
+ * slower than biquad() but uses more precise coefficients
+ * can handle (slowly) varying coefficients
+ */
+void SKP_Silk_biquad_alt(
+ const SKP_int16 *in, /* I: Input signal */
+ const SKP_int32 *B_Q28, /* I: MA coefficients [3] */
+ const SKP_int32 *A_Q28, /* I: AR coefficients [2] */
+ SKP_int32 *S, /* I/O: State vector [2] */
+ SKP_int16 *out, /* O: Output signal */
+ const SKP_int32 len /* I: Signal length (must be even) */
+);
+
+/*!
+ * variable order MA filter. Prediction error filter implementation. Coeficients negated and starting with coef to x[n - 1]
+ */
+void SKP_Silk_MA_Prediction(
+ const SKP_int16 *in, /* I: Input signal */
+ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
+ SKP_int32 *S, /* I/O: State vector [order] */
+ SKP_int16 *out, /* O: Output signal */
+ const SKP_int32 len, /* I: Signal length */
+ const SKP_int32 order /* I: Filter order */
+);
+
+/*!
+ * 16th order AR filter for LPC synthesis, coefficients are in Q12
+ */
+void SKP_Silk_LPC_synthesis_order16(
+ const SKP_int16 *in, /* I: excitation signal */
+ const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
+ const SKP_int32 Gain_Q26, /* I: gain */
+ SKP_int32 *S, /* I/O: state vector [16] */
+ SKP_int16 *out, /* O: output signal */
+ const SKP_int32 len /* I: signal length, must be multiple of 16 */
+);
+
+/* variable order MA prediction error filter. */
+/* Inverse filter of SKP_Silk_LPC_synthesis_filter */
+void SKP_Silk_LPC_analysis_filter(
+ const SKP_int16 *in, /* I: Input signal */
+ const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
+ SKP_int16 *S, /* I/O: State vector [order] */
+ SKP_int16 *out, /* O: Output signal */
+ const SKP_int32 len, /* I: Signal length */
+ const SKP_int32 Order /* I: Filter order */
+);
+
+/* even order AR filter */
+void SKP_Silk_LPC_synthesis_filter(
+ const SKP_int16 *in, /* I: excitation signal */
+ const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
+ const SKP_int32 Gain_Q26, /* I: gain */
+ SKP_int32 *S, /* I/O: state vector [Order] */
+ SKP_int16 *out, /* O: output signal */
+ const SKP_int32 len, /* I: signal length */
+ const SKP_int Order /* I: filter order, must be even */
+);
+
+/* Chirp (bandwidth expand) LP AR filter */
+void SKP_Silk_bwexpander(
+ SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
+ const SKP_int d, /* I Length of ar */
+ SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
+);
+
+/* Chirp (bandwidth expand) LP AR filter */
+void SKP_Silk_bwexpander_32(
+ SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
+ const SKP_int d, /* I Length of ar */
+ SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */
+);
+
+/* Compute inverse of LPC prediction gain, and */
+/* test if LPC coefficients are stable (all poles within unit circle) */
+SKP_int SKP_Silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwise 0 */
+ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
+ const SKP_int16 *A_Q12, /* I: Prediction coefficients, Q12 [order] */
+ const SKP_int order /* I: Prediction order */
+);
+
+SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
+ SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
+ const SKP_int32 *A_Q24, /* I: Prediction coefficients, Q24 [order] */
+ const SKP_int order /* I: Prediction order */
+);
+
+/* split signal in two decimated bands using first-order allpass filters */
+void SKP_Silk_ana_filt_bank_1(
+ const SKP_int16 *in, /* I: Input signal [N] */
+ SKP_int32 *S, /* I/O: State vector [2] */
+ SKP_int16 *outL, /* O: Low band [N/2] */
+ SKP_int16 *outH, /* O: High band [N/2] */
+ SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */
+ const SKP_int32 N /* I: Number of input samples */
+);
+
+/********************************************************************/
+/* SCALAR FUNCTIONS */
+/********************************************************************/
+
+/* Approximation of 128 * log2() (very close inverse of approx 2^() below) */
+/* Convert input to a log scale */
+SKP_int32 SKP_Silk_lin2log(const SKP_int32 inLin); /* I: Input in linear scale */
+
+/* Approximation of a sigmoid function */
+SKP_int SKP_Silk_sigm_Q15(SKP_int in_Q5);
+
+/* approximation of 2^() (exact inverse of approx log2() above) */
+/* convert input to a linear scale */
+SKP_int32 SKP_Silk_log2lin(const SKP_int32 inLog_Q7); /* I: input on log scale */
+
+/* Function that returns the maximum absolut value of the input vector */
+SKP_int16 SKP_Silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */
+ const SKP_int16 *vec, /* I Input vector [len] */
+ const SKP_int32 len /* I Length of input vector */
+);
+
+/* Compute number of bits to right shift the sum of squares of a vector */
+/* of int16s to make it fit in an int32 */
+void SKP_Silk_sum_sqr_shift(
+ SKP_int32 *energy, /* O Energy of x, after shifting to the right */
+ SKP_int *shift, /* O Number of bits right shift applied to energy */
+ const SKP_int16 *x, /* I Input vector */
+ SKP_int len /* I Length of input vector */
+);
+
+/* Calculates the reflection coefficients from the correlation sequence */
+/* Faster than schur64(), but much less accurate. */
+/* Uses SMLAWB(), requiring armv5E and higher. */
+SKP_int32 SKP_Silk_schur( /* O: Returns residual energy */
+ SKP_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */
+ const SKP_int32 *c, /* I: correlations [order+1] */
+ const SKP_int32 order /* I: prediction order */
+);
+
+/* Calculates the reflection coefficients from the correlation sequence */
+/* Slower than schur(), but more accurate. */
+/* Uses SMULL(), available on armv4 */
+SKP_int32 SKP_Silk_schur64( /* O: returns residual energy */
+ SKP_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */
+ const SKP_int32 c[], /* I: Correlations [order+1] */
+ SKP_int32 order /* I: Prediction order */
+);
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void SKP_Silk_k2a(
+ SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
+ const SKP_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */
+ const SKP_int32 order /* I: Prediction order */
+);
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void SKP_Silk_k2a_Q16(
+ SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
+ const SKP_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */
+ const SKP_int32 order /* I: Prediction order */
+);
+
+/* Apply sine window to signal vector. */
+/* Window types: */
+/* 1 -> sine window from 0 to pi/2 */
+/* 2 -> sine window from pi/2 to pi */
+/* Every other sample is linearly interpolated, for speed. */
+void SKP_Silk_apply_sine_window(
+ SKP_int16 px_win[], /* O Pointer to windowed signal */
+ const SKP_int16 px[], /* I Pointer to input signal */
+ const SKP_int win_type, /* I Selects a window type */
+ const SKP_int length /* I Window length, multiple of 4 */
+);
+
+/* Compute autocorrelation */
+void SKP_Silk_autocorr(
+ SKP_int32 *results, /* O Result (length correlationCount) */
+ SKP_int *scale, /* O Scaling of the correlation vector */
+ const SKP_int16 *inputData, /* I Input data to correlate */
+ const SKP_int inputDataSize, /* I Length of input */
+ const SKP_int correlationCount /* I Number of correlation taps to compute */
+);
+
+/* Pitch estimator */
+#define SKP_Silk_PITCH_EST_MIN_COMPLEX 0
+#define SKP_Silk_PITCH_EST_MID_COMPLEX 1
+#define SKP_Silk_PITCH_EST_MAX_COMPLEX 2
+
+void SKP_Silk_decode_pitch(
+ SKP_int lagIndex, /* I */
+ SKP_int contourIndex, /* O */
+ SKP_int pitch_lags[], /* O 4 pitch values */
+ SKP_int Fs_kHz /* I sampling frequency (kHz) */
+);
+
+SKP_int SKP_Silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
+ const SKP_int16 *signal, /* I Signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */
+ SKP_int *pitch_out, /* O 4 pitch lag values */
+ SKP_int *lagIndex, /* O Lag Index */
+ SKP_int *contourIndex, /* O Pitch contour Index */
+ SKP_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
+ SKP_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
+ const SKP_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
+ const SKP_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */
+ const SKP_int Fs_kHz, /* I Sample frequency (kHz) */
+ const SKP_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
+ const SKP_int forLJC /* I 1 if this function is called from LJC code, 0 otherwise. */
+);
+
+/* parameter defining the size and accuracy of the piecewise linear */
+/* cosine approximatin table. */
+
+#define LSF_COS_TAB_SZ_FIX 128
+/* rom table with cosine values */
+extern const SKP_int SKP_Silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ];
+
+/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
+/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
+void SKP_Silk_A2NLSF(
+ SKP_int *NLSF, /* O Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d] */
+ SKP_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
+ const SKP_int d /* I Filter order (must be even) */
+);
+
+/* compute whitening filter coefficients from normalized line spectral frequencies */
+void SKP_Silk_NLSF2A(
+ SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
+ const SKP_int *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
+ const SKP_int d /* i filter order (should be even) */
+);
+
+void SKP_Silk_insertion_sort_increasing(
+ SKP_int32 *a, /* I/O Unsorted / Sorted vector */
+ SKP_int *index, /* O: Index vector for the sorted elements */
+ const SKP_int L, /* I: Vector length */
+ const SKP_int K /* I: Number of correctly sorted positions */
+);
+
+void SKP_Silk_insertion_sort_decreasing_int16(
+ SKP_int16 *a, /* I/O: Unsorted / Sorted vector */
+ SKP_int *index, /* O: Index vector for the sorted elements */
+ const SKP_int L, /* I: Vector length */
+ const SKP_int K /* I: Number of correctly sorted positions */
+);
+
+void SKP_Silk_insertion_sort_increasing_all_values(
+ SKP_int *a, /* I/O: Unsorted / Sorted vector */
+ const SKP_int L /* I: Vector length */
+);
+
+/* NLSF stabilizer, for a single input data vector */
+void SKP_Silk_NLSF_stabilize(
+ SKP_int *NLSF_Q15, /* I/O: Unstable/stabilized normalized LSF vector in Q15 [L] */
+ const SKP_int *NDeltaMin_Q15, /* I: Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
+ const SKP_int L /* I: Number of NLSF parameters in the input vector */
+);
+
+/* Laroia low complexity NLSF weights */
+void SKP_Silk_NLSF_VQ_weights_laroia(
+ SKP_int *pNLSFW_Q6, /* O: Pointer to input vector weights [D x 1] */
+ const SKP_int *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
+ const SKP_int D /* I: Input vector dimension (even) */
+);
+
+/* Compute reflection coefficients from input signal */
+void SKP_Silk_burg_modified(
+ SKP_int32 *res_nrg, /* O residual energy */
+ SKP_int *res_nrgQ, /* O residual energy Q value */
+ SKP_int32 A_Q16[], /* O prediction coefficients (length order) */
+ const SKP_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */
+ const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
+ const SKP_int nb_subfr, /* I number of subframes stacked in x */
+ const SKP_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */
+ const SKP_int D /* I order */
+);
+
+/* Copy and multiply a vector by a constant */
+void SKP_Silk_scale_copy_vector16(
+ SKP_int16 *data_out,
+ const SKP_int16 *data_in,
+ SKP_int32 gain_Q16, /* I: gain in Q16 */
+ const SKP_int dataSize /* I: length */
+);
+
+/* Some for the LTP related function requires Q26 to work.*/
+void SKP_Silk_scale_vector32_Q26_lshift_18(
+ SKP_int32 *data1, /* I/O: Q0/Q18 */
+ SKP_int32 gain_Q26, /* I: Q26 */
+ SKP_int dataSize /* I: length */
+);
+
+/********************************************************************/
+/* INLINE ARM MATH */
+/********************************************************************/
+
+/* return sum(inVec1[i]*inVec2[i]) */
+/* inVec1 and inVec2 should be increasing ordered, and starting address should be 4 byte aligned. (a factor of 4)*/
+SKP_int32 SKP_Silk_inner_prod_aligned(
+ const SKP_int16* const inVec1, /* I input vector 1 */
+ const SKP_int16* const inVec2, /* I input vector 2 */
+ const SKP_int len /* I vector lengths */
+);
+
+SKP_int64 SKP_Silk_inner_prod16_aligned_64(
+ const SKP_int16 *inVec1, /* I input vector 1 */
+ const SKP_int16 *inVec2, /* I input vector 2 */
+ const SKP_int len /* I vector lengths */
+);
+/********************************************************************/
+/* MACROS */
+/********************************************************************/
+
+/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating
+ left. Output is 32bit int.
+ Note: contemporary compilers recognize the C expressions below and
+ compile them into 'ror' instructions if available. No need for inline ASM! */
+#if defined(EMBEDDED_MIPS)
+/* For MIPS (and most likely for ARM! and >=i486) we don't have to handle
+ negative rot's as only 5 bits of rot are encoded into ROR instructions. */
+SKP_INLINE SKP_int32 SKP_ROR32(SKP_int32 a32, SKP_int rot)
+{
+ SKP_uint32 _x = (SKP_uint32) a32;
+ SKP_uint32 _r = (SKP_uint32) rot;
+ return (SKP_int32) ((_x << (32 - _r)) | (_x >> _r));
+}
+#else
+/* PPC must use this generic implementation. */
+SKP_INLINE SKP_int32 SKP_ROR32( SKP_int32 a32, SKP_int rot )
+{
+ SKP_uint32 x = (SKP_uint32) a32;
+ SKP_uint32 r = (SKP_uint32) rot;
+ SKP_uint32 m = (SKP_uint32) -rot;
+ if(rot <= 0)
+ return (SKP_int32) ((x << m) | (x >> (32 - m)));
+ else
+ return (SKP_int32) ((x << (32 - r)) | (x >> r));
+}
+#endif
+
+/* Allocate SKP_int16 alligned to 4-byte memory address */
+#if EMBEDDED_ARM
+#if defined(_WIN32) && defined(_M_ARM)
+#define SKP_DWORD_ALIGN __declspec(align(4))
+#else
+#define SKP_DWORD_ALIGN __attribute__((aligned(4)))
+#endif
+#else
+#define SKP_DWORD_ALIGN
+#endif
+
+/* Useful Macros that can be adjusted to other platforms */
+#define SKP_memcpy(a, b, c) memcpy((a), (b), (c)) /* Dest, Src, ByteCount */
+#define SKP_memset(a, b, c) memset((a), (b), (c)) /* Dest, value, ByteCount */
+#define SKP_memmove(a, b, c) memmove((a), (b), (c)) /* Dest, Src, ByteCount */
+/* fixed point macros */
+
+// (a32 * b32) output have to be 32bit int
+#define SKP_MUL(a32, b32) ((a32) * (b32))
+
+// (a32 * b32) output have to be 32bit uint
+#define SKP_MUL_uint(a32, b32) SKP_MUL(a32, b32)
+
+// a32 + (b32 * c32) output have to be 32bit int
+#define SKP_MLA(a32, b32, c32) SKP_ADD32((a32),((b32) * (c32)))
+
+/* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
+#define SKP_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16))
+
+/* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
+#define SKP_SMLATT(a32, b32, c32) SKP_ADD32((a32),((b32) >> 16) * ((c32) >> 16))
+
+#define SKP_SMLALBB(a64, b16, c16) SKP_ADD64((a64),(SKP_int64)((SKP_int32)(b16) * (SKP_int32)(c16)))
+
+// (a32 * b32)
+#define SKP_SMULL(a32, b32) ((SKP_int64)(a32) * /*(SKP_int64)*/(b32))
+
+/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
+ (just standard two's complement implementation-specific behaviour) */
+#define SKP_ADD32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) + (SKP_uint32)(b)))
+/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
+ (just standard two's complement implementation-specific behaviour) */
+#define SKP_SUB32_ovflw(a, b) ((SKP_int32)((SKP_uint32)(a) - (SKP_uint32)(b)))
+
+/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
+#define SKP_MLA_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), (SKP_uint32)(b32) * (SKP_uint32)(c32))
+#ifndef SKP_SMLABB_ovflw
+ #define SKP_SMLABB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULBB((b32),(c32)))
+#endif
+#define SKP_SMLATT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULTT((b32),(c32)))
+#define SKP_SMLAWB_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWB((b32),(c32)))
+#define SKP_SMLAWT_ovflw(a32, b32, c32) SKP_ADD32_ovflw((a32), SKP_SMULWT((b32),(c32)))
+#define SKP_DIV32_16(a32, b16) ((SKP_int32)((a32) / (b16)))
+#define SKP_DIV32(a32, b32) ((SKP_int32)((a32) / (b32)))
+
+#define SKP_ADD32(a, b) ((a) + (b))
+#define SKP_ADD64(a, b) ((a) + (b))
+
+#define SKP_SUB32(a, b) ((a) - (b))
+
+#define SKP_SAT16(a) ((a) > SKP_int16_MAX ? SKP_int16_MAX : \
+ ((a) < SKP_int16_MIN ? SKP_int16_MIN : (a)))
+#define SKP_SAT32(a) ((a) > SKP_int32_MAX ? SKP_int32_MAX : \
+ ((a) < SKP_int32_MIN ? SKP_int32_MIN : (a)))
+
+#define SKP_CHECK_FIT16(a) (a)
+#define SKP_CHECK_FIT32(a) (a)
+
+#define SKP_ADD_SAT16(a, b) (SKP_int16)SKP_SAT16( SKP_ADD32( (SKP_int32)(a), (b) ) )
+
+/* Add with saturation for positive input values */
+#define SKP_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? SKP_int32_MAX : ((a)+(b)))
+
+#define SKP_LSHIFT32(a, shift) ((a)<<(shift)) // shift >= 0, shift < 32
+#define SKP_LSHIFT64(a, shift) ((a)<<(shift)) // shift >= 0, shift < 64
+#define SKP_LSHIFT(a, shift) SKP_LSHIFT32(a, shift) // shift >= 0, shift < 32
+
+#define SKP_RSHIFT32(a, shift) ((a)>>(shift)) // shift >= 0, shift < 32
+#define SKP_RSHIFT64(a, shift) ((a)>>(shift)) // shift >= 0, shift < 64
+#define SKP_RSHIFT(a, shift) SKP_RSHIFT32(a, shift) // shift >= 0, shift < 32
+
+/* saturates before shifting */
+#define SKP_LSHIFT_SAT32(a, shift) (SKP_LSHIFT32( SKP_LIMIT_32( (a), SKP_RSHIFT32( SKP_int32_MIN, (shift) ), \
+ SKP_RSHIFT32( SKP_int32_MAX, (shift) ) ), (shift) ))
+
+#define SKP_LSHIFT_ovflw(a, shift) ((a)<<(shift)) // shift >= 0, allowed to overflow
+#define SKP_LSHIFT_uint(a, shift) ((a)<<(shift)) // shift >= 0
+#define SKP_RSHIFT_uint(a, shift) ((a)>>(shift)) // shift >= 0
+
+#define SKP_ADD_LSHIFT(a, b, shift) ((a) + SKP_LSHIFT((b), (shift))) // shift >= 0
+#define SKP_ADD_LSHIFT32(a, b, shift) SKP_ADD32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0
+#define SKP_ADD_RSHIFT(a, b, shift) ((a) + SKP_RSHIFT((b), (shift))) // shift >= 0
+#define SKP_ADD_RSHIFT32(a, b, shift) SKP_ADD32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0
+#define SKP_ADD_RSHIFT_uint(a, b, shift) ((a) + SKP_RSHIFT_uint((b), (shift))) // shift >= 0
+#define SKP_SUB_LSHIFT32(a, b, shift) SKP_SUB32((a), SKP_LSHIFT32((b), (shift))) // shift >= 0
+#define SKP_SUB_RSHIFT32(a, b, shift) SKP_SUB32((a), SKP_RSHIFT32((b), (shift))) // shift >= 0
+
+/* Requires that shift > 0 */
+#define SKP_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
+#define SKP_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
+
+/* Number of rightshift required to fit the multiplication */
+#define SKP_NSHIFT_MUL_32_32(a, b) ( -(31- (32-SKP_Silk_CLZ32(SKP_abs(a)) + (32-SKP_Silk_CLZ32(SKP_abs(b))))) )
+
+#define SKP_min(a, b) (((a) < (b)) ? (a) : (b))
+#define SKP_max(a, b) (((a) > (b)) ? (a) : (b))
+
+/* Macro to convert floating-point constants to fixed-point */
+#define SKP_FIX_CONST( C, Q ) ((SKP_int32)((C) * ((SKP_int64)1 << (Q)) + 0.5))
+
+/* SKP_min() versions with typecast in the function call */
+SKP_INLINE SKP_int SKP_min_int(SKP_int a, SKP_int b)
+{
+ return (((a) < (b)) ? (a) : (b));
+}
+
+SKP_INLINE SKP_int32 SKP_min_32(SKP_int32 a, SKP_int32 b)
+{
+ return (((a) < (b)) ? (a) : (b));
+}
+
+/* SKP_min() versions with typecast in the function call */
+SKP_INLINE SKP_int SKP_max_int(SKP_int a, SKP_int b)
+{
+ return (((a) > (b)) ? (a) : (b));
+}
+SKP_INLINE SKP_int16 SKP_max_16(SKP_int16 a, SKP_int16 b)
+{
+ return (((a) > (b)) ? (a) : (b));
+}
+SKP_INLINE SKP_int32 SKP_max_32(SKP_int32 a, SKP_int32 b)
+{
+ return (((a) > (b)) ? (a) : (b));
+}
+
+#define SKP_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
+ : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))))
+
+#define SKP_LIMIT_int SKP_LIMIT
+#define SKP_LIMIT_32 SKP_LIMIT
+
+//#define SKP_non_neg(a) ((a) & ((-(a)) >> (8 * sizeof(a) - 1))) /* doesn't seem faster than SKP_max(0, a);
+
+#define SKP_abs(a) (((a) > 0) ? (a) : -(a)) // Be careful, SKP_abs returns wrong when input equals to SKP_intXX_MIN
+#define SKP_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31))
+
+/* PSEUDO-RANDOM GENERATOR */
+/* Make sure to store the result as the seed for the next call (also in between */
+/* frames), otherwise result won't be random at all. When only using some of the */
+/* bits, take the most significant bits by right-shifting. Do not just mask off */
+/* the lowest bits. */
+#define SKP_RAND(seed) (SKP_MLA_ovflw(907633515, (seed), 196314165))
+
+// Add some multiplication functions that can be easily mapped to ARM.
+
+// SKP_SMMUL: Signed top word multiply.
+// ARMv6 2 instruction cycles.
+// ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)
+//#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT(SKP_SMLAL(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16)), 16)
+// the following seems faster on x86
+//#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
+
+#include "SKP_Silk_Inlines.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_VAD.c b/pkg/silk/csilk/SKP_Silk_VAD.c
new file mode 100644
index 0000000..35a5a9d
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_VAD.c
@@ -0,0 +1,320 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/*
+ * File Name: SKP_Silk_VAD.c
+ * Description: Silk VAD.
+ */
+
+#include
+#include "SKP_Silk_main.h"
+
+/**********************************/
+/* Initialization of the Silk VAD */
+/**********************************/
+SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */
+ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
+)
+{
+ SKP_int b, ret = 0;
+
+ /* reset state memory */
+ SKP_memset( psSilk_VAD, 0, sizeof( SKP_Silk_VAD_state ) );
+
+ /* init noise levels */
+ /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */
+ for( b = 0; b < VAD_N_BANDS; b++ ) {
+ psSilk_VAD->NoiseLevelBias[ b ] = SKP_max_32( SKP_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );
+ }
+
+ /* Initialize state */
+ for( b = 0; b < VAD_N_BANDS; b++ ) {
+ psSilk_VAD->NL[ b ] = SKP_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );
+ psSilk_VAD->inv_NL[ b ] = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->NL[ b ] );
+ }
+ psSilk_VAD->counter = 15;
+
+ /* init smoothed energy-to-noise ratio*/
+ for( b = 0; b < VAD_N_BANDS; b++ ) {
+ psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */
+ }
+
+ return( ret );
+}
+
+/* Weighting factors for tilt measure */
+const static SKP_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
+
+/***************************************/
+/* Get the speech activity level in Q8 */
+/***************************************/
+SKP_int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */
+ SKP_Silk_VAD_state *psSilk_VAD, /* I/O Silk VAD state */
+ SKP_int *pSA_Q8, /* O Speech activity level in Q8 */
+ SKP_int *pSNR_dB_Q7, /* O SNR for current frame in Q7 */
+ SKP_int pQuality_Q15[ VAD_N_BANDS ], /* O Smoothed SNR for each band */
+ SKP_int *pTilt_Q15, /* O current frame's frequency tilt */
+ const SKP_int16 pIn[], /* I PCM input [framelength] */
+ const SKP_int framelength /* I Input frame length */
+)
+{
+ SKP_int SA_Q15, input_tilt;
+ SKP_int32 scratch[ 3 * MAX_FRAME_LENGTH / 2 ];
+ SKP_int decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
+ SKP_int32 sumSquared, smooth_coef_Q16;
+ SKP_int16 HPstateTmp;
+
+ SKP_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ];
+ SKP_int32 Xnrg[ VAD_N_BANDS ];
+ SKP_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
+ SKP_int32 speech_nrg, x_tmp;
+ SKP_int ret = 0;
+
+ /* Safety checks */
+ SKP_assert( VAD_N_BANDS == 4 );
+ SKP_assert( MAX_FRAME_LENGTH >= framelength );
+ SKP_assert( framelength <= 512 );
+
+ /***********************/
+ /* Filter and Decimate */
+ /***********************/
+ /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
+ SKP_Silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], &scratch[ 0 ], framelength );
+
+ /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
+ SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 1 ) );
+
+ /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
+ SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 2 ) );
+
+ /*********************************************/
+ /* HP filter on lowest band (differentiator) */
+ /*********************************************/
+ decimated_framelength = SKP_RSHIFT( framelength, 3 );
+ X[ 0 ][ decimated_framelength - 1 ] = SKP_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 );
+ HPstateTmp = X[ 0 ][ decimated_framelength - 1 ];
+ for( i = decimated_framelength - 1; i > 0; i-- ) {
+ X[ 0 ][ i - 1 ] = SKP_RSHIFT( X[ 0 ][ i - 1 ], 1 );
+ X[ 0 ][ i ] -= X[ 0 ][ i - 1 ];
+ }
+ X[ 0 ][ 0 ] -= psSilk_VAD->HPstate;
+ psSilk_VAD->HPstate = HPstateTmp;
+
+ /*************************************/
+ /* Calculate the energy in each band */
+ /*************************************/
+ for( b = 0; b < VAD_N_BANDS; b++ ) {
+ /* Find the decimated framelength in the non-uniformly divided bands */
+ decimated_framelength = SKP_RSHIFT( framelength, SKP_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
+
+ /* Split length into subframe lengths */
+ dec_subframe_length = SKP_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
+ dec_subframe_offset = 0;
+
+ /* Compute energy per sub-frame */
+ /* initialize with summed energy of last subframe */
+ Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
+ for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
+ sumSquared = 0;
+ for( i = 0; i < dec_subframe_length; i++ ) {
+ /* The energy will be less than dec_subframe_length * ( SKP_int16_MIN / 8 ) ^ 2. */
+ /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
+ x_tmp = SKP_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 );
+ sumSquared = SKP_SMLABB( sumSquared, x_tmp, x_tmp );
+
+ /* Safety check */
+ SKP_assert( sumSquared >= 0 );
+ }
+
+ /* Add/saturate summed energy of current subframe */
+ if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
+ Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
+ } else {
+ /* Look-ahead subframe */
+ Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], SKP_RSHIFT( sumSquared, 1 ) );
+ }
+
+ dec_subframe_offset += dec_subframe_length;
+ }
+ psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
+ }
+
+ /********************/
+ /* Noise estimation */
+ /********************/
+ SKP_Silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
+
+ /***********************************************/
+ /* Signal-plus-noise to noise ratio estimation */
+ /***********************************************/
+ sumSquared = 0;
+ input_tilt = 0;
+ for( b = 0; b < VAD_N_BANDS; b++ ) {
+ speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
+ if( speech_nrg > 0 ) {
+ /* Divide, with sufficient resolution */
+ if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
+ NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( SKP_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
+ } else {
+ NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( Xnrg[ b ], SKP_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
+ }
+
+ /* Convert to log domain */
+ SNR_Q7 = SKP_Silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
+
+ /* Sum-of-squares */
+ sumSquared = SKP_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
+
+ /* Tilt measure */
+ if( speech_nrg < ( 1 << 20 ) ) {
+ /* Scale down SNR value for small subband speech energies */
+ SNR_Q7 = SKP_SMULWB( SKP_LSHIFT( SKP_Silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
+ }
+ input_tilt = SKP_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
+ } else {
+ NrgToNoiseRatio_Q8[ b ] = 256;
+ }
+ }
+
+ /* Mean-of-squares */
+ sumSquared = SKP_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
+
+ /* Root-mean-square approximation, scale to dBs, and write to output pointer */
+ *pSNR_dB_Q7 = ( SKP_int16 )( 3 * SKP_Silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
+
+ /*********************************/
+ /* Speech Probability Estimation */
+ /*********************************/
+ SA_Q15 = SKP_Silk_sigm_Q15( SKP_SMULWB( VAD_SNR_FACTOR_Q16, *pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
+
+ /**************************/
+ /* Frequency Tilt Measure */
+ /**************************/
+ *pTilt_Q15 = SKP_LSHIFT( SKP_Silk_sigm_Q15( input_tilt ) - 16384, 1 );
+
+ /**************************************************/
+ /* Scale the sigmoid output based on power levels */
+ /**************************************************/
+ speech_nrg = 0;
+ for( b = 0; b < VAD_N_BANDS; b++ ) {
+ /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
+ speech_nrg += ( b + 1 ) * SKP_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
+ }
+
+ /* Power scaling */
+ if( speech_nrg <= 0 ) {
+ SA_Q15 = SKP_RSHIFT( SA_Q15, 1 );
+ } else if( speech_nrg < 32768 ) {
+ /* square-root */
+ speech_nrg = SKP_Silk_SQRT_APPROX( SKP_LSHIFT( speech_nrg, 15 ) );
+ SA_Q15 = SKP_SMULWB( 32768 + speech_nrg, SA_Q15 );
+ }
+
+ /* Copy the resulting speech activity in Q8 to *pSA_Q8 */
+ *pSA_Q8 = SKP_min_int( SKP_RSHIFT( SA_Q15, 7 ), SKP_uint8_MAX );
+
+ /***********************************/
+ /* Energy Level and SNR estimation */
+ /***********************************/
+ /* Smoothing coefficient */
+ smooth_coef_Q16 = SKP_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, SKP_SMULWB( SA_Q15, SA_Q15 ) );
+ for( b = 0; b < VAD_N_BANDS; b++ ) {
+ /* compute smoothed energy-to-noise ratio per band */
+ psSilk_VAD->NrgRatioSmth_Q8[ b ] = SKP_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
+ NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
+
+ /* signal to noise ratio in dB per band */
+ SNR_Q7 = 3 * ( SKP_Silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
+ /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
+ pQuality_Q15[ b ] = SKP_Silk_sigm_Q15( SKP_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
+ }
+
+ return( ret );
+}
+
+/**************************/
+/* Noise level estimation */
+/**************************/
+void SKP_Silk_VAD_GetNoiseLevels(
+ const SKP_int32 pX[ VAD_N_BANDS ], /* I subband energies */
+ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
+)
+{
+ SKP_int k;
+ SKP_int32 nl, nrg, inv_nrg;
+ SKP_int coef, min_coef;
+
+ /* Initially faster smoothing */
+ if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
+ min_coef = SKP_DIV32_16( SKP_int16_MAX, SKP_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
+ } else {
+ min_coef = 0;
+ }
+
+ for( k = 0; k < VAD_N_BANDS; k++ ) {
+ /* Get old noise level estimate for current band */
+ nl = psSilk_VAD->NL[ k ];
+ SKP_assert( nl >= 0 );
+
+ /* Add bias */
+ nrg = SKP_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );
+ SKP_assert( nrg > 0 );
+
+ /* Invert energies */
+ inv_nrg = SKP_DIV32( SKP_int32_MAX, nrg );
+ SKP_assert( inv_nrg >= 0 );
+
+ /* Less update when subband energy is high */
+ if( nrg > SKP_LSHIFT( nl, 3 ) ) {
+ coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
+ } else if( nrg < nl ) {
+ coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;
+ } else {
+ coef = SKP_SMULWB( SKP_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );
+ }
+
+ /* Initially faster smoothing */
+ coef = SKP_max_int( coef, min_coef );
+
+ /* Smooth inverse energies */
+ psSilk_VAD->inv_NL[ k ] = SKP_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );
+ SKP_assert( psSilk_VAD->inv_NL[ k ] >= 0 );
+
+ /* Compute noise level by inverting again */
+ nl = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->inv_NL[ k ] );
+ SKP_assert( nl >= 0 );
+
+ /* Limit noise levels (guarantee 7 bits of head room) */
+ nl = SKP_min( nl, 0x00FFFFFF );
+
+ /* Store as part of state */
+ psSilk_VAD->NL[ k ] = nl;
+ }
+
+ /* Increment frame counter */
+ psSilk_VAD->counter++;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_VQ_nearest_neighbor_FIX.c b/pkg/silk/csilk/SKP_Silk_VQ_nearest_neighbor_FIX.c
new file mode 100644
index 0000000..74a2653
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_VQ_nearest_neighbor_FIX.c
@@ -0,0 +1,159 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/* Entropy constrained MATRIX-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
+void SKP_Silk_VQ_WMat_EC_FIX(
+ SKP_int *ind, /* O index of best codebook vector */
+ SKP_int32 *rate_dist_Q14, /* O best weighted quantization error + mu * rate*/
+ const SKP_int16 *in_Q14, /* I input vector to be quantized */
+ const SKP_int32 *W_Q18, /* I weighting matrix */
+ const SKP_int16 *cb_Q14, /* I codebook */
+ const SKP_int16 *cl_Q6, /* I code length for each codebook vector */
+ const SKP_int mu_Q8, /* I tradeoff between weighted error and rate */
+ SKP_int L /* I number of vectors in codebook */
+)
+{
+ SKP_int k;
+ const SKP_int16 *cb_row_Q14;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 sum1_Q14, sum2_Q16, diff_Q14_01, diff_Q14_23, diff_Q14_4;
+#else
+ SKP_int16 diff_Q14[ 5 ];
+ SKP_int32 sum1_Q14, sum2_Q16;
+#endif
+
+ /* Loop over codebook */
+ *rate_dist_Q14 = SKP_int32_MAX;
+ cb_row_Q14 = cb_Q14;
+ for( k = 0; k < L; k++ ) {
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* Pack pairs of int16 values per int32 */
+ diff_Q14_01 = ( SKP_uint16 )( in_Q14[ 0 ] - cb_row_Q14[ 0 ] ) | SKP_LSHIFT( ( SKP_int32 )in_Q14[ 1 ] - cb_row_Q14[ 1 ], 16 );
+ diff_Q14_23 = ( SKP_uint16 )( in_Q14[ 2 ] - cb_row_Q14[ 2 ] ) | SKP_LSHIFT( ( SKP_int32 )in_Q14[ 3 ] - cb_row_Q14[ 3 ], 16 );
+ diff_Q14_4 = in_Q14[ 4 ] - cb_row_Q14[ 4 ];
+#else
+ diff_Q14[ 0 ] = in_Q14[ 0 ] - cb_row_Q14[ 0 ];
+ diff_Q14[ 1 ] = in_Q14[ 1 ] - cb_row_Q14[ 1 ];
+ diff_Q14[ 2 ] = in_Q14[ 2 ] - cb_row_Q14[ 2 ];
+ diff_Q14[ 3 ] = in_Q14[ 3 ] - cb_row_Q14[ 3 ];
+ diff_Q14[ 4 ] = in_Q14[ 4 ] - cb_row_Q14[ 4 ];
+#endif
+
+ /* Weighted rate */
+ sum1_Q14 = SKP_SMULBB( mu_Q8, cl_Q6[ k ] );
+
+ SKP_assert( sum1_Q14 >= 0 );
+
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* Add weighted quantization error, assuming W_Q18 is symmetric */
+ /* NOTE: the code below loads two int16 values as one int32, and multiplies each using the */
+ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
+ /* loaded in reverse order and the code will give the wrong result. In that case swapping */
+ /* the SMLAWB and SMLAWT instructions should solve the problem. */
+ /* first row of W_Q18 */
+ sum2_Q16 = SKP_SMULWT( W_Q18[ 1 ], diff_Q14_01 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14_23 );
+ sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 3 ], diff_Q14_23 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14_4 );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14_01 );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_01 );
+
+ /* second row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 7 ], diff_Q14_23 );
+ sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 8 ], diff_Q14_23 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14_4 );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 6 ], diff_Q14_01 );
+ sum1_Q14 = SKP_SMLAWT( sum1_Q14, sum2_Q16, diff_Q14_01 );
+
+ /* third row of W_Q18 */
+ sum2_Q16 = SKP_SMULWT( W_Q18[ 13 ], diff_Q14_23 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14_4 );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14_23 );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_23 );
+
+ /* fourth row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 19 ], diff_Q14_4 );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWT( sum2_Q16, W_Q18[ 18 ], diff_Q14_23 );
+ sum1_Q14 = SKP_SMLAWT( sum1_Q14, sum2_Q16, diff_Q14_23 );
+
+ /* last row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 24 ], diff_Q14_4 );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14_4 );
+#else
+ /* first row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 1 ], diff_Q14[ 1 ] );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14[ 2 ] );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 3 ], diff_Q14[ 3 ] );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14[ 4 ] );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] );
+
+ /* second row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] );
+
+ /* third row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] );
+
+ /* fourth row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] );
+ sum2_Q16 = SKP_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = SKP_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] );
+
+ /* last row of W_Q18 */
+ sum2_Q16 = SKP_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] );
+ sum1_Q14 = SKP_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] );
+#endif
+
+ SKP_assert( sum1_Q14 >= 0 );
+
+ /* find best */
+ if( sum1_Q14 < *rate_dist_Q14 ) {
+ *rate_dist_Q14 = sum1_Q14;
+ *ind = k;
+ }
+
+ /* Go to next cbk vector */
+ cb_row_Q14 += LTP_ORDER;
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_ana_filt_bank_1.c b/pkg/silk/csilk/SKP_Silk_ana_filt_bank_1.c
new file mode 100644
index 0000000..206f3b5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_ana_filt_bank_1.c
@@ -0,0 +1,82 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_ana_filt_bank_1.c *
+ * *
+ * Split signal into two decimated bands using first-order allpass filters *
+ * *
+ * Copyright 2006 (c), Skype Limited *
+ * Date: 060221 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+#if EMBEDDED_ARM<5
+/* Coefficients for 2-band filter bank based on first-order allpass filters */
+// old
+static SKP_int16 A_fb1_20[ 1 ] = { 5394 << 1 };
+static SKP_int16 A_fb1_21[ 1 ] = { (SKP_int16) (20623 << 1) }; /* wrap-around to negative number is intentional */
+
+/* Split signal into two decimated bands using first-order allpass filters */
+void SKP_Silk_ana_filt_bank_1(
+ const SKP_int16 *in, /* I: Input signal [N] */
+ SKP_int32 *S, /* I/O: State vector [2] */
+ SKP_int16 *outL, /* O: Low band [N/2] */
+ SKP_int16 *outH, /* O: High band [N/2] */
+ SKP_int32 *scratch, /* I: Scratch memory [3*N/2] */ // todo: remove - no longer used
+ const SKP_int32 N /* I: Number of input samples */
+)
+{
+ SKP_int k, N2 = SKP_RSHIFT( N, 1 );
+ SKP_int32 in32, X, Y, out_1, out_2;
+
+ /* Internal variables and state are in Q10 format */
+ for( k = 0; k < N2; k++ ) {
+ /* Convert to Q10 */
+ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 );
+
+ /* All-pass section for even input sample */
+ Y = SKP_SUB32( in32, S[ 0 ] );
+ X = SKP_SMLAWB( Y, Y, A_fb1_21[ 0 ] );
+ out_1 = SKP_ADD32( S[ 0 ], X );
+ S[ 0 ] = SKP_ADD32( in32, X );
+
+ /* Convert to Q10 */
+ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 );
+
+ /* All-pass section for odd input sample */
+ Y = SKP_SUB32( in32, S[ 1 ] );
+ X = SKP_SMULWB( Y, A_fb1_20[ 0 ] );
+ out_2 = SKP_ADD32( S[ 1 ], X );
+ S[ 1 ] = SKP_ADD32( in32, X );
+
+ /* Add/subtract, convert back to int16 and store to output */
+ outL[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_ADD32( out_2, out_1 ), 11 ) );
+ outH[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( out_2, out_1 ), 11 ) );
+ }
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_apply_sine_window.c b/pkg/silk/csilk/SKP_Silk_apply_sine_window.c
new file mode 100644
index 0000000..b7706d7
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_apply_sine_window.c
@@ -0,0 +1,120 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SigProc_FIX.h"
+
+/* Apply sine window to signal vector. */
+/* Window types: */
+/* 1 -> sine window from 0 to pi/2 */
+/* 2 -> sine window from pi/2 to pi */
+/* Every other sample is linearly interpolated, for speed. */
+/* Window length must be between 16 and 120 (incl) and a multiple of 4. */
+
+/* Matlab code for table:
+ for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end
+*/
+static SKP_int16 freq_table_Q16[ 27 ] = {
+ 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202,
+ 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422,
+ 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702,
+};
+
+//#if EMBEDDED_ARM<6
+void SKP_Silk_apply_sine_window(
+ SKP_int16 px_win[], /* O Pointer to windowed signal */
+ const SKP_int16 px[], /* I Pointer to input signal */
+ const SKP_int win_type, /* I Selects a window type */
+ const SKP_int length /* I Window length, multiple of 4 */
+)
+{
+ SKP_int k, f_Q16, c_Q16;
+ SKP_int32 S0_Q16, S1_Q16;
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 px32;
+#endif
+ SKP_assert( win_type == 1 || win_type == 2 );
+
+ /* Length must be in a range from 16 to 120 and a multiple of 4 */
+ SKP_assert( length >= 16 && length <= 120 );
+ SKP_assert( ( length & 3 ) == 0 );
+
+ /* Input pointer must be 4-byte aligned */
+ SKP_assert( ( ( SKP_int64 )( ( SKP_int8* )px - ( SKP_int8* )0 ) & 3 ) == 0 );
+
+ /* Frequency */
+ k = ( length >> 2 ) - 4;
+ SKP_assert( k >= 0 && k <= 26 );
+ f_Q16 = (SKP_int)freq_table_Q16[ k ];
+
+ /* Factor used for cosine approximation */
+ c_Q16 = SKP_SMULWB( f_Q16, -f_Q16 );
+ SKP_assert( c_Q16 >= -32768 );
+
+ /* initialize state */
+ if( win_type == 1 ) {
+ /* start from 0 */
+ S0_Q16 = 0;
+ /* approximation of sin(f) */
+ S1_Q16 = f_Q16 + SKP_RSHIFT( length, 3 );
+ } else {
+ /* start from 1 */
+ S0_Q16 = ( 1 << 16 );
+ /* approximation of cos(f) */
+ S1_Q16 = ( 1 << 16 ) + SKP_RSHIFT( c_Q16, 1 ) + SKP_RSHIFT( length, 4 );
+ }
+
+ /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
+ /* 4 samples at a time */
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ for( k = 0; k < length; k += 4 ) {
+ px32 = *( (SKP_int32 *)&px[ k ] ); /* load two values at once */
+ px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px32 );
+ px_win[ k + 1 ] = (SKP_int16)SKP_SMULWT( S1_Q16, px32 );
+ S0_Q16 = SKP_SMULWB( S1_Q16, c_Q16 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
+ S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) );
+
+ px32 = *( (SKP_int32 *)&px[k + 2] ); /* load two values at once */
+ px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px32 );
+ px_win[ k + 3 ] = (SKP_int16)SKP_SMULWT( S0_Q16, px32 );
+ S1_Q16 = SKP_SMULWB( S0_Q16, c_Q16 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16;
+ S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) );
+ }
+#else
+ for( k = 0; k < length; k += 4 ) {
+ px_win[ k ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
+ px_win[ k + 1 ] = (SKP_int16)SKP_SMULWB( S1_Q16, px[ k + 1] );
+ S0_Q16 = SKP_SMULWB( S1_Q16, c_Q16 ) + SKP_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
+ S0_Q16 = SKP_min( S0_Q16, ( 1 << 16 ) );
+
+ px_win[ k + 2 ] = (SKP_int16)SKP_SMULWB( SKP_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
+ px_win[ k + 3 ] = (SKP_int16)SKP_SMULWB( S0_Q16, px[ k + 3 ] );
+ S1_Q16 = SKP_SMULWB( S0_Q16, c_Q16 ) + SKP_LSHIFT( S0_Q16, 1 ) - S1_Q16;
+ S1_Q16 = SKP_min( S1_Q16, ( 1 << 16 ) );
+ }
+#endif
+}
+//#endif
diff --git a/pkg/silk/csilk/SKP_Silk_array_maxabs.c b/pkg/silk/csilk/SKP_Silk_array_maxabs.c
new file mode 100644
index 0000000..0d6be63
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_array_maxabs.c
@@ -0,0 +1,70 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_int16_array_maxabs.c *
+ * *
+ * Function that returns the maximum absolut value of *
+ * the input vector *
+ * *
+ * Copyright 2006 (c), Skype Limited *
+ * Date: 060221 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Function that returns the maximum absolut value of the input vector */
+#if (EMBEDDED_ARM<4)
+SKP_int16 SKP_Silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */
+ const SKP_int16 *vec, /* I Input vector [len] */
+ const SKP_int32 len /* I Length of input vector */
+)
+{
+ SKP_int32 max = 0, i, lvl = 0, ind;
+ if( len == 0 ) return 0;
+
+ ind = len - 1;
+ max = SKP_SMULBB( vec[ ind ], vec[ ind ] );
+ for( i = len - 2; i >= 0; i-- ) {
+ lvl = SKP_SMULBB( vec[ i ], vec[ i ] );
+ if( lvl > max ) {
+ max = lvl;
+ ind = i;
+ }
+ }
+
+ /* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */
+ if( max >= 1073676289 ) { // (2^15-1)^2 = 1073676289
+ return( SKP_int16_MAX );
+ } else {
+ if( vec[ ind ] < 0 ) {
+ return( -vec[ ind ] );
+ } else {
+ return( vec[ ind ] );
+ }
+ }
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_autocorr.c b/pkg/silk/csilk/SKP_Silk_autocorr.c
new file mode 100644
index 0000000..39ca5ab
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_autocorr.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_autocorr.c *
+ * *
+ * Calculates the autocorrelation *
+ * The result has 29 non-zero bits for the first correlation, to leave *
+ * some room for adding white noise fractions etc. *
+ * *
+ * Copyright 2008 (c), Skype Limited *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Compute autocorrelation */
+void SKP_Silk_autocorr(
+ SKP_int32 *results, /* O Result (length correlationCount) */
+ SKP_int *scale, /* O Scaling of the correlation vector */
+ const SKP_int16 *inputData, /* I Input data to correlate */
+ const SKP_int inputDataSize, /* I Length of input */
+ const SKP_int correlationCount /* I Number of correlation taps to compute */
+)
+{
+ SKP_int i, lz, nRightShifts, corrCount;
+ SKP_int64 corr64;
+
+ corrCount = SKP_min_int( inputDataSize, correlationCount );
+
+ /* compute energy (zero-lag correlation) */
+ corr64 = SKP_Silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize );
+
+ /* deal with all-zero input data */
+ corr64 += 1;
+
+ /* number of leading zeros */
+ lz = SKP_Silk_CLZ64( corr64 );
+
+ /* scaling: number of right shifts applied to correlations */
+ nRightShifts = 35 - lz;
+ *scale = nRightShifts;
+
+ if( nRightShifts <= 0 ) {
+ results[ 0 ] = SKP_LSHIFT( (SKP_int32)SKP_CHECK_FIT32( corr64 ), -nRightShifts );
+
+ /* compute remaining correlations based on int32 inner product */
+ for( i = 1; i < corrCount; i++ ) {
+ results[ i ] = SKP_LSHIFT( SKP_Silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts );
+ }
+ } else {
+ results[ 0 ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( corr64, nRightShifts ) );
+
+ /* compute remaining correlations based on int64 inner product */
+ for( i = 1; i < corrCount; i++ ) {
+ results[ i ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( SKP_Silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) );
+ }
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_biquad.c b/pkg/silk/csilk/SKP_Silk_biquad.c
new file mode 100644
index 0000000..f98de55
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_biquad.c
@@ -0,0 +1,72 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_biquad.c *
+ * *
+ * Second order ARMA filter *
+ * Can handle slowly varying filter coefficients *
+ * *
+ * Copyright 2006 (c), Skype Limited *
+ * Date: 060221 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Second order ARMA filter */
+/* Can handle slowly varying filter coefficients */
+void SKP_Silk_biquad(
+ const SKP_int16 *in, /* I: input signal */
+ const SKP_int16 *B, /* I: MA coefficients, Q13 [3] */
+ const SKP_int16 *A, /* I: AR coefficients, Q13 [2] */
+ SKP_int32 *S, /* I/O: state vector [2] */
+ SKP_int16 *out, /* O: output signal */
+ const SKP_int32 len /* I: signal length */
+)
+{
+ SKP_int k, in16;
+ SKP_int32 A0_neg, A1_neg, S0, S1, out32, tmp32;
+
+ S0 = S[ 0 ];
+ S1 = S[ 1 ];
+ A0_neg = -A[ 0 ];
+ A1_neg = -A[ 1 ];
+ for( k = 0; k < len; k++ ) {
+ /* S[ 0 ], S[ 1 ]: Q13 */
+ in16 = in[ k ];
+ out32 = SKP_SMLABB( S0, in16, B[ 0 ] );
+
+ S0 = SKP_SMLABB( S1, in16, B[ 1 ] );
+ S0 += SKP_LSHIFT( SKP_SMULWB( out32, A0_neg ), 3 );
+
+ S1 = SKP_LSHIFT( SKP_SMULWB( out32, A1_neg ), 3 );
+ S1 = SKP_SMLABB( S1, in16, B[ 2 ] );
+ tmp32 = SKP_RSHIFT_ROUND( out32, 13 ) + 1;
+ out[ k ] = (SKP_int16)SKP_SAT16( tmp32 );
+ }
+ S[ 0 ] = S0;
+ S[ 1 ] = S1;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_biquad_alt.c b/pkg/silk/csilk/SKP_Silk_biquad_alt.c
new file mode 100644
index 0000000..90c27ac
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_biquad_alt.c
@@ -0,0 +1,73 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_biquad_alt.c *
+ * *
+ * Second order ARMA filter *
+ * Can handle slowly varying filter coefficients *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+
+/* Second order ARMA filter, alternative implementation */
+void SKP_Silk_biquad_alt(
+ const SKP_int16 *in, /* I: Input signal */
+ const SKP_int32 *B_Q28, /* I: MA coefficients [3] */
+ const SKP_int32 *A_Q28, /* I: AR coefficients [2] */
+ SKP_int32 *S, /* I/O: State vector [2] */
+ SKP_int16 *out, /* O: Output signal */
+ const SKP_int32 len /* I: Signal length (must be even) */
+)
+{
+ /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
+ SKP_int k;
+ SKP_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;
+
+ /* Negate A_Q28 values and split in two parts */
+ A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
+ A0_U_Q28 = SKP_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
+ A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
+ A1_U_Q28 = SKP_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
+
+ for( k = 0; k < len; k++ ) {
+ /* S[ 0 ], S[ 1 ]: Q12 */
+ inval = in[ k ];
+ out32_Q14 = SKP_LSHIFT( SKP_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
+
+ S[ 0 ] = S[1] + SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
+ S[ 0 ] = SKP_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );
+ S[ 0 ] = SKP_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);
+
+ S[ 1 ] = SKP_RSHIFT_ROUND( SKP_SMULWB( out32_Q14, A1_L_Q28 ), 14 );
+ S[ 1 ] = SKP_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );
+ S[ 1 ] = SKP_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
+
+ /* Scale back to Q0 and saturate */
+ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_burg_modified.c b/pkg/silk/csilk/SKP_Silk_burg_modified.c
new file mode 100644
index 0000000..8708b8b
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_burg_modified.c
@@ -0,0 +1,229 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_burg_modified.c *
+ * *
+ * Calculates the reflection coefficients from the input vector *
+ * Input vector contains nb_subfr sub vectors of length L_sub + D *
+ * *
+ * Copyright 2009 (c), Skype Limited *
+ * Date: 100105 *
+ */
+
+#include "SKP_Silk_SigProc_FIX.h"
+
+#define MAX_FRAME_SIZE 544 // subfr_length * nb_subfr = ( 0.005 * 24000 + 16 ) * 4 = 544
+#define MAX_NB_SUBFR 4
+
+#undef QA
+#define QA 25
+#define N_BITS_HEAD_ROOM 2
+#define MIN_RSHIFTS -16
+#define MAX_RSHIFTS (32 - QA)
+
+/* Compute reflection coefficients from input signal */
+void SKP_Silk_burg_modified(
+ SKP_int32 *res_nrg, /* O residual energy */
+ SKP_int *res_nrg_Q, /* O residual energy Q value */
+ SKP_int32 A_Q16[], /* O prediction coefficients (length order) */
+ const SKP_int16 x[], /* I input signal, length: nb_subfr * ( D + subfr_length ) */
+ const SKP_int subfr_length, /* I input signal subframe length (including D preceeding samples) */
+ const SKP_int nb_subfr, /* I number of subframes stacked in x */
+ const SKP_int32 WhiteNoiseFrac_Q32, /* I fraction added to zero-lag autocorrelation */
+ const SKP_int D /* I order */
+)
+{
+ SKP_int k, n, s, lz, rshifts, rshifts_extra;
+ SKP_int32 C0, num, nrg, rc_Q31, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
+ const SKP_int16 *x_ptr;
+
+ SKP_int32 C_first_row[ SKP_Silk_MAX_ORDER_LPC ];
+ SKP_int32 C_last_row[ SKP_Silk_MAX_ORDER_LPC ];
+ SKP_int32 Af_QA[ SKP_Silk_MAX_ORDER_LPC ];
+
+ SKP_int32 CAf[ SKP_Silk_MAX_ORDER_LPC + 1 ];
+ SKP_int32 CAb[ SKP_Silk_MAX_ORDER_LPC + 1 ];
+
+ SKP_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+ SKP_assert( nb_subfr <= MAX_NB_SUBFR );
+
+
+ /* Compute autocorrelations, added over subframes */
+ SKP_Silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
+ if( rshifts > MAX_RSHIFTS ) {
+ C0 = SKP_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
+ SKP_assert( C0 > 0 );
+ rshifts = MAX_RSHIFTS;
+ } else {
+ lz = SKP_Silk_CLZ32( C0 ) - 1;
+ rshifts_extra = N_BITS_HEAD_ROOM - lz;
+ if( rshifts_extra > 0 ) {
+ rshifts_extra = SKP_min( rshifts_extra, MAX_RSHIFTS - rshifts );
+ C0 = SKP_RSHIFT32( C0, rshifts_extra );
+ } else {
+ rshifts_extra = SKP_max( rshifts_extra, MIN_RSHIFTS - rshifts );
+ C0 = SKP_LSHIFT32( C0, -rshifts_extra );
+ }
+ rshifts += rshifts_extra;
+ }
+ SKP_memset( C_first_row, 0, SKP_Silk_MAX_ORDER_LPC * sizeof( SKP_int32 ) );
+ if( rshifts > 0 ) {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ for( n = 1; n < D + 1; n++ ) {
+ C_first_row[ n - 1 ] += (SKP_int32)SKP_RSHIFT64(
+ SKP_Silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n ), rshifts );
+ }
+ }
+ } else {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ for( n = 1; n < D + 1; n++ ) {
+ C_first_row[ n - 1 ] += SKP_LSHIFT32(
+ SKP_Silk_inner_prod_aligned( x_ptr, x_ptr + n, subfr_length - n ), -rshifts );
+ }
+ }
+ }
+ SKP_memcpy( C_last_row, C_first_row, SKP_Silk_MAX_ORDER_LPC * sizeof( SKP_int32 ) );
+
+ /* Initialize */
+ CAb[ 0 ] = CAf[ 0 ] = C0 + SKP_SMMUL( WhiteNoiseFrac_Q32, C0 ) + 1; // Q(-rshifts)
+
+ for( n = 0; n < D; n++ ) {
+ /* Update first row of correlation matrix (without first element) */
+ /* Update last row of correlation matrix (without last element, stored in reversed order) */
+ /* Update C * Af */
+ /* Update C * flipud(Af) (stored in reversed order) */
+ if( rshifts > -2 ) {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ x1 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], 16 - rshifts ); // Q(16-rshifts)
+ x2 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); // Q(16-rshifts)
+ tmp1 = SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], QA - 16 ); // Q(QA-16)
+ tmp2 = SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); // Q(QA-16)
+ for( k = 0; k < n; k++ ) {
+ C_first_row[ k ] = SKP_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); // Q( -rshifts )
+ C_last_row[ k ] = SKP_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); // Q( -rshifts )
+ Atmp_QA = Af_QA[ k ];
+ tmp1 = SKP_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); // Q(QA-16)
+ tmp2 = SKP_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); // Q(QA-16)
+ }
+ tmp1 = SKP_LSHIFT32( -tmp1, 32 - QA - rshifts ); // Q(16-rshifts)
+ tmp2 = SKP_LSHIFT32( -tmp2, 32 - QA - rshifts ); // Q(16-rshifts)
+ for( k = 0; k <= n; k++ ) {
+ CAf[ k ] = SKP_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); // Q( -rshift )
+ CAb[ k ] = SKP_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); // Q( -rshift )
+ }
+ }
+ } else {
+ for( s = 0; s < nb_subfr; s++ ) {
+ x_ptr = x + s * subfr_length;
+ x1 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], -rshifts ); // Q( -rshifts )
+ x2 = -SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); // Q( -rshifts )
+ tmp1 = SKP_LSHIFT32( (SKP_int32)x_ptr[ n ], 17 ); // Q17
+ tmp2 = SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n - 1 ], 17 ); // Q17
+ for( k = 0; k < n; k++ ) {
+ C_first_row[ k ] = SKP_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); // Q( -rshifts )
+ C_last_row[ k ] = SKP_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); // Q( -rshifts )
+ Atmp1 = SKP_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); // Q17
+ tmp1 = SKP_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); // Q17
+ tmp2 = SKP_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); // Q17
+ }
+ tmp1 = -tmp1; // Q17
+ tmp2 = -tmp2; // Q17
+ for( k = 0; k <= n; k++ ) {
+ CAf[ k ] = SKP_SMLAWW( CAf[ k ], tmp1,
+ SKP_LSHIFT32( (SKP_int32)x_ptr[ n - k ], -rshifts - 1 ) ); // Q( -rshift )
+ CAb[ k ] = SKP_SMLAWW( CAb[ k ], tmp2,
+ SKP_LSHIFT32( (SKP_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) );// Q( -rshift )
+ }
+ }
+ }
+
+ /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
+ tmp1 = C_first_row[ n ]; // Q( -rshifts )
+ tmp2 = C_last_row[ n ]; // Q( -rshifts )
+ num = 0; // Q( -rshifts )
+ nrg = SKP_ADD32( CAb[ 0 ], CAf[ 0 ] ); // Q( 1-rshifts )
+ for( k = 0; k < n; k++ ) {
+ Atmp_QA = Af_QA[ k ];
+ lz = SKP_Silk_CLZ32( SKP_abs( Atmp_QA ) ) - 1;
+ lz = SKP_min( 32 - QA, lz );
+ Atmp1 = SKP_LSHIFT32( Atmp_QA, lz ); // Q( QA + lz )
+
+ tmp1 = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts )
+ tmp2 = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts )
+ num = SKP_ADD_LSHIFT32( num, SKP_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); // Q( -rshifts )
+ nrg = SKP_ADD_LSHIFT32( nrg, SKP_SMMUL( SKP_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
+ Atmp1 ), 32 - QA - lz ); // Q( 1-rshifts )
+ }
+ CAf[ n + 1 ] = tmp1; // Q( -rshifts )
+ CAb[ n + 1 ] = tmp2; // Q( -rshifts )
+ num = SKP_ADD32( num, tmp2 ); // Q( -rshifts )
+ num = SKP_LSHIFT32( -num, 1 ); // Q( 1-rshifts )
+
+ /* Calculate the next order reflection (parcor) coefficient */
+ if( SKP_abs( num ) < nrg ) {
+ rc_Q31 = SKP_DIV32_varQ( num, nrg, 31 );
+ } else {
+ /* Negative energy or ratio too high; set remaining coefficients to zero and exit loop */
+ SKP_memset( &Af_QA[ n ], 0, ( D - n ) * sizeof( SKP_int32 ) );
+ SKP_assert( 0 );
+ break;
+ }
+
+ /* Update the AR coefficients */
+ for( k = 0; k < (n + 1) >> 1; k++ ) {
+ tmp1 = Af_QA[ k ]; // QA
+ tmp2 = Af_QA[ n - k - 1 ]; // QA
+ Af_QA[ k ] = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( tmp2, rc_Q31 ), 1 ); // QA
+ Af_QA[ n - k - 1 ] = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( tmp1, rc_Q31 ), 1 ); // QA
+ }
+ Af_QA[ n ] = SKP_RSHIFT32( rc_Q31, 31 - QA ); // QA
+
+ /* Update C * Af and C * Ab */
+ for( k = 0; k <= n + 1; k++ ) {
+ tmp1 = CAf[ k ]; // Q( -rshifts )
+ tmp2 = CAb[ n - k + 1 ]; // Q( -rshifts )
+ CAf[ k ] = SKP_ADD_LSHIFT32( tmp1, SKP_SMMUL( tmp2, rc_Q31 ), 1 ); // Q( -rshifts )
+ CAb[ n - k + 1 ] = SKP_ADD_LSHIFT32( tmp2, SKP_SMMUL( tmp1, rc_Q31 ), 1 ); // Q( -rshifts )
+ }
+ }
+
+ /* Return residual energy */
+ nrg = CAf[ 0 ]; // Q( -rshifts )
+ tmp1 = 1 << 16; // Q16
+ for( k = 0; k < D; k++ ) {
+ Atmp1 = SKP_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); // Q16
+ nrg = SKP_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); // Q( -rshifts )
+ tmp1 = SKP_SMLAWW( tmp1, Atmp1, Atmp1 ); // Q16
+ A_Q16[ k ] = -Atmp1;
+ }
+ *res_nrg = SKP_SMLAWW( nrg, SKP_SMMUL( WhiteNoiseFrac_Q32, C0 ), -tmp1 ); // Q( -rshifts )
+ *res_nrg_Q = -rshifts;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_bwexpander.c b/pkg/silk/csilk/SKP_Silk_bwexpander.c
new file mode 100644
index 0000000..6affb6b
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_bwexpander.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SigProc_FIX.h"
+
+/* Chirp (bandwidth expand) LP AR filter */
+void SKP_Silk_bwexpander(
+ SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
+ const SKP_int d, /* I Length of ar */
+ SKP_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
+)
+{
+ SKP_int i;
+ SKP_int32 chirp_minus_one_Q16;
+
+ chirp_minus_one_Q16 = chirp_Q16 - 65536;
+
+ /* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL() , 16 ), below. */
+ /* Bias in SKP_SMULWB can lead to unstable filters */
+ for( i = 0; i < d - 1; i++ ) {
+ ar[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ i ] ), 16 );
+ chirp_Q16 += SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
+ }
+ ar[ d - 1 ] = (SKP_int16)SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_bwexpander_32.c b/pkg/silk/csilk/SKP_Silk_bwexpander_32.c
new file mode 100644
index 0000000..0a83869
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_bwexpander_32.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SigProc_FIX.h"
+
+/* Chirp (bandwidth expand) LP AR filter */
+void SKP_Silk_bwexpander_32(
+ SKP_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
+ const SKP_int d, /* I Length of ar */
+ SKP_int32 chirp_Q16 /* I Chirp factor in Q16 */
+)
+{
+ SKP_int i;
+ SKP_int32 tmp_chirp_Q16;
+
+ tmp_chirp_Q16 = chirp_Q16;
+ for( i = 0; i < d - 1; i++ ) {
+ ar[ i ] = SKP_SMULWW( ar[ i ], tmp_chirp_Q16 );
+ tmp_chirp_Q16 = SKP_SMULWW( chirp_Q16, tmp_chirp_Q16 );
+ }
+ ar[ d - 1 ] = SKP_SMULWW( ar[ d - 1 ], tmp_chirp_Q16 );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_code_signs.c b/pkg/silk/csilk/SKP_Silk_code_signs.c
new file mode 100644
index 0000000..3149f4a
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_code_signs.c
@@ -0,0 +1,91 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+//#define SKP_enc_map(a) ((a) > 0 ? 1 : 0)
+//#define SKP_dec_map(a) ((a) > 0 ? 1 : -1)
+/* shifting avoids if-statement */
+#define SKP_enc_map(a) ( SKP_RSHIFT( (a), 15 ) + 1 )
+#define SKP_dec_map(a) ( SKP_LSHIFT( (a), 1 ) - 1 )
+
+/* Encodes signs of excitation */
+void SKP_Silk_encode_signs(
+ SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */
+ const SKP_int8 q[], /* I Pulse signal */
+ const SKP_int length, /* I Length of input */
+ const SKP_int sigtype, /* I Signal type */
+ const SKP_int QuantOffsetType, /* I Quantization offset type */
+ const SKP_int RateLevelIndex /* I Rate level index */
+)
+{
+ SKP_int i;
+ SKP_int inData;
+ SKP_uint16 cdf[ 3 ];
+
+ i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
+ cdf[ 0 ] = 0;
+ cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
+ cdf[ 2 ] = 65535;
+
+ for( i = 0; i < length; i++ ) {
+ if( q[ i ] != 0 ) {
+ inData = SKP_enc_map( q[ i ] ); /* - = 0, + = 1 */
+ SKP_Silk_range_encoder( sRC, inData, cdf );
+ }
+ }
+}
+
+/* Decodes signs of excitation */
+void SKP_Silk_decode_signs(
+ SKP_Silk_range_coder_state *sRC, /* I/O Range coder state */
+ SKP_int q[], /* I/O pulse signal */
+ const SKP_int length, /* I length of output */
+ const SKP_int sigtype, /* I Signal type */
+ const SKP_int QuantOffsetType, /* I Quantization offset type */
+ const SKP_int RateLevelIndex /* I Rate Level Index */
+)
+{
+ SKP_int i;
+ SKP_int data;
+ SKP_uint16 cdf[ 3 ];
+
+ i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
+ cdf[ 0 ] = 0;
+ cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
+ cdf[ 2 ] = 65535;
+
+ for( i = 0; i < length; i++ ) {
+ if( q[ i ] > 0 ) {
+ SKP_Silk_range_decoder( &data, sRC, cdf, 1 );
+ /* attach sign */
+ /* implementation with shift, subtraction, multiplication */
+ q[ i ] *= SKP_dec_map( data );
+ }
+ }
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_common_pitch_est_defines.h b/pkg/silk/csilk/SKP_Silk_common_pitch_est_defines.h
new file mode 100644
index 0000000..7ca23d3
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_common_pitch_est_defines.h
@@ -0,0 +1,76 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SIGPROC_COMMON_PITCH_EST_DEFINES_H
+#define SIGPROC_COMMON_PITCH_EST_DEFINES_H
+
+#include "SKP_Silk_SigProc_FIX.h"
+
+/************************************************************/
+/* Definitions For Fix pitch estimator */
+/************************************************************/
+
+#define PITCH_EST_MAX_FS_KHZ 24 /* Maximum sampling frequency used */
+
+#define PITCH_EST_FRAME_LENGTH_MS 40 /* 40 ms */
+
+#define PITCH_EST_MAX_FRAME_LENGTH (PITCH_EST_FRAME_LENGTH_MS * PITCH_EST_MAX_FS_KHZ)
+#define PITCH_EST_MAX_FRAME_LENGTH_ST_1 (PITCH_EST_MAX_FRAME_LENGTH >> 2)
+#define PITCH_EST_MAX_FRAME_LENGTH_ST_2 (PITCH_EST_MAX_FRAME_LENGTH >> 1)
+#define PITCH_EST_MAX_SF_FRAME_LENGTH (PITCH_EST_SUB_FRAME * PITCH_EST_MAX_FS_KHZ)
+
+#define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */
+#define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */
+#define PITCH_EST_MAX_LAG (PITCH_EST_MAX_LAG_MS * PITCH_EST_MAX_FS_KHZ)
+#define PITCH_EST_MIN_LAG (PITCH_EST_MIN_LAG_MS * PITCH_EST_MAX_FS_KHZ)
+
+#define PITCH_EST_NB_SUBFR 4
+
+#define PITCH_EST_D_SRCH_LENGTH 24
+
+#define PITCH_EST_MAX_DECIMATE_STATE_LENGTH 7
+
+#define PITCH_EST_NB_STAGE3_LAGS 5
+
+#define PITCH_EST_NB_CBKS_STAGE2 3
+#define PITCH_EST_NB_CBKS_STAGE2_EXT 11
+
+#define PITCH_EST_CB_mn2 1
+#define PITCH_EST_CB_mx2 2
+
+#define PITCH_EST_NB_CBKS_STAGE3_MAX 34
+#define PITCH_EST_NB_CBKS_STAGE3_MID 24
+#define PITCH_EST_NB_CBKS_STAGE3_MIN 16
+
+extern const SKP_int16 SKP_Silk_CB_lags_stage2[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE2_EXT];
+extern const SKP_int16 SKP_Silk_CB_lags_stage3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX];
+extern const SKP_int16 SKP_Silk_Lag_range_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ] [ PITCH_EST_NB_SUBFR ][ 2 ];
+extern const SKP_int16 SKP_Silk_cbk_sizes_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ];
+extern const SKP_int16 SKP_Silk_cbk_offsets_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ];
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_control.h b/pkg/silk/csilk/SKP_Silk_control.h
new file mode 100644
index 0000000..ef0eac2
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_control.h
@@ -0,0 +1,91 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_CONTROL_H
+#define SKP_SILK_CONTROL_H
+
+#include "SKP_Silk_typedef.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/***********************************************/
+/* Structure for controlling encoder operation */
+/***********************************************/
+typedef struct {
+ /* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000 */
+ SKP_int32 API_sampleRate;
+
+ /* I: Maximum internal sampling rate in Hertz; 8000/12000/16000/24000 */
+ SKP_int32 maxInternalSampleRate;
+
+ /* I: Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms */
+ SKP_int packetSize;
+
+ /* I: Bitrate during active speech in bits/second; internally limited */
+ SKP_int32 bitRate;
+
+ /* I: Uplink packet loss in percent (0-100) */
+ SKP_int packetLossPercentage;
+
+ /* I: Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity */
+ SKP_int complexity;
+
+ /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
+ SKP_int useInBandFEC;
+
+ /* I: Flag to enable discontinuous transmission (DTX); 0/1 */
+ SKP_int useDTX;
+} SKP_SILK_SDK_EncControlStruct;
+
+/**************************************************************************/
+/* Structure for controlling decoder operation and reading decoder status */
+/**************************************************************************/
+typedef struct {
+ /* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000 */
+ SKP_int32 API_sampleRate;
+
+ /* O: Number of samples per frame */
+ SKP_int frameSize;
+
+ /* O: Frames per packet 1, 2, 3, 4, 5 */
+ SKP_int framesPerPacket;
+
+ /* O: Flag to indicate that the decoder has remaining payloads internally */
+ SKP_int moreInternalDecoderFrames;
+
+ /* O: Distance between main payload and redundant payload in packets */
+ SKP_int inBandFECOffset;
+} SKP_SILK_SDK_DecControlStruct;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_control_audio_bandwidth.c b/pkg/silk/csilk/SKP_Silk_control_audio_bandwidth.c
new file mode 100644
index 0000000..e7bed0c
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_control_audio_bandwidth.c
@@ -0,0 +1,137 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Control internal sampling rate */
+SKP_int SKP_Silk_control_audio_bandwidth(
+ SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
+ const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
+)
+{
+ SKP_int fs_kHz;
+
+ fs_kHz = psEncC->fs_kHz;
+ if( fs_kHz == 0 ) {
+ /* Encoder has just been initialized */
+ if( TargetRate_bps >= SWB2WB_BITRATE_BPS ) {
+ fs_kHz = 24;
+ } else if( TargetRate_bps >= WB2MB_BITRATE_BPS ) {
+ fs_kHz = 16;
+ } else if( TargetRate_bps >= MB2NB_BITRATE_BPS ) {
+ fs_kHz = 12;
+ } else {
+ fs_kHz = 8;
+ }
+ /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */
+ fs_kHz = SKP_min( fs_kHz, SKP_DIV32_16( psEncC->API_fs_Hz, 1000 ) );
+ fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz );
+ } else if( SKP_SMULBB( fs_kHz, 1000 ) > psEncC->API_fs_Hz || fs_kHz > psEncC->maxInternal_fs_kHz ) {
+ /* Make sure internal rate is not higher than external rate or maximum allowed */
+ fs_kHz = SKP_DIV32_16( psEncC->API_fs_Hz, 1000 );
+ fs_kHz = SKP_min( fs_kHz, psEncC->maxInternal_fs_kHz );
+ } else {
+ /* State machine for the internal sampling rate switching */
+ if( psEncC->API_fs_Hz > 8000 ) {
+ /* Accumulate the difference between the target rate and limit for switching down */
+ psEncC->bitrateDiff += SKP_MUL( psEncC->PacketSize_ms, TargetRate_bps - psEncC->bitrate_threshold_down );
+ psEncC->bitrateDiff = SKP_min( psEncC->bitrateDiff, 0 );
+
+ if( psEncC->vadFlag == NO_VOICE_ACTIVITY ) { /* Low speech activity */
+ /* Check if we should switch down */
+#if SWITCH_TRANSITION_FILTERING
+ if( ( psEncC->sLP.transition_frame_no == 0 ) && /* Transition phase not active */
+ ( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || /* Bitrate threshold is met */
+ ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz == 24 ) ) ) { /* Forced down-switching due to WB input */
+ psEncC->sLP.transition_frame_no = 1; /* Begin transition phase */
+ psEncC->sLP.mode = 0; /* Switch down */
+ } else if(
+ ( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && /* Transition phase complete */
+ ( psEncC->sLP.mode == 0 ) ) { /* Ready to switch down */
+ psEncC->sLP.transition_frame_no = 0; /* Ready for new transition phase */
+#else
+ if( psEncC->bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) { /* Bitrate threshold is met */
+#endif
+ psEncC->bitrateDiff = 0;
+
+ /* Switch to a lower sample frequency */
+ if( psEncC->fs_kHz == 24 ) {
+ fs_kHz = 16;
+ } else if( psEncC->fs_kHz == 16 ) {
+ fs_kHz = 12;
+ } else {
+ SKP_assert( psEncC->fs_kHz == 12 );
+ fs_kHz = 8;
+ }
+ }
+
+ /* Check if we should switch up */
+ if( ( ( psEncC->fs_kHz * 1000 < psEncC->API_fs_Hz ) &&
+ ( TargetRate_bps >= psEncC->bitrate_threshold_up ) &&
+ ( psEncC->sSWBdetect.WB_detected * psEncC->fs_kHz < 16 ) ) &&
+ ( ( ( psEncC->fs_kHz == 16 ) && ( psEncC->maxInternal_fs_kHz >= 24 ) ) ||
+ ( ( psEncC->fs_kHz == 12 ) && ( psEncC->maxInternal_fs_kHz >= 16 ) ) ||
+ ( ( psEncC->fs_kHz == 8 ) && ( psEncC->maxInternal_fs_kHz >= 12 ) ) )
+#if SWITCH_TRANSITION_FILTERING
+ && ( psEncC->sLP.transition_frame_no == 0 ) ) { /* No transition phase running, ready to switch */
+ psEncC->sLP.mode = 1; /* Switch up */
+#else
+ ) {
+#endif
+ psEncC->bitrateDiff = 0;
+
+ /* Switch to a higher sample frequency */
+ if( psEncC->fs_kHz == 8 ) {
+ fs_kHz = 12;
+ } else if( psEncC->fs_kHz == 12 ) {
+ fs_kHz = 16;
+ } else {
+ SKP_assert( psEncC->fs_kHz == 16 );
+ fs_kHz = 24;
+ }
+ }
+ }
+ }
+
+#if SWITCH_TRANSITION_FILTERING
+ /* After switching up, stop transition filter during speech inactivity */
+ if( ( psEncC->sLP.mode == 1 ) &&
+ ( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES_UP ) &&
+ ( psEncC->vadFlag == NO_VOICE_ACTIVITY ) ) {
+
+ psEncC->sLP.transition_frame_no = 0;
+
+ /* Reset transition filter state */
+ SKP_memset( psEncC->sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
+ }
+#endif
+ }
+
+
+
+ return fs_kHz;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_control_codec_FIX.c b/pkg/silk/csilk/SKP_Silk_control_codec_FIX.c
new file mode 100644
index 0000000..a24853c
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_control_codec_FIX.c
@@ -0,0 +1,402 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_setup_complexity.h"
+
+SKP_INLINE SKP_int SKP_Silk_setup_resamplers_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int fs_kHz /* I Internal sampling rate (kHz) */
+);
+
+SKP_INLINE SKP_int SKP_Silk_setup_packetsize_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int PacketSize_ms /* I Packet length (ms) */
+);
+
+SKP_INLINE SKP_int SKP_Silk_setup_fs_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int fs_kHz /* I Internal sampling rate (kHz) */
+);
+
+SKP_INLINE SKP_int SKP_Silk_setup_rate_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int32 TargetRate_bps /* I Target max bitrate (if SNR_dB == 0) */
+);
+
+SKP_INLINE SKP_int SKP_Silk_setup_LBRR_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk encoder state FIX */
+);
+
+/* Control encoder */
+SKP_int SKP_Silk_control_encoder_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */
+ const SKP_int PacketSize_ms, /* I Packet length (ms) */
+ const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
+ const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */
+ const SKP_int DTX_enabled, /* I Enable / disable DTX */
+ const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */
+)
+{
+ SKP_int fs_kHz, ret = 0;
+
+ if( psEnc->sCmn.controlled_since_last_payload != 0 ) {
+ if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
+ /* Change in API sampling rate in the middle of encoding a packet */
+ ret += SKP_Silk_setup_resamplers_FIX( psEnc, psEnc->sCmn.fs_kHz );
+ }
+ return ret;
+ }
+
+ /* Beyond this point we know that there are no previously coded frames in the payload buffer */
+
+ /********************************************/
+ /* Determine internal sampling rate */
+ /********************************************/
+ fs_kHz = SKP_Silk_control_audio_bandwidth( &psEnc->sCmn, TargetRate_bps );
+
+ /********************************************/
+ /* Prepare resampler and buffered data */
+ /********************************************/
+ ret += SKP_Silk_setup_resamplers_FIX( psEnc, fs_kHz );
+
+ /********************************************/
+ /* Set packet size */
+ /********************************************/
+ ret += SKP_Silk_setup_packetsize_FIX( psEnc, PacketSize_ms );
+
+ /********************************************/
+ /* Set internal sampling frequency */
+ /********************************************/
+ ret += SKP_Silk_setup_fs_FIX( psEnc, fs_kHz );
+
+ /********************************************/
+ /* Set encoding complexity */
+ /********************************************/
+ ret += SKP_Silk_setup_complexity( &psEnc->sCmn, Complexity );
+
+ /********************************************/
+ /* Set bitrate/coding quality */
+ /********************************************/
+ ret += SKP_Silk_setup_rate_FIX( psEnc, TargetRate_bps );
+
+ /********************************************/
+ /* Set packet loss rate measured by farend */
+ /********************************************/
+ if( ( PacketLoss_perc < 0 ) || ( PacketLoss_perc > 100 ) ) {
+ ret = SKP_SILK_ENC_INVALID_LOSS_RATE;
+ }
+ psEnc->sCmn.PacketLoss_perc = PacketLoss_perc;
+
+ /********************************************/
+ /* Set LBRR usage */
+ /********************************************/
+ ret += SKP_Silk_setup_LBRR_FIX( psEnc );
+
+ /********************************************/
+ /* Set DTX mode */
+ /********************************************/
+ if( DTX_enabled < 0 || DTX_enabled > 1 ) {
+ ret = SKP_SILK_ENC_INVALID_DTX_SETTING;
+ }
+ psEnc->sCmn.useDTX = DTX_enabled;
+ psEnc->sCmn.controlled_since_last_payload = 1;
+
+ return ret;
+}
+
+/* Control low bitrate redundancy usage */
+void SKP_Silk_LBRR_ctrl_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I Encoder state FIX */
+ SKP_Silk_encoder_control *psEncCtrlC /* I/O Encoder control */
+)
+{
+ SKP_int LBRR_usage;
+
+ if( psEnc->sCmn.LBRR_enabled ) {
+ /* Control LBRR */
+
+ /* Usage Control based on sensitivity and packet loss caracteristics */
+ /* For now only enable adding to next for active frames. Make more complex later */
+ LBRR_usage = SKP_SILK_NO_LBRR;
+ if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) { // nb! maybe multiply loss prob and speech activity
+ LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS1;
+ }
+ psEncCtrlC->LBRR_usage = LBRR_usage;
+ } else {
+ psEncCtrlC->LBRR_usage = SKP_SILK_NO_LBRR;
+ }
+}
+
+SKP_INLINE SKP_int SKP_Silk_setup_resamplers_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int fs_kHz /* I Internal sampling rate (kHz) */
+)
+{
+ SKP_int ret = SKP_SILK_NO_ERROR;
+
+ if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) {
+
+ if( psEnc->sCmn.fs_kHz == 0 ) {
+ /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
+ ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000 );
+ } else {
+ /* Allocate space for worst case temporary upsampling, 8 to 48 kHz, so a factor 6 */
+ SKP_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * ( MAX_API_FS_KHZ / 8 ) ];
+
+ SKP_int32 nSamples_temp = SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + LA_SHAPE_MS * psEnc->sCmn.fs_kHz;
+
+ if( SKP_SMULBB( fs_kHz, 1000 ) < psEnc->sCmn.API_fs_Hz && psEnc->sCmn.fs_kHz != 0 ) {
+ /* Resample buffered data in x_buf to API_fs_Hz */
+
+ SKP_Silk_resampler_state_struct temp_resampler_state;
+
+ /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
+ ret += SKP_Silk_resampler_init( &temp_resampler_state, SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz );
+
+ /* Temporary resampling of x_buf data to API_fs_Hz */
+ ret += SKP_Silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, psEnc->x_buf, nSamples_temp );
+
+ /* Calculate number of samples that has been temporarily upsampled */
+ nSamples_temp = SKP_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) );
+
+ /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
+ ret += SKP_Silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, SKP_SMULBB( fs_kHz, 1000 ) );
+
+ } else {
+ /* Copy data */
+ SKP_memcpy( x_buf_API_fs_Hz, psEnc->x_buf, nSamples_temp * sizeof( SKP_int16 ) );
+ }
+
+ if( 1000 * fs_kHz != psEnc->sCmn.API_fs_Hz ) {
+ /* Correct resampler state (unless resampling by a factor 1) by resampling buffered data from API_fs_Hz to fs_kHz */
+ ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state, psEnc->x_buf, x_buf_API_fs_Hz, nSamples_temp );
+ }
+ }
+ }
+
+ psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
+
+ return(ret);
+}
+
+SKP_INLINE SKP_int SKP_Silk_setup_packetsize_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int PacketSize_ms /* I Packet length (ms) */
+)
+{
+ SKP_int ret = SKP_SILK_NO_ERROR;
+
+ /* Set packet size */
+ if( ( PacketSize_ms != 20 ) &&
+ ( PacketSize_ms != 40 ) &&
+ ( PacketSize_ms != 60 ) &&
+ ( PacketSize_ms != 80 ) &&
+ ( PacketSize_ms != 100 ) ) {
+ ret = SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
+ } else {
+ if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
+ psEnc->sCmn.PacketSize_ms = PacketSize_ms;
+
+ /* Packet length changes. Reset LBRR buffer */
+ SKP_Silk_LBRR_reset( &psEnc->sCmn );
+ }
+ }
+ return(ret);
+}
+
+SKP_INLINE SKP_int SKP_Silk_setup_fs_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int fs_kHz /* I Internal sampling rate (kHz) */
+)
+{
+ SKP_int ret = SKP_SILK_NO_ERROR;
+
+ /* Set internal sampling frequency */
+ if( psEnc->sCmn.fs_kHz != fs_kHz ) {
+ /* reset part of the state */
+ SKP_memset( &psEnc->sShape, 0, sizeof( SKP_Silk_shape_state_FIX ) );
+ SKP_memset( &psEnc->sPrefilt, 0, sizeof( SKP_Silk_prefilter_state_FIX ) );
+ SKP_memset( &psEnc->sPred, 0, sizeof( SKP_Silk_predict_state_FIX ) );
+ SKP_memset( &psEnc->sCmn.sNSQ, 0, sizeof( SKP_Silk_nsq_state ) );
+ SKP_memset( psEnc->sCmn.sNSQ_LBRR.xq, 0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) );
+ SKP_memset( psEnc->sCmn.LBRR_buffer, 0, MAX_LBRR_DELAY * sizeof( SKP_SILK_LBRR_struct ) );
+#if SWITCH_TRANSITION_FILTERING
+ SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );
+ if( psEnc->sCmn.sLP.mode == 1 ) {
+ /* Begin transition phase */
+ psEnc->sCmn.sLP.transition_frame_no = 1;
+ } else {
+ /* End transition phase */
+ psEnc->sCmn.sLP.transition_frame_no = 0;
+ }
+#endif
+ psEnc->sCmn.inputBufIx = 0;
+ psEnc->sCmn.nFramesInPayloadBuf = 0;
+ psEnc->sCmn.nBytesInPayloadBuf = 0;
+ psEnc->sCmn.oldest_LBRR_idx = 0;
+ psEnc->sCmn.TargetRate_bps = 0; /* Ensures that psEnc->SNR_dB is recomputed */
+
+ SKP_memset( psEnc->sPred.prev_NLSFq_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
+
+ /* Initialize non-zero parameters */
+ psEnc->sCmn.prevLag = 100;
+ psEnc->sCmn.prev_sigtype = SIG_TYPE_UNVOICED;
+ psEnc->sCmn.first_frame_after_reset = 1;
+ psEnc->sPrefilt.lagPrev = 100;
+ psEnc->sShape.LastGainIndex = 1;
+ psEnc->sCmn.sNSQ.lagPrev = 100;
+ psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536;
+ psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536;
+
+ psEnc->sCmn.fs_kHz = fs_kHz;
+ if( psEnc->sCmn.fs_kHz == 8 ) {
+ psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
+ psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10;
+ psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10;
+ } else {
+ psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
+ psEnc->sCmn.psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16;
+ psEnc->sCmn.psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16;
+ }
+ psEnc->sCmn.frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz );
+ psEnc->sCmn.subfr_length = SKP_DIV32_16( psEnc->sCmn.frame_length, NB_SUBFR );
+ psEnc->sCmn.la_pitch = SKP_SMULBB( LA_PITCH_MS, fs_kHz );
+ psEnc->sPred.min_pitch_lag = SKP_SMULBB( 3, fs_kHz );
+ psEnc->sPred.max_pitch_lag = SKP_SMULBB( 18, fs_kHz );
+ psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
+ if( psEnc->sCmn.fs_kHz == 24 ) {
+ psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_SWB, 8 );
+ psEnc->sCmn.bitrate_threshold_up = SKP_int32_MAX;
+ psEnc->sCmn.bitrate_threshold_down = SWB2WB_BITRATE_BPS;
+ } else if( psEnc->sCmn.fs_kHz == 16 ) {
+ psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_WB, 8 );
+ psEnc->sCmn.bitrate_threshold_up = WB2SWB_BITRATE_BPS;
+ psEnc->sCmn.bitrate_threshold_down = WB2MB_BITRATE_BPS;
+ } else if( psEnc->sCmn.fs_kHz == 12 ) {
+ psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_MB, 8 );
+ psEnc->sCmn.bitrate_threshold_up = MB2WB_BITRATE_BPS;
+ psEnc->sCmn.bitrate_threshold_down = MB2NB_BITRATE_BPS;
+ } else {
+ psEnc->mu_LTP_Q8 = SKP_FIX_CONST( MU_LTP_QUANT_NB, 8 );
+ psEnc->sCmn.bitrate_threshold_up = NB2MB_BITRATE_BPS;
+ psEnc->sCmn.bitrate_threshold_down = 0;
+ }
+ psEnc->sCmn.fs_kHz_changed = 1;
+
+ /* Check that settings are valid */
+ SKP_assert( ( psEnc->sCmn.subfr_length * NB_SUBFR ) == psEnc->sCmn.frame_length );
+ }
+ return( ret );
+}
+
+SKP_INLINE SKP_int SKP_Silk_setup_rate_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state FIX */
+ SKP_int32 TargetRate_bps /* I Target max bitrate (if SNR_dB == 0) */
+)
+{
+ SKP_int k, ret = SKP_SILK_NO_ERROR;
+ SKP_int32 frac_Q6;
+ const SKP_int32 *rateTable;
+
+ /* Set bitrate/coding quality */
+ if( TargetRate_bps != psEnc->sCmn.TargetRate_bps ) {
+ psEnc->sCmn.TargetRate_bps = TargetRate_bps;
+
+ /* If new TargetRate_bps, translate to SNR_dB value */
+ if( psEnc->sCmn.fs_kHz == 8 ) {
+ rateTable = TargetRate_table_NB;
+ } else if( psEnc->sCmn.fs_kHz == 12 ) {
+ rateTable = TargetRate_table_MB;
+ } else if( psEnc->sCmn.fs_kHz == 16 ) {
+ rateTable = TargetRate_table_WB;
+ } else {
+ rateTable = TargetRate_table_SWB;
+ }
+ for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
+ /* Find bitrate interval in table and interpolate */
+ if( TargetRate_bps <= rateTable[ k ] ) {
+ frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ),
+ rateTable[ k ] - rateTable[ k - 1 ] );
+ psEnc->SNR_dB_Q7 = SKP_LSHIFT( SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, SNR_table_Q1[ k ] - SNR_table_Q1[ k - 1 ] );
+ break;
+ }
+ }
+ }
+ return( ret );
+}
+
+SKP_INLINE SKP_int SKP_Silk_setup_LBRR_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk encoder state FIX */
+)
+{
+ SKP_int ret = SKP_SILK_NO_ERROR;
+#if USE_LBRR
+ SKP_int32 LBRRRate_thres_bps;
+
+ if( psEnc->sCmn.useInBandFEC < 0 || psEnc->sCmn.useInBandFEC > 1 ) {
+ ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;
+ }
+
+ psEnc->sCmn.LBRR_enabled = psEnc->sCmn.useInBandFEC;
+ if( psEnc->sCmn.fs_kHz == 8 ) {
+ LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 9000;
+ } else if( psEnc->sCmn.fs_kHz == 12 ) {
+ LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 6000;;
+ } else if( psEnc->sCmn.fs_kHz == 16 ) {
+ LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 3000;
+ } else {
+ LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS;
+ }
+
+ if( psEnc->sCmn.TargetRate_bps >= LBRRRate_thres_bps ) {
+ /* Set gain increase / rate reduction for LBRR usage */
+ /* Coarsely tuned with PESQ for now. */
+ /* Linear regression coefs G = 8 - 0.5 * loss */
+ /* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */
+ psEnc->sCmn.LBRR_GainIncreases = SKP_max_int( 8 - SKP_RSHIFT( psEnc->sCmn.PacketLoss_perc, 1 ), 0 );
+
+ /* Set main stream rate compensation */
+ if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) {
+ /* Tuned to give approx same mean / weighted bitrate as no inband FEC */
+ psEnc->inBandFEC_SNR_comp_Q8 = SKP_FIX_CONST( 6.0f, 8 ) - SKP_LSHIFT( psEnc->sCmn.LBRR_GainIncreases, 7 );
+ } else {
+ psEnc->inBandFEC_SNR_comp_Q8 = 0;
+ psEnc->sCmn.LBRR_enabled = 0;
+ }
+ } else {
+ psEnc->inBandFEC_SNR_comp_Q8 = 0;
+ psEnc->sCmn.LBRR_enabled = 0;
+ }
+#else
+ if( INBandFEC_enabled != 0 ) {
+ ret = SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING;
+ }
+ psEnc->sCmn.LBRR_enabled = 0;
+#endif
+ return ret;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_corrMatrix_FIX.c b/pkg/silk/csilk/SKP_Silk_corrMatrix_FIX.c
new file mode 100644
index 0000000..18b55c9
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_corrMatrix_FIX.c
@@ -0,0 +1,153 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/**********************************************************************
+ * Correlation Matrix Computations for LS estimate.
+ **********************************************************************/
+
+#include "SKP_Silk_main_FIX.h"
+
+/* Calculates correlation vector X'*t */
+void SKP_Silk_corrVector_FIX(
+ const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
+ const SKP_int16 *t, /* I target vector [L] */
+ const SKP_int L, /* I Length of vectors */
+ const SKP_int order, /* I Max lag for correlation */
+ SKP_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
+ const SKP_int rshifts /* I Right shifts of correlations */
+)
+{
+ SKP_int lag, i;
+ const SKP_int16 *ptr1, *ptr2;
+ SKP_int32 inner_prod;
+
+ ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
+ ptr2 = t;
+ /* Calculate X'*t */
+ if( rshifts > 0 ) {
+ /* Right shifting used */
+ for( lag = 0; lag < order; lag++ ) {
+ inner_prod = 0;
+ for( i = 0; i < L; i++ ) {
+ inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
+ }
+ Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
+ ptr1--; /* Go to next column of X */
+ }
+ } else {
+ SKP_assert( rshifts == 0 );
+ for( lag = 0; lag < order; lag++ ) {
+ Xt[ lag ] = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */
+ ptr1--; /* Go to next column of X */
+ }
+ }
+}
+
+/* Calculates correlation matrix X'*X */
+void SKP_Silk_corrMatrix_FIX(
+ const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
+ const SKP_int L, /* I Length of vectors */
+ const SKP_int order, /* I Max lag for correlation */
+ const SKP_int head_room, /* I Desired headroom */
+ SKP_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ]*/
+ SKP_int *rshifts /* I/O Right shifts of correlations */
+)
+{
+ SKP_int i, j, lag, rshifts_local, head_room_rshifts;
+ SKP_int32 energy;
+ const SKP_int16 *ptr1, *ptr2;
+
+ /* Calculate energy to find shift used to fit in 32 bits */
+ SKP_Silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );
+
+ /* Add shifts to get the desired head room */
+ head_room_rshifts = SKP_max( head_room - SKP_Silk_CLZ32( energy ), 0 );
+
+ energy = SKP_RSHIFT32( energy, head_room_rshifts );
+ rshifts_local += head_room_rshifts;
+
+ /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
+ /* Remove contribution of first order - 1 samples */
+ for( i = 0; i < order - 1; i++ ) {
+ energy -= SKP_RSHIFT32( SKP_SMULBB( x[ i ], x[ i ] ), rshifts_local );
+ }
+ if( rshifts_local < *rshifts ) {
+ /* Adjust energy */
+ energy = SKP_RSHIFT32( energy, *rshifts - rshifts_local );
+ rshifts_local = *rshifts;
+ }
+
+ /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
+ /* Fill out the diagonal of the correlation matrix */
+ matrix_ptr( XX, 0, 0, order ) = energy;
+ ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
+ for( j = 1; j < order; j++ ) {
+ energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );
+ energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );
+ matrix_ptr( XX, j, j, order ) = energy;
+ }
+
+ ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
+ /* Calculate the remaining elements of the correlation matrix */
+ if( rshifts_local > 0 ) {
+ /* Right shifting used */
+ for( lag = 1; lag < order; lag++ ) {
+ /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
+ energy = 0;
+ for( i = 0; i < L; i++ ) {
+ energy += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );
+ }
+ /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
+ matrix_ptr( XX, lag, 0, order ) = energy;
+ matrix_ptr( XX, 0, lag, order ) = energy;
+ for( j = 1; j < ( order - lag ); j++ ) {
+ energy = SKP_SUB32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );
+ energy = SKP_ADD32( energy, SKP_RSHIFT32( SKP_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );
+ matrix_ptr( XX, lag + j, j, order ) = energy;
+ matrix_ptr( XX, j, lag + j, order ) = energy;
+ }
+ ptr2--; /* Update pointer to first sample of next column (lag) in X */
+ }
+ } else {
+ for( lag = 1; lag < order; lag++ ) {
+ /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
+ energy = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L );
+ matrix_ptr( XX, lag, 0, order ) = energy;
+ matrix_ptr( XX, 0, lag, order ) = energy;
+ /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
+ for( j = 1; j < ( order - lag ); j++ ) {
+ energy = SKP_SUB32( energy, SKP_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );
+ energy = SKP_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );
+ matrix_ptr( XX, lag + j, j, order ) = energy;
+ matrix_ptr( XX, j, lag + j, order ) = energy;
+ }
+ ptr2--;/* Update pointer to first sample of next column (lag) in X */
+ }
+ }
+ *rshifts = rshifts_local;
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_create_init_destroy.c b/pkg/silk/csilk/SKP_Silk_create_init_destroy.c
new file mode 100644
index 0000000..355ca85
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_create_init_destroy.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+
+/************************/
+/* Init Decoder State */
+/************************/
+SKP_int SKP_Silk_init_decoder(
+ SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */
+)
+{
+ SKP_memset( psDec, 0, sizeof( SKP_Silk_decoder_state ) );
+ /* Set sampling rate to 24 kHz, and init non-zero values */
+ SKP_Silk_decoder_set_fs( psDec, 24 );
+
+ /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */
+ psDec->first_frame_after_reset = 1;
+ psDec->prev_inv_gain_Q16 = 65536;
+
+ /* Reset CNG state */
+ SKP_Silk_CNG_Reset( psDec );
+
+ SKP_Silk_PLC_Reset( psDec );
+
+ return(0);
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_dec_API.c b/pkg/silk/csilk/SKP_Silk_dec_API.c
new file mode 100644
index 0000000..ca031e3
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_dec_API.c
@@ -0,0 +1,279 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SDK_API.h"
+#include "SKP_Silk_main.h"
+
+/*********************/
+/* Decoder functions */
+/*********************/
+
+SKP_int SKP_Silk_SDK_Get_Decoder_Size( SKP_int32 *decSizeBytes )
+{
+ SKP_int ret = 0;
+
+ *decSizeBytes = sizeof( SKP_Silk_decoder_state );
+
+ return ret;
+}
+
+/* Reset decoder state */
+SKP_int SKP_Silk_SDK_InitDecoder(
+ void* decState /* I/O: State */
+)
+{
+ SKP_int ret = 0;
+ SKP_Silk_decoder_state *struc;
+
+ struc = (SKP_Silk_decoder_state *)decState;
+
+ ret = SKP_Silk_init_decoder( struc );
+
+ return ret;
+}
+
+/* Decode a frame */
+SKP_int SKP_Silk_SDK_Decode(
+ void* decState, /* I/O: State */
+ SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control structure */
+ SKP_int lostFlag, /* I: 0: no loss, 1 loss */
+ const SKP_uint8 *inData, /* I: Encoded input vector */
+ const SKP_int nBytesIn, /* I: Number of input Bytes */
+ SKP_int16 *samplesOut, /* O: Decoded output speech vector */
+ SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
+)
+{
+ SKP_int ret = 0, used_bytes, prev_fs_kHz;
+ SKP_Silk_decoder_state *psDec;
+ SKP_int16 samplesOutInternal[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ];
+ SKP_int16 *pSamplesOutInternal;
+
+ psDec = (SKP_Silk_decoder_state *)decState;
+
+ /* We need this buffer to have room for an internal frame */
+ pSamplesOutInternal = samplesOut;
+ if( psDec->fs_kHz * 1000 > decControl->API_sampleRate ) {
+ pSamplesOutInternal = samplesOutInternal;
+ }
+
+ /**********************************/
+ /* Test if first frame in payload */
+ /**********************************/
+ if( psDec->moreInternalDecoderFrames == 0 ) {
+ /* First Frame in Payload */
+ psDec->nFramesDecoded = 0; /* Used to count frames in packet */
+ }
+
+ if( psDec->moreInternalDecoderFrames == 0 && /* First frame in packet */
+ lostFlag == 0 && /* Not packet loss */
+ nBytesIn > MAX_ARITHM_BYTES ) { /* Too long payload */
+ /* Avoid trying to decode a too large packet */
+ lostFlag = 1;
+ ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE;
+ }
+
+ /* Save previous sample frequency */
+ prev_fs_kHz = psDec->fs_kHz;
+
+ /* Call decoder for one frame */
+ ret += SKP_Silk_decode_frame( psDec, pSamplesOutInternal, nSamplesOut, inData, nBytesIn,
+ lostFlag, &used_bytes );
+
+ if( used_bytes ) { /* Only Call if not a packet loss */
+ if( psDec->nBytesLeft > 0 && psDec->FrameTermination == SKP_SILK_MORE_FRAMES && psDec->nFramesDecoded < 5 ) {
+ /* We have more frames in the Payload */
+ psDec->moreInternalDecoderFrames = 1;
+ } else {
+ /* Last frame in Payload */
+ psDec->moreInternalDecoderFrames = 0;
+ psDec->nFramesInPacket = psDec->nFramesDecoded;
+
+ /* Track inband FEC usage */
+ if( psDec->vadFlag == VOICE_ACTIVITY ) {
+ if( psDec->FrameTermination == SKP_SILK_LAST_FRAME ) {
+ psDec->no_FEC_counter++;
+ if( psDec->no_FEC_counter > NO_LBRR_THRES ) {
+ psDec->inband_FEC_offset = 0;
+ }
+ } else if( psDec->FrameTermination == SKP_SILK_LBRR_VER1 ) {
+ psDec->inband_FEC_offset = 1; /* FEC info with 1 packet delay */
+ psDec->no_FEC_counter = 0;
+ } else if( psDec->FrameTermination == SKP_SILK_LBRR_VER2 ) {
+ psDec->inband_FEC_offset = 2; /* FEC info with 2 packets delay */
+ psDec->no_FEC_counter = 0;
+ }
+ }
+ }
+ }
+
+ if( MAX_API_FS_KHZ * 1000 < decControl->API_sampleRate ||
+ 8000 > decControl->API_sampleRate ) {
+ ret = SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY;
+ return( ret );
+ }
+
+ /* Resample if needed */
+ if( psDec->fs_kHz * 1000 != decControl->API_sampleRate ) {
+ SKP_int16 samplesOut_tmp[ MAX_API_FS_KHZ * FRAME_LENGTH_MS ];
+ SKP_assert( psDec->fs_kHz <= MAX_API_FS_KHZ );
+
+ /* Copy to a tmp buffer as the resampling writes to samplesOut */
+ SKP_memcpy( samplesOut_tmp, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) );
+
+ /* (Re-)initialize resampler state when switching internal sampling frequency */
+ if( prev_fs_kHz != psDec->fs_kHz || psDec->prev_API_sampleRate != decControl->API_sampleRate ) {
+ ret = SKP_Silk_resampler_init( &psDec->resampler_state, SKP_SMULBB( psDec->fs_kHz, 1000 ), decControl->API_sampleRate );
+ }
+
+ /* Resample the output to API_sampleRate */
+ ret += SKP_Silk_resampler( &psDec->resampler_state, samplesOut, samplesOut_tmp, *nSamplesOut );
+
+ /* Update the number of output samples */
+ *nSamplesOut = SKP_DIV32( ( SKP_int32 )*nSamplesOut * decControl->API_sampleRate, psDec->fs_kHz * 1000 );
+ } else if( prev_fs_kHz * 1000 > decControl->API_sampleRate ) {
+ SKP_memcpy( samplesOut, pSamplesOutInternal, *nSamplesOut * sizeof( SKP_int16 ) );
+ }
+
+ psDec->prev_API_sampleRate = decControl->API_sampleRate;
+
+ /* Copy all parameters that are needed out of internal structure to the control stucture */
+ decControl->frameSize = (SKP_uint16)( decControl->API_sampleRate / 50 ) ;
+ decControl->framesPerPacket = ( SKP_int )psDec->nFramesInPacket;
+ decControl->inBandFECOffset = ( SKP_int )psDec->inband_FEC_offset;
+ decControl->moreInternalDecoderFrames = ( SKP_int )psDec->moreInternalDecoderFrames;
+
+ return ret;
+}
+
+/* Function to find LBRR information in a packet */
+void SKP_Silk_SDK_search_for_LBRR(
+ const SKP_uint8 *inData, /* I: Encoded input vector */
+ const SKP_int nBytesIn, /* I: Number of input Bytes */
+ SKP_int lost_offset, /* I: Offset from lost packet */
+ SKP_uint8 *LBRRData, /* O: LBRR payload */
+ SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
+)
+{
+ SKP_Silk_decoder_state sDec; // Local decoder state to avoid interfering with running decoder */
+ SKP_Silk_decoder_control sDecCtrl;
+ SKP_int TempQ[ MAX_FRAME_LENGTH ];
+
+ if( lost_offset < 1 || lost_offset > MAX_LBRR_DELAY ) {
+ /* No useful FEC in this packet */
+ *nLBRRBytes = 0;
+ return;
+ }
+
+ sDec.nFramesDecoded = 0;
+ sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */
+ sDec.lossCnt = 0; /* Avoid running bw expansion of the LPC parameters when searching for LBRR data */
+ SKP_memset( sDec.prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
+ SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn );
+
+ while(1) {
+ SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 );
+
+ if( sDec.sRC.error ) {
+ /* Corrupt stream */
+ *nLBRRBytes = 0;
+ return;
+ };
+ if( ( sDec.FrameTermination - 1 ) & lost_offset && sDec.FrameTermination > 0 && sDec.nBytesLeft >= 0 ) {
+ /* The wanted FEC is present in the packet */
+ *nLBRRBytes = sDec.nBytesLeft;
+ SKP_memcpy( LBRRData, &inData[ nBytesIn - sDec.nBytesLeft ], sDec.nBytesLeft * sizeof( SKP_uint8 ) );
+ break;
+ }
+ if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) {
+ sDec.nFramesDecoded++;
+ } else {
+ LBRRData = NULL;
+ *nLBRRBytes = 0;
+ break;
+ }
+ }
+}
+
+/* Getting type of content for a packet */
+void SKP_Silk_SDK_get_TOC(
+ const SKP_uint8 *inData, /* I: Encoded input vector */
+ const SKP_int nBytesIn, /* I: Number of input bytes */
+ SKP_Silk_TOC_struct *Silk_TOC /* O: Type of content */
+)
+{
+ SKP_Silk_decoder_state sDec; // Local Decoder state to avoid interfering with running decoder */
+ SKP_Silk_decoder_control sDecCtrl;
+ SKP_int TempQ[ MAX_FRAME_LENGTH ];
+
+ sDec.nFramesDecoded = 0;
+ sDec.fs_kHz = 0; /* Force update parameters LPC_order etc */
+ SKP_Silk_range_dec_init( &sDec.sRC, inData, ( SKP_int32 )nBytesIn );
+
+ Silk_TOC->corrupt = 0;
+ while( 1 ) {
+ SKP_Silk_decode_parameters( &sDec, &sDecCtrl, TempQ, 0 );
+
+ Silk_TOC->vadFlags[ sDec.nFramesDecoded ] = sDec.vadFlag;
+ Silk_TOC->sigtypeFlags[ sDec.nFramesDecoded ] = sDecCtrl.sigtype;
+
+ if( sDec.sRC.error ) {
+ /* Corrupt stream */
+ Silk_TOC->corrupt = 1;
+ break;
+ };
+
+ if( sDec.nBytesLeft > 0 && sDec.FrameTermination == SKP_SILK_MORE_FRAMES ) {
+ sDec.nFramesDecoded++;
+ } else {
+ break;
+ }
+ }
+ if( Silk_TOC->corrupt || sDec.FrameTermination == SKP_SILK_MORE_FRAMES ||
+ sDec.nFramesInPacket > SILK_MAX_FRAMES_PER_PACKET ) {
+ /* Corrupt packet */
+ SKP_memset( Silk_TOC, 0, sizeof( SKP_Silk_TOC_struct ) );
+ Silk_TOC->corrupt = 1;
+ } else {
+ Silk_TOC->framesInPacket = sDec.nFramesDecoded + 1;
+ Silk_TOC->fs_kHz = sDec.fs_kHz;
+ if( sDec.FrameTermination == SKP_SILK_LAST_FRAME ) {
+ Silk_TOC->inbandLBRR = sDec.FrameTermination;
+ } else {
+ Silk_TOC->inbandLBRR = sDec.FrameTermination - 1;
+ }
+ }
+}
+
+/**************************/
+/* Get the version number */
+/**************************/
+/* Return a pointer to string specifying the version */
+const char *SKP_Silk_SDK_get_version()
+{
+ static const char version[] = "1.0.9.6";
+ return version;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_decode_core.c b/pkg/silk/csilk/SKP_Silk_decode_core.c
new file mode 100644
index 0000000..247f24d
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_decode_core.c
@@ -0,0 +1,314 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+
+void SKP_Silk_decode_short_term_prediction(
+SKP_int32 *vec_Q10,
+SKP_int32 *pres_Q10,
+SKP_int32 *sLPC_Q14,
+SKP_int16 *A_Q12_tmp,
+SKP_int LPC_order,
+SKP_int subfr_length
+);
+
+
+/**********************************************************/
+/* Core decoder. Performs inverse NSQ operation LTP + LPC */
+/**********************************************************/
+void SKP_Silk_decode_core(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
+ SKP_int16 xq[], /* O Decoded speech */
+ const SKP_int q[ MAX_FRAME_LENGTH ] /* I Pulse signal */
+)
+{
+ SKP_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, sigtype;
+ SKP_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
+ SKP_int16 sLTP[ MAX_FRAME_LENGTH ];
+ SKP_int32 LTP_pred_Q14, Gain_Q16, inv_gain_Q16, inv_gain_Q32, gain_adj_Q16, rand_seed, offset_Q10, dither;
+ SKP_int32 *pred_lag_ptr, *pexc_Q10, *pres_Q10;
+ SKP_int32 vec_Q10[ MAX_FRAME_LENGTH / NB_SUBFR ];
+ SKP_int32 FiltState[ MAX_LPC_ORDER ];
+
+ SKP_assert( psDec->prev_inv_gain_Q16 != 0 );
+
+ offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psDecCtrl->sigtype ][ psDecCtrl->QuantOffsetType ];
+
+ if( psDecCtrl->NLSFInterpCoef_Q2 < ( 1 << 2 ) ) {
+ NLSF_interpolation_flag = 1;
+ } else {
+ NLSF_interpolation_flag = 0;
+ }
+
+
+ /* Decode excitation */
+ rand_seed = psDecCtrl->Seed;
+ for( i = 0; i < psDec->frame_length; i++ ) {
+ rand_seed = SKP_RAND( rand_seed );
+ /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
+ dither = SKP_RSHIFT( rand_seed, 31 );
+
+ psDec->exc_Q10[ i ] = SKP_LSHIFT( ( SKP_int32 )q[ i ], 10 ) + offset_Q10;
+ psDec->exc_Q10[ i ] = ( psDec->exc_Q10[ i ] ^ dither ) - dither;
+
+ rand_seed += q[ i ];
+ }
+
+
+ pexc_Q10 = psDec->exc_Q10;
+ pres_Q10 = psDec->res_Q10;
+ pxq = &psDec->outBuf[ psDec->frame_length ];
+ sLTP_buf_idx = psDec->frame_length;
+ /* Loop over subframes */
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ];
+
+ /* Preload LPC coeficients to array on stack. Gives small performance gain */
+ SKP_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( SKP_int16 ) );
+ B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ];
+ Gain_Q16 = psDecCtrl->Gains_Q16[ k ];
+ sigtype = psDecCtrl->sigtype;
+
+ inv_gain_Q16 = SKP_INVERSE32_varQ( SKP_max( Gain_Q16, 1 ), 32 );
+ inv_gain_Q16 = SKP_min( inv_gain_Q16, SKP_int16_MAX );
+
+ /* Calculate Gain adjustment factor */
+ gain_adj_Q16 = ( SKP_int32 )1 << 16;
+ if( inv_gain_Q16 != psDec->prev_inv_gain_Q16 ) {
+ gain_adj_Q16 = SKP_DIV32_varQ( inv_gain_Q16, psDec->prev_inv_gain_Q16, 16 );
+ }
+
+ /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */
+ if( psDec->lossCnt && psDec->prev_sigtype == SIG_TYPE_VOICED &&
+ psDecCtrl->sigtype == SIG_TYPE_UNVOICED && k < ( NB_SUBFR >> 1 ) ) {
+
+ SKP_memset( B_Q14, 0, LTP_ORDER * sizeof( SKP_int16 ) );
+ B_Q14[ LTP_ORDER/2 ] = ( SKP_int16 )1 << 12; /* 0.25 */
+
+ sigtype = SIG_TYPE_VOICED;
+ psDecCtrl->pitchL[ k ] = psDec->lagPrev;
+ }
+
+ if( sigtype == SIG_TYPE_VOICED ) {
+ /* Voiced */
+
+ lag = psDecCtrl->pitchL[ k ];
+ /* Re-whitening */
+ if( ( k & ( 3 - SKP_LSHIFT( NLSF_interpolation_flag, 1 ) ) ) == 0 ) {
+ /* Rewhiten with new A coefs */
+ start_idx = psDec->frame_length - lag - psDec->LPC_order - LTP_ORDER / 2;
+ SKP_assert( start_idx >= 0 );
+ SKP_assert( start_idx <= psDec->frame_length - psDec->LPC_order );
+
+ SKP_memset( FiltState, 0, psDec->LPC_order * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind and Coverity will complain otherwise */
+ SKP_Silk_MA_Prediction( &psDec->outBuf[ start_idx + k * ( psDec->frame_length >> 2 ) ],
+ A_Q12, FiltState, sLTP + start_idx, psDec->frame_length - start_idx, psDec->LPC_order );
+
+ /* After rewhitening the LTP state is unscaled */
+ inv_gain_Q32 = SKP_LSHIFT( inv_gain_Q16, 16 );
+ if( k == 0 ) {
+ /* Do LTP downscaling */
+ inv_gain_Q32 = SKP_LSHIFT( SKP_SMULWB( inv_gain_Q32, psDecCtrl->LTP_scale_Q14 ), 2 );
+ }
+ for( i = 0; i < (lag + LTP_ORDER/2); i++ ) {
+ psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWB( inv_gain_Q32, sLTP[ psDec->frame_length - i - 1 ] );
+ }
+ } else {
+ /* Update LTP state when Gain changes */
+ if( gain_adj_Q16 != ( SKP_int32 )1 << 16 ) {
+ for( i = 0; i < ( lag + LTP_ORDER / 2 ); i++ ) {
+ psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] = SKP_SMULWW( gain_adj_Q16, psDec->sLTP_Q16[ sLTP_buf_idx - i - 1 ] );
+ }
+ }
+ }
+ }
+
+ /* Scale short term state */
+ for( i = 0; i < MAX_LPC_ORDER; i++ ) {
+ psDec->sLPC_Q14[ i ] = SKP_SMULWW( gain_adj_Q16, psDec->sLPC_Q14[ i ] );
+ }
+
+ /* Save inv_gain */
+ SKP_assert( inv_gain_Q16 != 0 );
+ psDec->prev_inv_gain_Q16 = inv_gain_Q16;
+
+ /* Long-term prediction */
+ if( sigtype == SIG_TYPE_VOICED ) {
+ /* Setup pointer */
+ pred_lag_ptr = &psDec->sLTP_Q16[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
+ for( i = 0; i < psDec->subfr_length; i++ ) {
+ /* Unrolled loop */
+ LTP_pred_Q14 = SKP_SMULWB( pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
+ LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
+ pred_lag_ptr++;
+
+ /* Generate LPC residual */
+ pres_Q10[ i ] = SKP_ADD32( pexc_Q10[ i ], SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );
+
+ /* Update states */
+ psDec->sLTP_Q16[ sLTP_buf_idx ] = SKP_LSHIFT( pres_Q10[ i ], 6 );
+ sLTP_buf_idx++;
+ }
+ } else {
+ SKP_memcpy( pres_Q10, pexc_Q10, psDec->subfr_length * sizeof( SKP_int32 ) );
+ }
+
+ SKP_Silk_decode_short_term_prediction(vec_Q10, pres_Q10, psDec->sLPC_Q14,A_Q12_tmp,psDec->LPC_order,psDec->subfr_length);
+
+ /* Scale with Gain */
+ for( i = 0; i < psDec->subfr_length; i++ ) {
+ pxq[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( vec_Q10[ i ], Gain_Q16 ), 10 ) );
+ }
+
+ /* Update LPC filter state */
+ SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
+ pexc_Q10 += psDec->subfr_length;
+ pres_Q10 += psDec->subfr_length;
+ pxq += psDec->subfr_length;
+ }
+
+ /* Copy to output */
+ SKP_memcpy( xq, &psDec->outBuf[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int16 ) );
+
+}
+
+#if EMBEDDED_ARM<5
+void SKP_Silk_decode_short_term_prediction(
+SKP_int32 *vec_Q10,
+SKP_int32 *pres_Q10,
+SKP_int32 *sLPC_Q14,
+SKP_int16 *A_Q12_tmp,
+SKP_int LPC_order,
+SKP_int subfr_length
+)
+{
+ SKP_int i;
+ SKP_int32 LPC_pred_Q10;
+ #if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 Atmp;
+ /* Short term prediction */
+ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
+ /* SMLAWB and SMLAWT instructions. On a big-endian CPU the two int16 variables would be */
+ /* loaded in reverse order and the code will give the wrong result. In that case swapping */
+ /* the SMLAWB and SMLAWT instructions should solve the problem. */
+ if( LPC_order == 16 ) {
+ for( i = 0; i < subfr_length; i++ ) {
+ /* unrolled */
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] ); /* read two coefficients at once */
+ LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 10 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 12 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 14 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], Atmp );
+
+ /* Add prediction to LPC residual */
+ vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );
+
+ /* Update states */
+ sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 );
+ }
+ } else {
+ SKP_assert( LPC_order == 10 );
+ for( i = 0; i < subfr_length; i++ ) {
+ /* unrolled */
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] ); /* read two coefficients at once */
+ LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], Atmp );
+ Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], Atmp );
+ LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );
+
+ /* Add prediction to LPC residual */
+ vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );
+
+ /* Update states */
+ sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 );
+ }
+ }
+#else
+ SKP_int j;
+ for( i = 0; i < subfr_length; i++ ) {
+ /* Partially unrolled */
+ LPC_pred_Q10 = SKP_SMULWB( sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] );
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );
+
+ for( j = 10; j < LPC_order; j ++ ) {
+ LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - j - 1 ], A_Q12_tmp[ j ] );
+ }
+
+ /* Add prediction to LPC residual */
+ vec_Q10[ i ] = SKP_ADD32( pres_Q10[ i ], LPC_pred_Q10 );
+
+ /* Update states */
+ sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT_ovflw( vec_Q10[ i ], 4 );
+ }
+#endif
+}
+#endif
+
+
+
diff --git a/pkg/silk/csilk/SKP_Silk_decode_frame.c b/pkg/silk/csilk/SKP_Silk_decode_frame.c
new file mode 100644
index 0000000..c0ff322
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_decode_frame.c
@@ -0,0 +1,155 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+#include "SKP_Silk_PLC.h"
+
+/****************/
+/* Decode frame */
+/****************/
+SKP_int SKP_Silk_decode_frame(
+ SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */
+ SKP_int16 pOut[], /* O Pointer to output speech frame */
+ SKP_int16 *pN, /* O Pointer to size of output frame */
+ const SKP_uint8 pCode[], /* I Pointer to payload */
+ const SKP_int nBytes, /* I Payload length */
+ SKP_int action, /* I Action from Jitter Buffer */
+ SKP_int *decBytes /* O Used bytes to decode this frame */
+)
+{
+ SKP_Silk_decoder_control sDecCtrl;
+ SKP_int L, fs_Khz_old, ret = 0;
+ SKP_int Pulses[ MAX_FRAME_LENGTH ];
+
+
+ L = psDec->frame_length;
+ sDecCtrl.LTP_scale_Q14 = 0;
+
+ /* Safety checks */
+ SKP_assert( L > 0 && L <= MAX_FRAME_LENGTH );
+
+ /********************************************/
+ /* Decode Frame if packet is not lost */
+ /********************************************/
+ *decBytes = 0;
+ if( action == 0 ) {
+ /********************************************/
+ /* Initialize arithmetic coder */
+ /********************************************/
+ fs_Khz_old = psDec->fs_kHz;
+ if( psDec->nFramesDecoded == 0 ) {
+ /* Initialize range decoder state */
+ SKP_Silk_range_dec_init( &psDec->sRC, pCode, nBytes );
+ }
+
+ /********************************************/
+ /* Decode parameters and pulse signal */
+ /********************************************/
+ SKP_Silk_decode_parameters( psDec, &sDecCtrl, Pulses, 1 );
+
+
+ if( psDec->sRC.error ) {
+ psDec->nBytesLeft = 0;
+
+ action = 1; /* PLC operation */
+ /* revert fs if changed in decode_parameters */
+ SKP_Silk_decoder_set_fs( psDec, fs_Khz_old );
+
+ /* Avoid crashing */
+ *decBytes = psDec->sRC.bufferLength;
+
+ if( psDec->sRC.error == RANGE_CODER_DEC_PAYLOAD_TOO_LONG ) {
+ ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE;
+ } else {
+ ret = SKP_SILK_DEC_PAYLOAD_ERROR;
+ }
+ } else {
+ *decBytes = psDec->sRC.bufferLength - psDec->nBytesLeft;
+ psDec->nFramesDecoded++;
+
+ /* Update lengths. Sampling frequency could have changed */
+ L = psDec->frame_length;
+
+ /********************************************************/
+ /* Run inverse NSQ */
+ /********************************************************/
+ SKP_Silk_decode_core( psDec, &sDecCtrl, pOut, Pulses );
+
+ /********************************************************/
+ /* Update PLC state */
+ /********************************************************/
+ SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );
+
+ psDec->lossCnt = 0;
+ psDec->prev_sigtype = sDecCtrl.sigtype;
+
+ /* A frame has been decoded without errors */
+ psDec->first_frame_after_reset = 0;
+ }
+ }
+ /*************************************************************/
+ /* Generate Concealment frame if packet is lost, or corrupt */
+ /*************************************************************/
+ if( action == 1 ) {
+ /* Handle packet loss by extrapolation */
+ SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );
+ }
+
+ /*************************/
+ /* Update output buffer. */
+ /*************************/
+ SKP_memcpy( psDec->outBuf, pOut, L * sizeof( SKP_int16 ) );
+
+ /****************************************************************/
+ /* Ensure smooth connection of extrapolated and good frames */
+ /****************************************************************/
+ SKP_Silk_PLC_glue_frames( psDec, &sDecCtrl, pOut, L );
+
+ /************************************************/
+ /* Comfort noise generation / estimation */
+ /************************************************/
+ SKP_Silk_CNG( psDec, &sDecCtrl, pOut , L );
+
+ /********************************************/
+ /* HP filter output */
+ /********************************************/
+ SKP_assert( ( ( psDec->fs_kHz == 12 ) && ( L % 3 ) == 0 ) ||
+ ( ( psDec->fs_kHz != 12 ) && ( L % 2 ) == 0 ) );
+ SKP_Silk_biquad( pOut, psDec->HP_B, psDec->HP_A, psDec->HPState, pOut, L );
+
+ /********************************************/
+ /* set output frame length */
+ /********************************************/
+ *pN = ( SKP_int16 )L;
+
+ /* Update some decoder state variables */
+ psDec->lagPrev = sDecCtrl.pitchL[ NB_SUBFR - 1 ];
+
+
+ return ret;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_decode_parameters.c b/pkg/silk/csilk/SKP_Silk_decode_parameters.c
new file mode 100644
index 0000000..108a939
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_decode_parameters.c
@@ -0,0 +1,244 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Decode parameters from payload */
+void SKP_Silk_decode_parameters(
+ SKP_Silk_decoder_state *psDec, /* I/O State */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int q[], /* O Excitation signal */
+ const SKP_int fullDecoding /* I Flag to tell if only arithmetic decoding */
+)
+{
+ SKP_int i, k, Ix, fs_kHz_dec, nBytesUsed;
+ SKP_int Ixs[ NB_SUBFR ];
+ SKP_int GainsIndices[ NB_SUBFR ];
+ SKP_int NLSFIndices[ NLSF_MSVQ_MAX_CB_STAGES ];
+ SKP_int pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ];
+ const SKP_int16 *cbk_ptr_Q14;
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB = NULL;
+ SKP_Silk_range_coder_state *psRC = &psDec->sRC;
+
+ /************************/
+ /* Decode sampling rate */
+ /************************/
+ /* only done for first frame of packet */
+ if( psDec->nFramesDecoded == 0 ) {
+ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_SamplingRates_CDF, SKP_Silk_SamplingRates_offset );
+
+ /* check that sampling rate is supported */
+ if( Ix < 0 || Ix > 3 ) {
+ psRC->error = RANGE_CODER_ILLEGAL_SAMPLING_RATE;
+ return;
+ }
+ fs_kHz_dec = SKP_Silk_SamplingRates_table[ Ix ];
+ SKP_Silk_decoder_set_fs( psDec, fs_kHz_dec );
+ }
+
+ /*******************************************/
+ /* Decode signal type and quantizer offset */
+ /*******************************************/
+ if( psDec->nFramesDecoded == 0 ) {
+ /* first frame in packet: independent coding */
+ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_CDF, SKP_Silk_type_offset_CDF_offset );
+ } else {
+ /* condidtional coding */
+ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_type_offset_joint_CDF[ psDec->typeOffsetPrev ],
+ SKP_Silk_type_offset_CDF_offset );
+ }
+ psDecCtrl->sigtype = SKP_RSHIFT( Ix, 1 );
+ psDecCtrl->QuantOffsetType = Ix & 1;
+ psDec->typeOffsetPrev = Ix;
+
+ /****************/
+ /* Decode gains */
+ /****************/
+ /* first subframe */
+ if( psDec->nFramesDecoded == 0 ) {
+ /* first frame in packet: independent coding */
+ SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_gain_CDF[ psDecCtrl->sigtype ], SKP_Silk_gain_CDF_offset );
+ } else {
+ /* condidtional coding */
+ SKP_Silk_range_decoder( &GainsIndices[ 0 ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset );
+ }
+
+ /* remaining subframes */
+ for( i = 1; i < NB_SUBFR; i++ ) {
+ SKP_Silk_range_decoder( &GainsIndices[ i ], psRC, SKP_Silk_delta_gain_CDF, SKP_Silk_delta_gain_CDF_offset );
+ }
+
+ /* Dequant Gains */
+ SKP_Silk_gains_dequant( psDecCtrl->Gains_Q16, GainsIndices, &psDec->LastGainIndex, psDec->nFramesDecoded );
+ /****************/
+ /* Decode NLSFs */
+ /****************/
+ /* Set pointer to NLSF VQ CB for the current signal type */
+ psNLSF_CB = psDec->psNLSF_CB[ psDecCtrl->sigtype ];
+
+ /* Range decode NLSF path */
+ SKP_Silk_range_decoder_multi( NLSFIndices, psRC, psNLSF_CB->StartPtr, psNLSF_CB->MiddleIx, psNLSF_CB->nStages );
+
+ /* From the NLSF path, decode an NLSF vector */
+ SKP_Silk_NLSF_MSVQ_decode( pNLSF_Q15, psNLSF_CB, NLSFIndices, psDec->LPC_order );
+
+ /************************************/
+ /* Decode NLSF interpolation factor */
+ /************************************/
+ SKP_Silk_range_decoder( &psDecCtrl->NLSFInterpCoef_Q2, psRC, SKP_Silk_NLSF_interpolation_factor_CDF,
+ SKP_Silk_NLSF_interpolation_factor_offset );
+
+ /* If just reset, e.g., because internal Fs changed, do not allow interpolation */
+ /* improves the case of packet loss in the first frame after a switch */
+ if( psDec->first_frame_after_reset == 1 ) {
+ psDecCtrl->NLSFInterpCoef_Q2 = 4;
+ }
+
+ if( fullDecoding ) {
+ /* Convert NLSF parameters to AR prediction filter coefficients */
+ SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
+
+ if( psDecCtrl->NLSFInterpCoef_Q2 < 4 ) {
+ /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */
+ /* the previous NLSF1, and the current NLSF1 */
+ for( i = 0; i < psDec->LPC_order; i++ ) {
+ pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + SKP_RSHIFT( SKP_MUL( psDecCtrl->NLSFInterpCoef_Q2,
+ ( pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ) ), 2 );
+ }
+
+ /* Convert NLSF parameters to AR prediction filter coefficients */
+ SKP_Silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
+ } else {
+ /* Copy LPC coefficients for first half from second half */
+ SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ],
+ psDec->LPC_order * sizeof( SKP_int16 ) );
+ }
+ }
+
+ SKP_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( SKP_int ) );
+
+ /* After a packet loss do BWE of LPC coefs */
+ if( psDec->lossCnt ) {
+ SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
+ SKP_Silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
+ }
+
+ if( psDecCtrl->sigtype == SIG_TYPE_VOICED ) {
+ /*********************/
+ /* Decode pitch lags */
+ /*********************/
+ /* Get lag index */
+ if( psDec->fs_kHz == 8 ) {
+ SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_NB_CDF, SKP_Silk_pitch_lag_NB_CDF_offset );
+ } else if( psDec->fs_kHz == 12 ) {
+ SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_MB_CDF, SKP_Silk_pitch_lag_MB_CDF_offset );
+ } else if( psDec->fs_kHz == 16 ) {
+ SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_WB_CDF, SKP_Silk_pitch_lag_WB_CDF_offset );
+ } else {
+ SKP_Silk_range_decoder( &Ixs[ 0 ], psRC, SKP_Silk_pitch_lag_SWB_CDF, SKP_Silk_pitch_lag_SWB_CDF_offset );
+ }
+
+ /* Get countour index */
+ if( psDec->fs_kHz == 8 ) {
+ /* Less codevectors used in 8 khz mode */
+ SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_NB_CDF, SKP_Silk_pitch_contour_NB_CDF_offset );
+ } else {
+ /* Joint for 12, 16, and 24 khz */
+ SKP_Silk_range_decoder( &Ixs[ 1 ], psRC, SKP_Silk_pitch_contour_CDF, SKP_Silk_pitch_contour_CDF_offset );
+ }
+
+ /* Decode pitch values */
+ SKP_Silk_decode_pitch( Ixs[ 0 ], Ixs[ 1 ], psDecCtrl->pitchL, psDec->fs_kHz );
+
+ /********************/
+ /* Decode LTP gains */
+ /********************/
+ /* Decode PERIndex value */
+ SKP_Silk_range_decoder( &psDecCtrl->PERIndex, psRC, SKP_Silk_LTP_per_index_CDF,
+ SKP_Silk_LTP_per_index_CDF_offset );
+
+ /* Decode Codebook Index */
+ cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ psDecCtrl->PERIndex ]; /* set pointer to start of codebook */
+
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTP_gain_CDF_ptrs[ psDecCtrl->PERIndex ],
+ SKP_Silk_LTP_gain_CDF_offsets[ psDecCtrl->PERIndex ] );
+
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = cbk_ptr_Q14[ Ix * LTP_ORDER + i ];
+ }
+ }
+
+ /**********************/
+ /* Decode LTP scaling */
+ /**********************/
+ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_LTPscale_CDF, SKP_Silk_LTPscale_offset );
+ psDecCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ Ix ];
+ } else {
+ SKP_assert( psDecCtrl->sigtype == SIG_TYPE_UNVOICED );
+ SKP_memset( psDecCtrl->pitchL, 0, NB_SUBFR * sizeof( SKP_int ) );
+ SKP_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * NB_SUBFR * sizeof( SKP_int16 ) );
+ psDecCtrl->PERIndex = 0;
+ psDecCtrl->LTP_scale_Q14 = 0;
+ }
+
+ /***************/
+ /* Decode seed */
+ /***************/
+ SKP_Silk_range_decoder( &Ix, psRC, SKP_Silk_Seed_CDF, SKP_Silk_Seed_offset );
+ psDecCtrl->Seed = ( SKP_int32 )Ix;
+ /*********************************************/
+ /* Decode quantization indices of excitation */
+ /*********************************************/
+ SKP_Silk_decode_pulses( psRC, psDecCtrl, q, psDec->frame_length );
+
+ /*********************************************/
+ /* Decode VAD flag */
+ /*********************************************/
+ SKP_Silk_range_decoder( &psDec->vadFlag, psRC, SKP_Silk_vadflag_CDF, SKP_Silk_vadflag_offset );
+
+ /**************************************/
+ /* Decode Frame termination indicator */
+ /**************************************/
+ SKP_Silk_range_decoder( &psDec->FrameTermination, psRC, SKP_Silk_FrameTermination_CDF, SKP_Silk_FrameTermination_offset );
+
+ /****************************************/
+ /* get number of bytes used so far */
+ /****************************************/
+ SKP_Silk_range_coder_get_length( psRC, &nBytesUsed );
+ psDec->nBytesLeft = psRC->bufferLength - nBytesUsed;
+ if( psDec->nBytesLeft < 0 ) {
+ psRC->error = RANGE_CODER_READ_BEYOND_BUFFER;
+ }
+
+ /****************************************/
+ /* check remaining bits in last byte */
+ /****************************************/
+ if( psDec->nBytesLeft == 0 ) {
+ SKP_Silk_range_coder_check_after_decoding( psRC );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_decode_pitch.c b/pkg/silk/csilk/SKP_Silk_decode_pitch.c
new file mode 100644
index 0000000..38b7aa7
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_decode_pitch.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/***********************************************************
+* Pitch analyser function
+********************************************************** */
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_common_pitch_est_defines.h"
+
+void SKP_Silk_decode_pitch(
+ SKP_int lagIndex, /* I */
+ SKP_int contourIndex, /* O */
+ SKP_int pitch_lags[], /* O 4 pitch values */
+ SKP_int Fs_kHz /* I sampling frequency (kHz) */
+)
+{
+ SKP_int lag, i, min_lag;
+
+ min_lag = SKP_SMULBB( PITCH_EST_MIN_LAG_MS, Fs_kHz );
+
+ /* Only for 24 / 16 kHz version for now */
+ lag = min_lag + lagIndex;
+ if( Fs_kHz == 8 ) {
+ /* Only a small codebook for 8 khz */
+ for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
+ pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage2[ i ][ contourIndex ];
+ }
+ } else {
+ for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
+ pitch_lags[ i ] = lag + SKP_Silk_CB_lags_stage3[ i ][ contourIndex ];
+ }
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_decode_pulses.c b/pkg/silk/csilk/SKP_Silk_decode_pulses.c
new file mode 100644
index 0000000..119553f
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_decode_pulses.c
@@ -0,0 +1,105 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/*********************************************/
+/* Decode quantization indices of excitation */
+/*********************************************/
+void SKP_Silk_decode_pulses(
+ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int q[], /* O Excitation signal */
+ const SKP_int frame_length /* I Frame length (preliminary) */
+)
+{
+ SKP_int i, j, k, iter, abs_q, nLS, bit;
+ SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ];
+ SKP_int *pulses_ptr;
+ const SKP_uint16 *cdf_ptr;
+
+ /*********************/
+ /* Decode rate level */
+ /*********************/
+ SKP_Silk_range_decoder( &psDecCtrl->RateLevelIndex, psRC,
+ SKP_Silk_rate_levels_CDF[ psDecCtrl->sigtype ], SKP_Silk_rate_levels_CDF_offset );
+
+ /* Calculate number of shell blocks */
+ iter = frame_length / SHELL_CODEC_FRAME_LENGTH;
+
+ /***************************************************/
+ /* Sum-Weighted-Pulses Decoding */
+ /***************************************************/
+ cdf_ptr = SKP_Silk_pulses_per_block_CDF[ psDecCtrl->RateLevelIndex ];
+ for( i = 0; i < iter; i++ ) {
+ nLshifts[ i ] = 0;
+ SKP_Silk_range_decoder( &sum_pulses[ i ], psRC, cdf_ptr, SKP_Silk_pulses_per_block_CDF_offset );
+
+ /* LSB indication */
+ while( sum_pulses[ i ] == ( MAX_PULSES + 1 ) ) {
+ nLshifts[ i ]++;
+ SKP_Silk_range_decoder( &sum_pulses[ i ], psRC,
+ SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ], SKP_Silk_pulses_per_block_CDF_offset );
+ }
+ }
+
+ /***************************************************/
+ /* Shell decoding */
+ /***************************************************/
+ for( i = 0; i < iter; i++ ) {
+ if( sum_pulses[ i ] > 0 ) {
+ SKP_Silk_shell_decoder( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRC, sum_pulses[ i ] );
+ } else {
+ SKP_memset( &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( SKP_int ) );
+ }
+ }
+
+ /***************************************************/
+ /* LSB Decoding */
+ /***************************************************/
+ for( i = 0; i < iter; i++ ) {
+ if( nLshifts[ i ] > 0 ) {
+ nLS = nLshifts[ i ];
+ pulses_ptr = &q[ SKP_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ];
+ for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
+ abs_q = pulses_ptr[ k ];
+ for( j = 0; j < nLS; j++ ) {
+ abs_q = SKP_LSHIFT( abs_q, 1 );
+ SKP_Silk_range_decoder( &bit, psRC, SKP_Silk_lsb_CDF, 1 );
+ abs_q += bit;
+ }
+ pulses_ptr[ k ] = abs_q;
+ }
+ }
+ }
+
+ /****************************************/
+ /* Decode and add signs to pulse signal */
+ /****************************************/
+ SKP_Silk_decode_signs( psRC, q, frame_length, psDecCtrl->sigtype,
+ psDecCtrl->QuantOffsetType, psDecCtrl->RateLevelIndex);
+}
diff --git a/pkg/silk/csilk/SKP_Silk_decoder_set_fs.c b/pkg/silk/csilk/SKP_Silk_decoder_set_fs.c
new file mode 100644
index 0000000..b4cd08b
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_decoder_set_fs.c
@@ -0,0 +1,80 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Set decoder sampling rate */
+void SKP_Silk_decoder_set_fs(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state pointer */
+ SKP_int fs_kHz /* I Sampling frequency (kHz) */
+)
+{
+ if( psDec->fs_kHz != fs_kHz ) {
+ psDec->fs_kHz = fs_kHz;
+ psDec->frame_length = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz );
+ psDec->subfr_length = SKP_SMULBB( FRAME_LENGTH_MS / NB_SUBFR, fs_kHz );
+ if( psDec->fs_kHz == 8 ) {
+ psDec->LPC_order = MIN_LPC_ORDER;
+ psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_10;
+ psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_10;
+ } else {
+ psDec->LPC_order = MAX_LPC_ORDER;
+ psDec->psNLSF_CB[ 0 ] = &SKP_Silk_NLSF_CB0_16;
+ psDec->psNLSF_CB[ 1 ] = &SKP_Silk_NLSF_CB1_16;
+ }
+ /* Reset part of the decoder state */
+ SKP_memset( psDec->sLPC_Q14, 0, MAX_LPC_ORDER * sizeof( SKP_int32 ) );
+ SKP_memset( psDec->outBuf, 0, MAX_FRAME_LENGTH * sizeof( SKP_int16 ) );
+ SKP_memset( psDec->prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );
+
+ psDec->lagPrev = 100;
+ psDec->LastGainIndex = 1;
+ psDec->prev_sigtype = 0;
+ psDec->first_frame_after_reset = 1;
+
+ if( fs_kHz == 24 ) {
+ psDec->HP_A = SKP_Silk_Dec_A_HP_24;
+ psDec->HP_B = SKP_Silk_Dec_B_HP_24;
+ } else if( fs_kHz == 16 ) {
+ psDec->HP_A = SKP_Silk_Dec_A_HP_16;
+ psDec->HP_B = SKP_Silk_Dec_B_HP_16;
+ } else if( fs_kHz == 12 ) {
+ psDec->HP_A = SKP_Silk_Dec_A_HP_12;
+ psDec->HP_B = SKP_Silk_Dec_B_HP_12;
+ } else if( fs_kHz == 8 ) {
+ psDec->HP_A = SKP_Silk_Dec_A_HP_8;
+ psDec->HP_B = SKP_Silk_Dec_B_HP_8;
+ } else {
+ /* unsupported sampling rate */
+ SKP_assert( 0 );
+ }
+ }
+
+ /* Check that settings are valid */
+ SKP_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_define.h b/pkg/silk/csilk/SKP_Silk_define.h
new file mode 100644
index 0000000..43e8e68
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_define.h
@@ -0,0 +1,306 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_DEFINE_H
+#define SKP_SILK_DEFINE_H
+
+#include "SKP_Silk_errors.h"
+#include "SKP_Silk_typedef.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#define MAX_FRAMES_PER_PACKET 5
+
+
+
+/* Limits on bitrate */
+#define MIN_TARGET_RATE_BPS 5000
+#define MAX_TARGET_RATE_BPS 100000
+
+/* Transition bitrates between modes */
+#define SWB2WB_BITRATE_BPS 25000
+#define WB2SWB_BITRATE_BPS 30000
+#define WB2MB_BITRATE_BPS 14000
+#define MB2WB_BITRATE_BPS 18000
+#define MB2NB_BITRATE_BPS 10000
+#define NB2MB_BITRATE_BPS 14000
+
+/* Integration/hysteresis threshold for lowering internal sample frequency */
+/* 30000000 -> 6 sec if bitrate is 5000 bps below limit; 3 sec if bitrate is 10000 bps below limit */
+#define ACCUM_BITS_DIFF_THRESHOLD 30000000
+#define TARGET_RATE_TAB_SZ 8
+
+/* DTX settings */
+#define NO_SPEECH_FRAMES_BEFORE_DTX 5 /* eq 100 ms */
+#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */
+
+#define USE_LBRR 1
+
+/* Amount of concecutive no FEC packets before telling JB */
+#define NO_LBRR_THRES 10
+
+/* Maximum delay between real packet and LBRR packet */
+#define MAX_LBRR_DELAY 2
+#define LBRR_IDX_MASK 1
+
+#define INBAND_FEC_MIN_RATE_BPS 18000 /* Dont use inband FEC below this total target rate */
+#define LBRR_LOSS_THRES 1 /* Start adding LBRR at this loss rate */
+
+/* LBRR usage defines */
+#define SKP_SILK_NO_LBRR 0 /* No LBRR information for this packet */
+#define SKP_SILK_ADD_LBRR_TO_PLUS1 1 /* Add LBRR for this packet to packet n + 1 */
+#define SKP_SILK_ADD_LBRR_TO_PLUS2 2 /* Add LBRR for this packet to packet n + 2 */
+
+/* Frame termination indicator defines */
+#define SKP_SILK_LAST_FRAME 0 /* Last frames in packet */
+#define SKP_SILK_MORE_FRAMES 1 /* More frames to follow this one */
+#define SKP_SILK_LBRR_VER1 2 /* LBRR information from packet n - 1 */
+#define SKP_SILK_LBRR_VER2 3 /* LBRR information from packet n - 2 */
+#define SKP_SILK_EXT_LAYER 4 /* Extension layers added */
+
+/* Number of Second order Sections for SWB detection HP filter */
+#define NB_SOS 3
+#define HP_8_KHZ_THRES 10 /* average energy per sample, above 8 kHz */
+#define CONCEC_SWB_SMPLS_THRES 480 * 15 /* 300 ms */
+#define WB_DETECT_ACTIVE_SPEECH_MS_THRES 15000 /* ms of active speech needed for WB detection */
+
+/* Low complexity setting */
+#define LOW_COMPLEXITY_ONLY 0
+
+/* Activate bandwidth transition filtering for mode switching */
+#define SWITCH_TRANSITION_FILTERING 1
+
+/* Decoder Parameters */
+#define DEC_HP_ORDER 2
+
+/* Maximum sampling frequency, should be 16 for some embedded platforms */
+#define MAX_FS_KHZ 24
+#define MAX_API_FS_KHZ 48
+
+/* Signal Types used by silk */
+#define SIG_TYPE_VOICED 0
+#define SIG_TYPE_UNVOICED 1
+
+/* VAD Types used by silk */
+#define NO_VOICE_ACTIVITY 0
+#define VOICE_ACTIVITY 1
+
+/* Number of samples per frame */
+#define FRAME_LENGTH_MS 20
+#define MAX_FRAME_LENGTH ( FRAME_LENGTH_MS * MAX_FS_KHZ )
+
+/* Milliseconds of lookahead for pitch analysis */
+#define LA_PITCH_MS 2
+#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ )
+
+/* Length of LPC window used in find pitch */
+#define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) )
+#define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ )
+
+/* Order of LPC used in find pitch */
+#define MAX_FIND_PITCH_LPC_ORDER 16
+
+#define PITCH_EST_COMPLEXITY_HC_MODE SKP_Silk_PITCH_EST_MAX_COMPLEX
+#define PITCH_EST_COMPLEXITY_MC_MODE SKP_Silk_PITCH_EST_MID_COMPLEX
+#define PITCH_EST_COMPLEXITY_LC_MODE SKP_Silk_PITCH_EST_MIN_COMPLEX
+
+/* Milliseconds of lookahead for noise shape analysis */
+#define LA_SHAPE_MS 5
+#define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ )
+
+/* Max length of LPC window used in noise shape analysis */
+#define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ )
+
+/* Max number of bytes in payload output buffer (may contain multiple frames) */
+#define MAX_ARITHM_BYTES 1024
+
+#define RANGE_CODER_WRITE_BEYOND_BUFFER -1
+#define RANGE_CODER_CDF_OUT_OF_RANGE -2
+#define RANGE_CODER_NORMALIZATION_FAILED -3
+#define RANGE_CODER_ZERO_INTERVAL_WIDTH -4
+#define RANGE_CODER_DECODER_CHECK_FAILED -5
+#define RANGE_CODER_READ_BEYOND_BUFFER -6
+#define RANGE_CODER_ILLEGAL_SAMPLING_RATE -7
+#define RANGE_CODER_DEC_PAYLOAD_TOO_LONG -8
+
+/* dB level of lowest gain quantization level */
+#define MIN_QGAIN_DB 6
+/* dB level of highest gain quantization level */
+#define MAX_QGAIN_DB 86
+/* Number of gain quantization levels */
+#define N_LEVELS_QGAIN 64
+/* Max increase in gain quantization index */
+#define MAX_DELTA_GAIN_QUANT 40
+/* Max decrease in gain quantization index */
+#define MIN_DELTA_GAIN_QUANT -4
+
+/* Quantization offsets (multiples of 4) */
+#define OFFSET_VL_Q10 32
+#define OFFSET_VH_Q10 100
+#define OFFSET_UVL_Q10 100
+#define OFFSET_UVH_Q10 256
+
+/* Maximum numbers of iterations used to stabilize a LPC vector */
+#define MAX_LPC_STABILIZE_ITERATIONS 20
+
+#define MAX_LPC_ORDER 16
+#define MIN_LPC_ORDER 10
+
+/* Find Pred Coef defines */
+#define LTP_ORDER 5
+
+/* LTP quantization settings */
+#define NB_LTP_CBKS 3
+
+/* Number of subframes */
+#define NB_SUBFR 4
+
+/* Flag to use harmonic noise shaping */
+#define USE_HARM_SHAPING 1
+
+/* Max LPC order of noise shaping filters */
+#define MAX_SHAPE_LPC_ORDER 16
+
+#define HARM_SHAPE_FIR_TAPS 3
+
+/* Maximum number of delayed decision states */
+#define MAX_DEL_DEC_STATES 4
+
+#define LTP_BUF_LENGTH 512
+#define LTP_MASK (LTP_BUF_LENGTH - 1)
+
+#define DECISION_DELAY 32
+#define DECISION_DELAY_MASK (DECISION_DELAY - 1)
+
+/* number of subframes for excitation entropy coding */
+#define SHELL_CODEC_FRAME_LENGTH 16
+#define MAX_NB_SHELL_BLOCKS (MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH)
+
+/* number of rate levels, for entropy coding of excitation */
+#define N_RATE_LEVELS 10
+
+/* maximum sum of pulses per shell coding frame */
+#define MAX_PULSES 18
+
+#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */
+
+#if( MAX_LPC_ORDER > DECISION_DELAY )
+# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER
+#else
+# define NSQ_LPC_BUF_LENGTH DECISION_DELAY
+#endif
+
+/***********************/
+/* High pass filtering */
+/***********************/
+#define HIGH_PASS_INPUT 1
+
+/***************************/
+/* Voice activity detector */
+/***************************/
+#define VAD_N_BANDS 4
+
+#define VAD_INTERNAL_SUBFRAMES_LOG2 2
+#define VAD_INTERNAL_SUBFRAMES (1 << VAD_INTERNAL_SUBFRAMES_LOG2)
+
+#define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */
+#define VAD_NOISE_LEVELS_BIAS 50
+
+/* Sigmoid settings */
+#define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */
+#define VAD_SNR_FACTOR_Q16 45000
+
+/* smoothing for SNR measurement */
+#define VAD_SNR_SMOOTH_COEF_Q18 4096
+
+/******************/
+/* NLSF quantizer */
+/******************/
+# define NLSF_MSVQ_MAX_CB_STAGES 10 /* Update manually when changing codebooks */
+# define NLSF_MSVQ_MAX_VECTORS_IN_STAGE 128 /* Update manually when changing codebooks */
+# define NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END 16 /* Update manually when changing codebooks */
+
+#define NLSF_MSVQ_FLUCTUATION_REDUCTION 1
+#define MAX_NLSF_MSVQ_SURVIVORS 16
+#define MAX_NLSF_MSVQ_SURVIVORS_LC_MODE 2
+#define MAX_NLSF_MSVQ_SURVIVORS_MC_MODE 4
+
+/* Based on above defines, calculate how much memory is necessary to allocate */
+#if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) )
+# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE NLSF_MSVQ_MAX_VECTORS_IN_STAGE
+#else
+# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED_LC_MODE MAX_NLSF_MSVQ_SURVIVORS_LC_MODE * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END
+#endif
+
+#if( NLSF_MSVQ_MAX_VECTORS_IN_STAGE > ( MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END ) )
+# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED NLSF_MSVQ_MAX_VECTORS_IN_STAGE
+#else
+# define NLSF_MSVQ_TREE_SEARCH_MAX_VECTORS_EVALUATED MAX_NLSF_MSVQ_SURVIVORS * NLSF_MSVQ_MAX_VECTORS_IN_STAGE_TWO_TO_END
+#endif
+
+#define NLSF_MSVQ_SURV_MAX_REL_RD 0.1f /* Must be < 0.5 */
+
+/* Transition filtering for mode switching */
+#if SWITCH_TRANSITION_FILTERING
+# define TRANSITION_TIME_UP_MS 5120 // 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)
+# define TRANSITION_TIME_DOWN_MS 2560 // 2560 = 32 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 32*(20*4)
+# define TRANSITION_NB 3 /* Hardcoded in tables */
+# define TRANSITION_NA 2 /* Hardcoded in tables */
+# define TRANSITION_INT_NUM 5 /* Hardcoded in tables */
+# define TRANSITION_FRAMES_UP ( TRANSITION_TIME_UP_MS / FRAME_LENGTH_MS )
+# define TRANSITION_FRAMES_DOWN ( TRANSITION_TIME_DOWN_MS / FRAME_LENGTH_MS )
+# define TRANSITION_INT_STEPS_UP ( TRANSITION_FRAMES_UP / ( TRANSITION_INT_NUM - 1 ) )
+# define TRANSITION_INT_STEPS_DOWN ( TRANSITION_FRAMES_DOWN / ( TRANSITION_INT_NUM - 1 ) )
+#endif
+
+/* Row based */
+#define matrix_ptr(Matrix_base_adr, row, column, N) *(Matrix_base_adr + ((row)*(N)+(column)))
+#define matrix_adr(Matrix_base_adr, row, column, N) (Matrix_base_adr + ((row)*(N)+(column)))
+
+/* Column based */
+#ifndef matrix_c_ptr
+# define matrix_c_ptr(Matrix_base_adr, row, column, M) *(Matrix_base_adr + ((row)+(M)*(column)))
+#endif
+#define matrix_c_adr(Matrix_base_adr, row, column, M) (Matrix_base_adr + ((row)+(M)*(column)))
+
+/* BWE factors to apply after packet loss */
+#define BWE_AFTER_LOSS_Q16 63570
+
+/* Defines for CN generation */
+#define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */
+#define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */
+#define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_detect_SWB_input.c b/pkg/silk/csilk/SKP_Silk_detect_SWB_input.c
new file mode 100644
index 0000000..eb3ee05
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_detect_SWB_input.c
@@ -0,0 +1,76 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/*
+ * Detect SWB input by measuring energy above 8 kHz.
+ */
+
+#include "SKP_Silk_main.h"
+
+void SKP_Silk_detect_SWB_input(
+ SKP_Silk_detect_SWB_state *psSWBdetect, /* (I/O) encoder state */
+ const SKP_int16 samplesIn[], /* (I) input to encoder */
+ SKP_int nSamplesIn /* (I) length of input */
+)
+{
+ SKP_int HP_8_kHz_len, i, shift;
+ SKP_int16 in_HP_8_kHz[ MAX_FRAME_LENGTH ];
+ SKP_int32 energy_32;
+
+ /* High pass filter with cutoff at 8 khz */
+ HP_8_kHz_len = SKP_min_int( nSamplesIn, MAX_FRAME_LENGTH );
+ HP_8_kHz_len = SKP_max_int( HP_8_kHz_len, 0 );
+
+ /* Cutoff around 9 khz */
+ /* A = conv(conv([8192,14613, 6868], [8192,12883, 7337]), [8192,11586, 7911]); */
+ /* B = conv(conv([575, -948, 575], [575, -221, 575]), [575, 104, 575]); */
+ SKP_Silk_biquad( samplesIn, SKP_Silk_SWB_detect_B_HP_Q13[ 0 ], SKP_Silk_SWB_detect_A_HP_Q13[ 0 ],
+ psSWBdetect->S_HP_8_kHz[ 0 ], in_HP_8_kHz, HP_8_kHz_len );
+ for( i = 1; i < NB_SOS; i++ ) {
+ SKP_Silk_biquad( in_HP_8_kHz, SKP_Silk_SWB_detect_B_HP_Q13[ i ], SKP_Silk_SWB_detect_A_HP_Q13[ i ],
+ psSWBdetect->S_HP_8_kHz[ i ], in_HP_8_kHz, HP_8_kHz_len );
+ }
+
+ /* Calculate energy in HP signal */
+ SKP_Silk_sum_sqr_shift( &energy_32, &shift, in_HP_8_kHz, HP_8_kHz_len );
+
+ /* Count concecutive samples above threshold, after adjusting threshold for number of input samples and shift */
+ if( energy_32 > SKP_RSHIFT( SKP_SMULBB( HP_8_KHZ_THRES, HP_8_kHz_len ), shift ) ) {
+ psSWBdetect->ConsecSmplsAboveThres += nSamplesIn;
+ if( psSWBdetect->ConsecSmplsAboveThres > CONCEC_SWB_SMPLS_THRES ) {
+ psSWBdetect->SWB_detected = 1;
+ }
+ } else {
+ psSWBdetect->ConsecSmplsAboveThres -= nSamplesIn;
+ psSWBdetect->ConsecSmplsAboveThres = SKP_max( psSWBdetect->ConsecSmplsAboveThres, 0 );
+ }
+
+ /* If sufficient speech activity and no SWB detected, we detect the signal as being WB */
+ if( ( psSWBdetect->ActiveSpeech_ms > WB_DETECT_ACTIVE_SPEECH_MS_THRES ) && ( psSWBdetect->SWB_detected == 0 ) ) {
+ psSWBdetect->WB_detected = 1;
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_div_oabi.c b/pkg/silk/csilk/SKP_Silk_div_oabi.c
new file mode 100644
index 0000000..327dcfa
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_div_oabi.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_typedef.h"
+
+SKP_int32 SKP_DIV32_arm( SKP_int32 a32, SKP_int32 b32 ) {
+ return ( ( SKP_int32 )( ( a32 ) / ( b32 ) ) );
+}
+
+
+
diff --git a/pkg/silk/csilk/SKP_Silk_enc_API.c b/pkg/silk/csilk/SKP_Silk_enc_API.c
new file mode 100644
index 0000000..63657ab
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_enc_API.c
@@ -0,0 +1,247 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_define.h"
+#include "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_SDK_API.h"
+#include "SKP_Silk_control.h"
+#include "SKP_Silk_typedef.h"
+#include "SKP_Silk_structs.h"
+#define SKP_Silk_EncodeControlStruct SKP_SILK_SDK_EncControlStruct
+
+/****************************************/
+/* Encoder functions */
+/****************************************/
+
+SKP_int SKP_Silk_SDK_Get_Encoder_Size( SKP_int32 *encSizeBytes )
+{
+ SKP_int ret = 0;
+
+ *encSizeBytes = sizeof( SKP_Silk_encoder_state_FIX );
+
+ return ret;
+}
+
+
+/***************************************/
+/* Read control structure from encoder */
+/***************************************/
+SKP_int SKP_Silk_SDK_QueryEncoder(
+ const void *encState, /* I: State Vector */
+ SKP_Silk_EncodeControlStruct *encStatus /* O: Control Structure */
+)
+{
+ SKP_Silk_encoder_state_FIX *psEnc;
+ SKP_int ret = 0;
+
+ psEnc = ( SKP_Silk_encoder_state_FIX* )encState;
+
+ encStatus->API_sampleRate = psEnc->sCmn.API_fs_Hz;
+ encStatus->maxInternalSampleRate = SKP_SMULBB( psEnc->sCmn.maxInternal_fs_kHz, 1000 );
+ encStatus->packetSize = ( SKP_int )SKP_DIV32_16( psEnc->sCmn.API_fs_Hz * psEnc->sCmn.PacketSize_ms, 1000 ); /* convert samples -> ms */
+ encStatus->bitRate = psEnc->sCmn.TargetRate_bps;
+ encStatus->packetLossPercentage = psEnc->sCmn.PacketLoss_perc;
+ encStatus->complexity = psEnc->sCmn.Complexity;
+ encStatus->useInBandFEC = psEnc->sCmn.useInBandFEC;
+ encStatus->useDTX = psEnc->sCmn.useDTX;
+ return ret;
+}
+
+/*************************/
+/* Init or Reset encoder */
+/*************************/
+SKP_int SKP_Silk_SDK_InitEncoder(
+ void *encState, /* I/O: State */
+ SKP_Silk_EncodeControlStruct *encStatus /* O: Control structure */
+)
+{
+ SKP_Silk_encoder_state_FIX *psEnc;
+ SKP_int ret = 0;
+
+
+ psEnc = ( SKP_Silk_encoder_state_FIX* )encState;
+
+ /* Reset Encoder */
+ if( ret += SKP_Silk_init_encoder_FIX( psEnc ) ) {
+ SKP_assert( 0 );
+ }
+
+ /* Read control structure */
+ if( ret += SKP_Silk_SDK_QueryEncoder( encState, encStatus ) ) {
+ SKP_assert( 0 );
+ }
+
+
+ return ret;
+}
+
+/**************************/
+/* Encode frame with Silk */
+/**************************/
+SKP_int SKP_Silk_SDK_Encode(
+ void *encState, /* I/O: State */
+ const SKP_Silk_EncodeControlStruct *encControl, /* I: Control structure */
+ const SKP_int16 *samplesIn, /* I: Speech sample input vector */
+ SKP_int nSamplesIn, /* I: Number of samples in input vector */
+ SKP_uint8 *outData, /* O: Encoded output vector */
+ SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
+)
+{
+ SKP_int max_internal_fs_kHz, PacketSize_ms, PacketLoss_perc, UseInBandFEC, UseDTX, ret = 0;
+ SKP_int nSamplesToBuffer, Complexity, input_10ms, nSamplesFromInput = 0;
+ SKP_int32 TargetRate_bps, API_fs_Hz;
+ SKP_int16 MaxBytesOut;
+ SKP_Silk_encoder_state_FIX *psEnc = ( SKP_Silk_encoder_state_FIX* )encState;
+
+ SKP_assert( encControl != NULL );
+
+ /* Check sampling frequency first, to avoid divide by zero later */
+ if( ( ( encControl->API_sampleRate != 8000 ) &&
+ ( encControl->API_sampleRate != 12000 ) &&
+ ( encControl->API_sampleRate != 16000 ) &&
+ ( encControl->API_sampleRate != 24000 ) &&
+ ( encControl->API_sampleRate != 32000 ) &&
+ ( encControl->API_sampleRate != 44100 ) &&
+ ( encControl->API_sampleRate != 48000 ) ) ||
+ ( ( encControl->maxInternalSampleRate != 8000 ) &&
+ ( encControl->maxInternalSampleRate != 12000 ) &&
+ ( encControl->maxInternalSampleRate != 16000 ) &&
+ ( encControl->maxInternalSampleRate != 24000 ) ) ) {
+ ret = SKP_SILK_ENC_FS_NOT_SUPPORTED;
+ SKP_assert( 0 );
+ return( ret );
+ }
+
+ /* Set encoder parameters from control structure */
+ API_fs_Hz = encControl->API_sampleRate;
+ max_internal_fs_kHz = (SKP_int)( encControl->maxInternalSampleRate >> 10 ) + 1; /* convert Hz -> kHz */
+ PacketSize_ms = SKP_DIV32( 1000 * (SKP_int)encControl->packetSize, API_fs_Hz );
+ TargetRate_bps = encControl->bitRate;
+ PacketLoss_perc = encControl->packetLossPercentage;
+ UseInBandFEC = encControl->useInBandFEC;
+ Complexity = encControl->complexity;
+ UseDTX = encControl->useDTX;
+
+ /* Save values in state */
+ psEnc->sCmn.API_fs_Hz = API_fs_Hz;
+ psEnc->sCmn.maxInternal_fs_kHz = max_internal_fs_kHz;
+ psEnc->sCmn.useInBandFEC = UseInBandFEC;
+
+ /* Only accept input lengths that are a multiple of 10 ms */
+ input_10ms = SKP_DIV32( 100 * nSamplesIn, API_fs_Hz );
+ if( input_10ms * API_fs_Hz != 100 * nSamplesIn || nSamplesIn < 0 ) {
+ ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
+ SKP_assert( 0 );
+ return( ret );
+ }
+
+ TargetRate_bps = SKP_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
+ if( ( ret = SKP_Silk_control_encoder_FIX( psEnc, PacketSize_ms, TargetRate_bps,
+ PacketLoss_perc, UseDTX, Complexity) ) != 0 ) {
+ SKP_assert( 0 );
+ return( ret );
+ }
+
+ /* Make sure no more than one packet can be produced */
+ if( 1000 * (SKP_int32)nSamplesIn > psEnc->sCmn.PacketSize_ms * API_fs_Hz ) {
+ ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
+ SKP_assert( 0 );
+ return( ret );
+ }
+
+#if MAX_FS_KHZ > 16
+ /* Detect energy above 8 kHz */
+ if( SKP_min( API_fs_Hz, 1000 * max_internal_fs_kHz ) == 24000 &&
+ psEnc->sCmn.sSWBdetect.SWB_detected == 0 &&
+ psEnc->sCmn.sSWBdetect.WB_detected == 0 ) {
+ SKP_Silk_detect_SWB_input( &psEnc->sCmn.sSWBdetect, samplesIn, ( SKP_int )nSamplesIn );
+ }
+#endif
+
+ /* Input buffering/resampling and encoding */
+ MaxBytesOut = 0; /* return 0 output bytes if no encoder called */
+ while( 1 ) {
+ nSamplesToBuffer = psEnc->sCmn.frame_length - psEnc->sCmn.inputBufIx;
+ if( API_fs_Hz == SKP_SMULBB( 1000, psEnc->sCmn.fs_kHz ) ) {
+ nSamplesToBuffer = SKP_min_int( nSamplesToBuffer, nSamplesIn );
+ nSamplesFromInput = nSamplesToBuffer;
+ /* Copy to buffer */
+ SKP_memcpy( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput * sizeof( SKP_int16 ) );
+ } else {
+ nSamplesToBuffer = SKP_min( nSamplesToBuffer, 10 * input_10ms * psEnc->sCmn.fs_kHz );
+ nSamplesFromInput = SKP_DIV32_16( nSamplesToBuffer * API_fs_Hz, psEnc->sCmn.fs_kHz * 1000 );
+ /* Resample and write to buffer */
+ ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state,
+ &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput );
+ }
+ samplesIn += nSamplesFromInput;
+ nSamplesIn -= nSamplesFromInput;
+ psEnc->sCmn.inputBufIx += nSamplesToBuffer;
+
+ /* Silk encoder */
+ if( psEnc->sCmn.inputBufIx >= psEnc->sCmn.frame_length ) {
+ SKP_assert( psEnc->sCmn.inputBufIx == psEnc->sCmn.frame_length );
+
+ /* Enough data in input buffer, so encode */
+ if( MaxBytesOut == 0 ) {
+ /* No payload obtained so far */
+ MaxBytesOut = *nBytesOut;
+ if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, &MaxBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {
+ SKP_assert( 0 );
+ }
+ } else {
+ /* outData already contains a payload */
+ if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, nBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {
+ SKP_assert( 0 );
+ }
+ /* Check that no second payload was created */
+ SKP_assert( *nBytesOut == 0 );
+ }
+ psEnc->sCmn.inputBufIx = 0;
+ psEnc->sCmn.controlled_since_last_payload = 0;
+
+ if( nSamplesIn == 0 ) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ *nBytesOut = MaxBytesOut;
+ if( psEnc->sCmn.useDTX && psEnc->sCmn.inDTX ) {
+ /* DTX simulation */
+ *nBytesOut = 0;
+ }
+
+
+
+ return ret;
+}
+
+
diff --git a/pkg/silk/csilk/SKP_Silk_encode_frame_FIX.c b/pkg/silk/csilk/SKP_Silk_encode_frame_FIX.c
new file mode 100644
index 0000000..c108289
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_encode_frame_FIX.c
@@ -0,0 +1,413 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/****************/
+/* Encode frame */
+/****************/
+SKP_int SKP_Silk_encode_frame_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
+ SKP_uint8 *pCode, /* O Pointer to payload */
+ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */
+ /* input: max length; output: used */
+ const SKP_int16 *pIn /* I Pointer to input speech frame */
+)
+{
+ SKP_Silk_encoder_control_FIX sEncCtrl;
+ SKP_int nBytes, ret = 0;
+ SKP_int16 *x_frame, *res_pitch_frame;
+ SKP_int16 xfw[ MAX_FRAME_LENGTH ];
+ SKP_int16 pIn_HP[ MAX_FRAME_LENGTH ];
+ SKP_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
+ SKP_int LBRR_idx, frame_terminator, SNR_dB_Q7;
+ const SKP_uint16 *FrameTermination_CDF;
+ /* Low bitrate redundancy parameters */
+ SKP_uint8 LBRRpayload[ MAX_ARITHM_BYTES ];
+ SKP_int16 nBytesLBRR;
+
+
+ sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;
+ /**************************************************************/
+ /* Setup Input Pointers, and insert frame in input buffer */
+ /*************************************************************/
+ x_frame = psEnc->x_buf + psEnc->sCmn.frame_length; /* start of frame to encode */
+ res_pitch_frame = res_pitch + psEnc->sCmn.frame_length; /* start of pitch LPC residual frame */
+
+ /****************************/
+ /* Voice Activity Detection */
+ /****************************/
+ ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7,
+ sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15,
+ pIn,psEnc->sCmn.frame_length );
+
+ /*******************************************/
+ /* High-pass filtering of the input signal */
+ /*******************************************/
+#if HIGH_PASS_INPUT
+ /* Variable high-pass filter */
+ SKP_Silk_HP_variable_cutoff_FIX( psEnc, &sEncCtrl, pIn_HP, pIn );
+#else
+ SKP_memcpy( pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
+#endif
+
+#if SWITCH_TRANSITION_FILTERING
+ /* Ensure smooth bandwidth transitions */
+ SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length );
+#else
+ SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP,psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );
+#endif
+
+ /*****************************************/
+ /* Find pitch lags, initial LPC analysis */
+ /*****************************************/
+ SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
+
+ /************************/
+ /* Noise shape analysis */
+ /************************/
+ SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
+
+ /*****************************************/
+ /* Prefiltering for noise shaper */
+ /*****************************************/
+ SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );
+
+ /***************************************************/
+ /* Find linear prediction coefficients (LPC + LTP) */
+ /***************************************************/
+ SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch );
+
+ /****************************************/
+ /* Process gains */
+ /****************************************/
+ SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl );
+
+
+ /****************************************/
+ /* Low Bitrate Redundant Encoding */
+ /****************************************/
+ nBytesLBRR = MAX_ARITHM_BYTES;
+ SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw );
+
+ /*****************************************/
+ /* Noise shaping quantization */
+ /*****************************************/
+ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
+ SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sNSQ, xfw,
+ psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2,
+ sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
+ sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10,
+ sEncCtrl.LTP_scale_Q14 );
+ } else {
+ SKP_Silk_NSQ( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sNSQ, xfw,
+ psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2,
+ sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
+ sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10,
+ sEncCtrl.LTP_scale_Q14 );
+ }
+
+ /**************************************************/
+ /* Convert speech activity into VAD and DTX flags */
+ /**************************************************/
+ if( psEnc->speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
+ psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY;
+ psEnc->sCmn.noSpeechCounter++;
+ if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) {
+ psEnc->sCmn.inDTX = 1;
+ }
+ if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NO_SPEECH_FRAMES_BEFORE_DTX ) {
+ psEnc->sCmn.noSpeechCounter = NO_SPEECH_FRAMES_BEFORE_DTX;
+ psEnc->sCmn.inDTX = 0;
+ }
+ } else {
+ psEnc->sCmn.noSpeechCounter = 0;
+ psEnc->sCmn.inDTX = 0;
+ psEnc->sCmn.vadFlag = VOICE_ACTIVITY;
+ }
+
+ /****************************************/
+ /* Initialize range coder */
+ /****************************************/
+ if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
+ SKP_Silk_range_enc_init( &psEnc->sCmn.sRC );
+ psEnc->sCmn.nBytesInPayloadBuf = 0;
+ }
+
+ /****************************************/
+ /* Encode Parameters */
+ /****************************************/
+ SKP_Silk_encode_parameters( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC, psEnc->sCmn.q );
+ FrameTermination_CDF = SKP_Silk_FrameTermination_CDF;
+
+ /****************************************/
+ /* Update Buffers and State */
+ /****************************************/
+ /* Update input buffer */
+ SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
+ ( psEnc->sCmn.frame_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) );
+
+ /* Parameters needed for next frame */
+ psEnc->sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype;
+ psEnc->sCmn.prevLag = sEncCtrl.sCmn.pitchL[ NB_SUBFR - 1];
+ psEnc->sCmn.first_frame_after_reset = 0;
+
+ if( psEnc->sCmn.sRC.error ) {
+ /* Encoder returned error: clear payload buffer */
+ psEnc->sCmn.nFramesInPayloadBuf = 0;
+ } else {
+ psEnc->sCmn.nFramesInPayloadBuf++;
+ }
+
+ /****************************************/
+ /* Finalize payload and copy to output */
+ /****************************************/
+ if( psEnc->sCmn.nFramesInPayloadBuf * FRAME_LENGTH_MS >= psEnc->sCmn.PacketSize_ms ) {
+
+ LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;
+
+ /* Check if FEC information should be added */
+ frame_terminator = SKP_SILK_LAST_FRAME;
+ if( psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS1 ) {
+ frame_terminator = SKP_SILK_LBRR_VER1;
+ }
+ if( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS2 ) {
+ frame_terminator = SKP_SILK_LBRR_VER2;
+ LBRR_idx = psEnc->sCmn.oldest_LBRR_idx;
+ }
+
+ /* Add the frame termination info to stream */
+ SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );
+
+ /* Payload length so far */
+ SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );
+
+ /* Check that there is enough space in external output buffer, and move data */
+ if( *pnBytesOut >= nBytes ) {
+ SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC );
+ SKP_memcpy( pCode, psEnc->sCmn.sRC.buffer, nBytes * sizeof( SKP_uint8 ) );
+
+ if( frame_terminator > SKP_SILK_MORE_FRAMES &&
+ *pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) {
+ /* Get old packet and add to payload. */
+ SKP_memcpy( &pCode[ nBytes ],
+ psEnc->sCmn.LBRR_buffer[ LBRR_idx ].payload,
+ psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes * sizeof( SKP_uint8 ) );
+ nBytes += psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes;
+ }
+
+ *pnBytesOut = nBytes;
+
+ /* Update FEC buffer */
+ SKP_memcpy( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].payload, LBRRpayload,
+ nBytesLBRR * sizeof( SKP_uint8 ) );
+ psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR;
+ /* The line below describes how FEC should be used */
+ psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage;
+ psEnc->sCmn.oldest_LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;
+
+ } else {
+ /* Not enough space: Payload will be discarded */
+ *pnBytesOut = 0;
+ nBytes = 0;
+ ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT;
+ }
+
+ /* Reset the number of frames in payload buffer */
+ psEnc->sCmn.nFramesInPayloadBuf = 0;
+ } else {
+ /* No payload this time */
+ *pnBytesOut = 0;
+
+ /* Encode that more frames follows */
+ frame_terminator = SKP_SILK_MORE_FRAMES;
+ SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );
+
+ /* Payload length so far */
+ SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC, &nBytes );
+
+ }
+
+ /* Check for arithmetic coder errors */
+ if( psEnc->sCmn.sRC.error ) {
+ ret = SKP_SILK_ENC_INTERNAL_ERROR;
+ }
+
+ /* Simulate number of ms buffered in channel because of exceeding TargetRate */
+ SKP_assert( ( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) ==
+ SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) );
+ SKP_assert( psEnc->sCmn.TargetRate_bps > 0 );
+ psEnc->BufferedInChannel_ms += SKP_DIV32( 8 * 1000 * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ), psEnc->sCmn.TargetRate_bps );
+ psEnc->BufferedInChannel_ms -= FRAME_LENGTH_MS;
+ psEnc->BufferedInChannel_ms = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 );
+ psEnc->sCmn.nBytesInPayloadBuf = nBytes;
+
+ if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES, 8 ) ) {
+ psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, FRAME_LENGTH_MS );
+ }
+
+
+ return( ret );
+}
+
+/* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */
+void SKP_Silk_LBRR_encode_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk encoder control struct */
+ SKP_uint8 *pCode, /* O Pointer to payload */
+ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */
+ SKP_int16 xfw[] /* I Input signal */
+)
+{
+ SKP_int TempGainsIndices[ NB_SUBFR ], frame_terminator;
+ SKP_int nBytes, nFramesInPayloadBuf;
+ SKP_int32 TempGains_Q16[ NB_SUBFR ];
+ SKP_int typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;
+ /*******************************************/
+ /* Control use of inband LBRR */
+ /*******************************************/
+ SKP_Silk_LBRR_ctrl_FIX( psEnc, &psEncCtrl->sCmn );
+
+ if( psEnc->sCmn.LBRR_enabled ) {
+ /* Save original gains */
+ SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, NB_SUBFR * sizeof( SKP_int ) );
+ SKP_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, NB_SUBFR * sizeof( SKP_int32 ) );
+
+ typeOffset = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten
+ LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;
+
+ /* Set max rate where quant signal is encoded */
+ if( psEnc->sCmn.fs_kHz == 8 ) {
+ Rate_only_parameters = 13500;
+ } else if( psEnc->sCmn.fs_kHz == 12 ) {
+ Rate_only_parameters = 15500;
+ } else if( psEnc->sCmn.fs_kHz == 16 ) {
+ Rate_only_parameters = 17500;
+ } else if( psEnc->sCmn.fs_kHz == 24 ) {
+ Rate_only_parameters = 19500;
+ } else {
+ SKP_assert( 0 );
+ }
+
+ if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {
+ if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
+ /* First frame in packet; copy everything */
+ SKP_memcpy( &psEnc->sCmn.sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( SKP_Silk_nsq_state ) );
+
+ psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
+ /* Increase Gains to get target LBRR rate */
+ psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
+ psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );
+ }
+ /* Decode to get gains in sync with decoder */
+ /* Overwrite unquantized gains with quantized gains */
+ SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices,
+ &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf );
+
+ /*****************************************/
+ /* Noise shaping quantization */
+ /*****************************************/
+ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
+ SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR,
+ psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
+ psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+ psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
+ } else {
+ SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR,
+ psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
+ psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+ psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
+ }
+ } else {
+ SKP_memset( psEnc->sCmn.q_LBRR, 0, psEnc->sCmn.frame_length * sizeof( SKP_int8 ) );
+ psEncCtrl->sCmn.LTP_scaleIndex = 0;
+ }
+ /****************************************/
+ /* Initialize arithmetic coder */
+ /****************************************/
+ if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
+ SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );
+ psEnc->sCmn.nBytesInPayloadBuf = 0;
+ }
+
+ /****************************************/
+ /* Encode Parameters */
+ /****************************************/
+ SKP_Silk_encode_parameters( &psEnc->sCmn, &psEncCtrl->sCmn,
+ &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.q_LBRR );
+
+ if( psEnc->sCmn.sRC_LBRR.error ) {
+ /* Encoder returned error: clear payload buffer */
+ nFramesInPayloadBuf = 0;
+ } else {
+ nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;
+ }
+
+ /****************************************/
+ /* Finalize payload and copy to output */
+ /****************************************/
+ if( SKP_SMULBB( nFramesInPayloadBuf, FRAME_LENGTH_MS ) >= psEnc->sCmn.PacketSize_ms ) {
+
+ /* Check if FEC information should be added */
+ frame_terminator = SKP_SILK_LAST_FRAME;
+
+ /* Add the frame termination info to stream */
+ SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );
+
+ /* Payload length so far */
+ SKP_Silk_range_coder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes );
+
+ /* Check that there is enough space in external output buffer and move data */
+ if( *pnBytesOut >= nBytes ) {
+ SKP_Silk_range_enc_wrap_up( &psEnc->sCmn.sRC_LBRR );
+ SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.buffer, nBytes * sizeof( SKP_uint8 ) );
+
+ *pnBytesOut = nBytes;
+ } else {
+ /* Not enough space: payload will be discarded */
+ *pnBytesOut = 0;
+ SKP_assert( 0 );
+ }
+ } else {
+ /* No payload this time */
+ *pnBytesOut = 0;
+
+ /* Encode that more frames follows */
+ frame_terminator = SKP_SILK_MORE_FRAMES;
+ SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_CDF );
+ }
+
+ /* Restore original Gains */
+ SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, NB_SUBFR * sizeof( SKP_int ) );
+ SKP_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, NB_SUBFR * sizeof( SKP_int32 ) );
+
+ /* Restore LTP scale index and typeoffset */
+ psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;
+ psEnc->sCmn.typeOffsetPrev = typeOffset;
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_encode_parameters.c b/pkg/silk/csilk/SKP_Silk_encode_parameters.c
new file mode 100644
index 0000000..be50e01
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_encode_parameters.c
@@ -0,0 +1,162 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/*******************************************/
+/* Encode parameters to create the payload */
+/*******************************************/
+void SKP_Silk_encode_parameters(
+ SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */
+ SKP_Silk_encoder_control *psEncCtrlC, /* I/O Encoder control */
+ SKP_Silk_range_coder_state *psRC, /* I/O Range encoder state */
+ const SKP_int8 *q /* I Quantization indices */
+)
+{
+ SKP_int i, k, typeOffset;
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB;
+
+
+ /************************/
+ /* Encode sampling rate */
+ /************************/
+ /* only done for first frame in packet */
+ if( psEncC->nFramesInPayloadBuf == 0 ) {
+ /* get sampling rate index */
+ for( i = 0; i < 3; i++ ) {
+ if( SKP_Silk_SamplingRates_table[ i ] == psEncC->fs_kHz ) {
+ break;
+ }
+ }
+ SKP_Silk_range_encoder( psRC, i, SKP_Silk_SamplingRates_CDF );
+ }
+
+ /*******************************************/
+ /* Encode signal type and quantizer offset */
+ /*******************************************/
+ typeOffset = 2 * psEncCtrlC->sigtype + psEncCtrlC->QuantOffsetType;
+ if( psEncC->nFramesInPayloadBuf == 0 ) {
+ /* first frame in packet: independent coding */
+ SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_CDF );
+ } else {
+ /* condidtional coding */
+ SKP_Silk_range_encoder( psRC, typeOffset, SKP_Silk_type_offset_joint_CDF[ psEncC->typeOffsetPrev ] );
+ }
+ psEncC->typeOffsetPrev = typeOffset;
+
+ /****************/
+ /* Encode gains */
+ /****************/
+ /* first subframe */
+ if( psEncC->nFramesInPayloadBuf == 0 ) {
+ /* first frame in packet: independent coding */
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_gain_CDF[ psEncCtrlC->sigtype ] );
+ } else {
+ /* condidtional coding */
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ 0 ], SKP_Silk_delta_gain_CDF );
+ }
+
+ /* remaining subframes */
+ for( i = 1; i < NB_SUBFR; i++ ) {
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->GainsIndices[ i ], SKP_Silk_delta_gain_CDF );
+ }
+
+
+ /****************/
+ /* Encode NLSFs */
+ /****************/
+ /* Range encoding of the NLSF path */
+ psNLSF_CB = psEncC->psNLSF_CB[ psEncCtrlC->sigtype ];
+ SKP_Silk_range_encoder_multi( psRC, psEncCtrlC->NLSFIndices, psNLSF_CB->StartPtr, psNLSF_CB->nStages );
+
+ /* Encode NLSF interpolation factor */
+ SKP_assert( psEncC->useInterpolatedNLSFs == 1 || psEncCtrlC->NLSFInterpCoef_Q2 == ( 1 << 2 ) );
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->NLSFInterpCoef_Q2, SKP_Silk_NLSF_interpolation_factor_CDF );
+
+
+ if( psEncCtrlC->sigtype == SIG_TYPE_VOICED ) {
+ /*********************/
+ /* Encode pitch lags */
+ /*********************/
+
+
+ /* lag index */
+ if( psEncC->fs_kHz == 8 ) {
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_NB_CDF );
+ } else if( psEncC->fs_kHz == 12 ) {
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_MB_CDF );
+ } else if( psEncC->fs_kHz == 16 ) {
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_WB_CDF );
+ } else {
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->lagIndex, SKP_Silk_pitch_lag_SWB_CDF );
+ }
+
+
+ /* countour index */
+ if( psEncC->fs_kHz == 8 ) {
+ /* Less codevectors used in 8 khz mode */
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_NB_CDF );
+ } else {
+ /* Joint for 12, 16, 24 khz */
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->contourIndex, SKP_Silk_pitch_contour_CDF );
+ }
+
+ /********************/
+ /* Encode LTP gains */
+ /********************/
+
+ /* PERIndex value */
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->PERIndex, SKP_Silk_LTP_per_index_CDF );
+
+ /* Codebook Indices */
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->LTPIndex[ k ], SKP_Silk_LTP_gain_CDF_ptrs[ psEncCtrlC->PERIndex ] );
+ }
+
+ /**********************/
+ /* Encode LTP scaling */
+ /**********************/
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->LTP_scaleIndex, SKP_Silk_LTPscale_CDF );
+ }
+
+
+ /***************/
+ /* Encode seed */
+ /***************/
+ SKP_Silk_range_encoder( psRC, psEncCtrlC->Seed, SKP_Silk_Seed_CDF );
+
+ /*********************************************/
+ /* Encode quantization indices of excitation */
+ /*********************************************/
+ SKP_Silk_encode_pulses( psRC, psEncCtrlC->sigtype, psEncCtrlC->QuantOffsetType, q, psEncC->frame_length );
+
+
+ /*********************************************/
+ /* Encode VAD flag */
+ /*********************************************/
+ SKP_Silk_range_encoder( psRC, psEncC->vadFlag, SKP_Silk_vadflag_CDF );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_encode_pulses.c b/pkg/silk/csilk/SKP_Silk_encode_pulses.c
new file mode 100644
index 0000000..b0ea05e
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_encode_pulses.c
@@ -0,0 +1,195 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/*********************************************/
+/* Encode quantization indices of excitation */
+/*********************************************/
+
+SKP_INLINE SKP_int combine_and_check( /* return ok */
+ SKP_int *pulses_comb, /* O */
+ const SKP_int *pulses_in, /* I */
+ SKP_int max_pulses, /* I max value for sum of pulses */
+ SKP_int len /* I number of output values */
+)
+{
+ SKP_int k, sum;
+
+ for( k = 0; k < len; k++ ) {
+ sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ];
+ if( sum > max_pulses ) {
+ return 1;
+ }
+ pulses_comb[ k ] = sum;
+ }
+
+ return 0;
+}
+
+/* Encode quantization indices of excitation */
+void SKP_Silk_encode_pulses(
+ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
+ const SKP_int sigtype, /* I Sigtype */
+ const SKP_int QuantOffsetType,/* I QuantOffsetType */
+ const SKP_int8 q[], /* I quantization indices */
+ const SKP_int frame_length /* I Frame length */
+)
+{
+ SKP_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;
+ SKP_int32 abs_q, minSumBits_Q6, sumBits_Q6;
+ SKP_int abs_pulses[ MAX_FRAME_LENGTH ];
+ SKP_int sum_pulses[ MAX_NB_SHELL_BLOCKS ];
+ SKP_int nRshifts[ MAX_NB_SHELL_BLOCKS ];
+ SKP_int pulses_comb[ 8 ];
+ SKP_int *abs_pulses_ptr;
+ const SKP_int8 *pulses_ptr;
+ const SKP_uint16 *cdf_ptr;
+ const SKP_int16 *nBits_ptr;
+
+ SKP_memset( pulses_comb, 0, 8 * sizeof( SKP_int ) ); // Fixing Valgrind reported problem
+
+ /****************************/
+ /* Prepare for shell coding */
+ /****************************/
+ /* Calculate number of shell blocks */
+ iter = frame_length / SHELL_CODEC_FRAME_LENGTH;
+
+ /* Take the absolute value of the pulses */
+ for( i = 0; i < frame_length; i+=4 ) {
+ abs_pulses[i+0] = ( SKP_int )SKP_abs( q[ i + 0 ] );
+ abs_pulses[i+1] = ( SKP_int )SKP_abs( q[ i + 1 ] );
+ abs_pulses[i+2] = ( SKP_int )SKP_abs( q[ i + 2 ] );
+ abs_pulses[i+3] = ( SKP_int )SKP_abs( q[ i + 3 ] );
+ }
+
+ /* Calc sum pulses per shell code frame */
+ abs_pulses_ptr = abs_pulses;
+ for( i = 0; i < iter; i++ ) {
+ nRshifts[ i ] = 0;
+
+ while( 1 ) {
+ /* 1+1 -> 2 */
+ scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, SKP_Silk_max_pulses_table[ 0 ], 8 );
+
+ /* 2+2 -> 4 */
+ scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 1 ], 4 );
+
+ /* 4+4 -> 8 */
+ scale_down += combine_and_check( pulses_comb, pulses_comb, SKP_Silk_max_pulses_table[ 2 ], 2 );
+
+ /* 8+8 -> 16 */
+ sum_pulses[ i ] = pulses_comb[ 0 ] + pulses_comb[ 1 ];
+ if( sum_pulses[ i ] > SKP_Silk_max_pulses_table[ 3 ] ) {
+ scale_down++;
+ }
+
+ if( scale_down ) {
+ /* We need to down scale the quantization signal */
+ nRshifts[ i ]++;
+ for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
+ abs_pulses_ptr[ k ] = SKP_RSHIFT( abs_pulses_ptr[ k ], 1 );
+ }
+ } else {
+ /* Jump out of while(1) loop and go to next shell coding frame */
+ break;
+ }
+ }
+ abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH;
+ }
+
+ /**************/
+ /* Rate level */
+ /**************/
+ /* find rate level that leads to fewest bits for coding of pulses per block info */
+ minSumBits_Q6 = SKP_int32_MAX;
+ for( k = 0; k < N_RATE_LEVELS - 1; k++ ) {
+ nBits_ptr = SKP_Silk_pulses_per_block_BITS_Q6[ k ];
+ sumBits_Q6 = SKP_Silk_rate_levels_BITS_Q6[sigtype][ k ];
+ for( i = 0; i < iter; i++ ) {
+ if( nRshifts[ i ] > 0 ) {
+ sumBits_Q6 += nBits_ptr[ MAX_PULSES + 1 ];
+ } else {
+ sumBits_Q6 += nBits_ptr[ sum_pulses[ i ] ];
+ }
+ }
+ if( sumBits_Q6 < minSumBits_Q6 ) {
+ minSumBits_Q6 = sumBits_Q6;
+ RateLevelIndex = k;
+ }
+ }
+ SKP_Silk_range_encoder( psRC, RateLevelIndex, SKP_Silk_rate_levels_CDF[ sigtype ] );
+
+ /***************************************************/
+ /* Sum-Weighted-Pulses Encoding */
+ /***************************************************/
+ cdf_ptr = SKP_Silk_pulses_per_block_CDF[ RateLevelIndex ];
+ for( i = 0; i < iter; i++ ) {
+ if( nRshifts[ i ] == 0 ) {
+ SKP_Silk_range_encoder( psRC, sum_pulses[ i ], cdf_ptr );
+ } else {
+ SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, cdf_ptr );
+ for( k = 0; k < nRshifts[ i ] - 1; k++ ) {
+ SKP_Silk_range_encoder( psRC, MAX_PULSES + 1, SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] );
+ }
+ SKP_Silk_range_encoder( psRC, sum_pulses[ i ], SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS - 1 ] );
+ }
+ }
+
+ /******************/
+ /* Shell Encoding */
+ /******************/
+ for( i = 0; i < iter; i++ ) {
+ if( sum_pulses[ i ] > 0 ) {
+ SKP_Silk_shell_encoder( psRC, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] );
+ }
+ }
+
+ /****************/
+ /* LSB Encoding */
+ /****************/
+ for( i = 0; i < iter; i++ ) {
+ if( nRshifts[ i ] > 0 ) {
+ pulses_ptr = &q[ i * SHELL_CODEC_FRAME_LENGTH ];
+ nLS = nRshifts[ i ] - 1;
+ for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
+ abs_q = (SKP_int8)SKP_abs( pulses_ptr[ k ] );
+ for( j = nLS; j > 0; j-- ) {
+ bit = SKP_RSHIFT( abs_q, j ) & 1;
+ SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF );
+ }
+ bit = abs_q & 1;
+ SKP_Silk_range_encoder( psRC, bit, SKP_Silk_lsb_CDF );
+ }
+ }
+ }
+
+ /****************/
+ /* Encode signs */
+ /****************/
+ SKP_Silk_encode_signs( psRC, q, frame_length, sigtype, QuantOffsetType, RateLevelIndex );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_errors.h b/pkg/silk/csilk/SKP_Silk_errors.h
new file mode 100644
index 0000000..ee2a487
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_errors.h
@@ -0,0 +1,89 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_ERRORS_H
+#define SKP_SILK_ERRORS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/******************/
+/* Error messages */
+/******************/
+#define SKP_SILK_NO_ERROR 0
+
+/**************************/
+/* Encoder error messages */
+/**************************/
+
+/* Input length is not a multiplum of 10 ms, or length is longer than the packet length */
+#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -1
+
+/* Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */
+#define SKP_SILK_ENC_FS_NOT_SUPPORTED -2
+
+/* Packet size not 20, 40, 60, 80 or 100 ms */
+#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -3
+
+/* Allocated payload buffer too short */
+#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT -4
+
+/* Loss rate not between 0 and 100 percent */
+#define SKP_SILK_ENC_INVALID_LOSS_RATE -5
+
+/* Complexity setting not valid, use 0, 1 or 2 */
+#define SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING -6
+
+/* Inband FEC setting not valid, use 0 or 1 */
+#define SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING -7
+
+/* DTX setting not valid, use 0 or 1 */
+#define SKP_SILK_ENC_INVALID_DTX_SETTING -8
+
+/* Internal encoder error */
+#define SKP_SILK_ENC_INTERNAL_ERROR -9
+
+/**************************/
+/* Decoder error messages */
+/**************************/
+
+/* Output sampling frequency lower than internal decoded sampling frequency */
+#define SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY -10
+
+/* Payload size exceeded the maximum allowed 1024 bytes */
+#define SKP_SILK_DEC_PAYLOAD_TOO_LARGE -11
+
+/* Payload has bit errors */
+#define SKP_SILK_DEC_PAYLOAD_ERROR -12
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_find_LPC_FIX.c b/pkg/silk/csilk/SKP_Silk_find_LPC_FIX.c
new file mode 100644
index 0000000..5a0c7c7
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_find_LPC_FIX.c
@@ -0,0 +1,148 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/* Finds LPC vector from correlations, and converts to NLSF */
+void SKP_Silk_find_LPC_FIX(
+ SKP_int NLSF_Q15[], /* O NLSFs */
+ SKP_int *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */
+ const SKP_int prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */
+ const SKP_int useInterpolatedNLSFs, /* I Flag */
+ const SKP_int LPC_order, /* I LPC order */
+ const SKP_int16 x[], /* I Input signal */
+ const SKP_int subfr_length /* I Input signal subframe length including preceeding samples */
+)
+{
+ SKP_int k;
+ SKP_int32 a_Q16[ MAX_LPC_ORDER ];
+ SKP_int isInterpLower, shift;
+ SKP_int16 S[ MAX_LPC_ORDER ];
+ SKP_int32 res_nrg0, res_nrg1;
+ SKP_int rshift0, rshift1;
+
+ /* Used only for LSF interpolation */
+ SKP_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;
+ SKP_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
+ SKP_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
+ SKP_int NLSF0_Q15[ MAX_LPC_ORDER ];
+ SKP_int16 LPC_res[ ( MAX_FRAME_LENGTH + NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
+
+ /* Default: no interpolation */
+ *interpIndex = 4;
+
+ /* Burg AR analysis for the full frame */
+ SKP_Silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, subfr_length, NB_SUBFR, SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
+
+ SKP_Silk_bwexpander_32( a_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
+
+ if( useInterpolatedNLSFs == 1 ) {
+
+ /* Optimal solution for last 10 ms */
+ SKP_Silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + ( NB_SUBFR >> 1 ) * subfr_length,
+ subfr_length, ( NB_SUBFR >> 1 ), SKP_FIX_CONST( FIND_LPC_COND_FAC, 32 ), LPC_order );
+
+ SKP_Silk_bwexpander_32( a_tmp_Q16, LPC_order, SKP_FIX_CONST( FIND_LPC_CHIRP, 16 ) );
+
+ /* subtract residual energy here, as that's easier than adding it to the */
+ /* residual energy of the first 10 ms in each iteration of the search below */
+ shift = res_tmp_nrg_Q - res_nrg_Q;
+ if( shift >= 0 ) {
+ if( shift < 32 ) {
+ res_nrg = res_nrg - SKP_RSHIFT( res_tmp_nrg, shift );
+ }
+ } else {
+ SKP_assert( shift > -32 );
+ res_nrg = SKP_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
+ res_nrg_Q = res_tmp_nrg_Q;
+ }
+
+ /* Convert to NLSFs */
+ SKP_Silk_A2NLSF( NLSF_Q15, a_tmp_Q16, LPC_order );
+
+ /* Search over interpolation indices to find the one with lowest residual energy */
+ for( k = 3; k >= 0; k-- ) {
+ /* Interpolate NLSFs for first half */
+ SKP_Silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
+
+ /* Convert to LPC for residual energy evaluation */
+ SKP_Silk_NLSF2A_stable( a_tmp_Q12, NLSF0_Q15, LPC_order );
+
+ /* Calculate residual energy with NLSF interpolation */
+ SKP_memset( S, 0, LPC_order * sizeof( SKP_int16 ) );
+ SKP_Silk_LPC_analysis_filter( x, a_tmp_Q12, S, LPC_res, 2 * subfr_length, LPC_order );
+
+ SKP_Silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + LPC_order, subfr_length - LPC_order );
+ SKP_Silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + LPC_order + subfr_length, subfr_length - LPC_order );
+
+ /* Add subframe energies from first half frame */
+ shift = rshift0 - rshift1;
+ if( shift >= 0 ) {
+ res_nrg1 = SKP_RSHIFT( res_nrg1, shift );
+ res_nrg_interp_Q = -rshift0;
+ } else {
+ res_nrg0 = SKP_RSHIFT( res_nrg0, -shift );
+ res_nrg_interp_Q = -rshift1;
+ }
+ res_nrg_interp = SKP_ADD32( res_nrg0, res_nrg1 );
+
+ /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
+ shift = res_nrg_interp_Q - res_nrg_Q;
+ if( shift >= 0 ) {
+ if( SKP_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
+ isInterpLower = SKP_TRUE;
+ } else {
+ isInterpLower = SKP_FALSE;
+ }
+ } else {
+ if( -shift < 32 ) {
+ if( res_nrg_interp < SKP_RSHIFT( res_nrg, -shift ) ) {
+ isInterpLower = SKP_TRUE;
+ } else {
+ isInterpLower = SKP_FALSE;
+ }
+ } else {
+ isInterpLower = SKP_FALSE;
+ }
+ }
+
+ /* Determine whether current interpolated NLSFs are best so far */
+ if( isInterpLower == SKP_TRUE ) {
+ /* Interpolation has lower residual energy */
+ res_nrg = res_nrg_interp;
+ res_nrg_Q = res_nrg_interp_Q;
+ *interpIndex = k;
+ }
+ }
+ }
+
+ if( *interpIndex == 4 ) {
+ /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
+ SKP_Silk_A2NLSF( NLSF_Q15, a_Q16, LPC_order );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_find_LTP_FIX.c b/pkg/silk/csilk/SKP_Silk_find_LTP_FIX.c
new file mode 100644
index 0000000..4d047ff
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_find_LTP_FIX.c
@@ -0,0 +1,243 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/* Head room for correlations */
+#define LTP_CORRS_HEAD_ROOM 2
+
+void SKP_Silk_fit_LTP(
+ SKP_int32 LTP_coefs_Q16[ LTP_ORDER ],
+ SKP_int16 LTP_coefs_Q14[ LTP_ORDER ]
+);
+
+void SKP_Silk_find_LTP_FIX(
+ SKP_int16 b_Q14[ NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
+ SKP_int32 WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
+ SKP_int *LTPredCodGain_Q7, /* O LTP coding gain */
+ const SKP_int16 r_first[], /* I residual signal after LPC signal + state for first 10 ms */
+ const SKP_int16 r_last[], /* I residual signal after LPC signal + state for last 10 ms */
+ const SKP_int lag[ NB_SUBFR ], /* I LTP lags */
+ const SKP_int32 Wght_Q15[ NB_SUBFR ], /* I weights */
+ const SKP_int subfr_length, /* I subframe length */
+ const SKP_int mem_offset, /* I number of samples in LTP memory */
+ SKP_int corr_rshifts[ NB_SUBFR ] /* O right shifts applied to correlations */
+)
+{
+ SKP_int i, k, lshift;
+ const SKP_int16 *r_ptr, *lag_ptr;
+ SKP_int16 *b_Q14_ptr;
+
+ SKP_int32 regu;
+ SKP_int32 *WLTP_ptr;
+ SKP_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ NB_SUBFR ], nrg[ NB_SUBFR ], g_Q26;
+ SKP_int32 w[ NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;
+
+ SKP_int32 temp32, denom32;
+ SKP_int extra_shifts;
+ SKP_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;
+ SKP_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;
+ SKP_int32 Rr[ LTP_ORDER ], rr[ NB_SUBFR ];
+ SKP_int32 wd, m_Q12;
+
+ b_Q14_ptr = b_Q14;
+ WLTP_ptr = WLTP;
+ r_ptr = &r_first[ mem_offset ];
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ if( k == ( NB_SUBFR >> 1 ) ) { /* shift residual for last 10 ms */
+ r_ptr = &r_last[ mem_offset ];
+ }
+ lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
+
+ SKP_Silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */
+
+ /* Assure headroom */
+ LZs = SKP_Silk_CLZ32( rr[k] );
+ if( LZs < LTP_CORRS_HEAD_ROOM ) {
+ rr[ k ] = SKP_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );
+ rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );
+ }
+ corr_rshifts[ k ] = rr_shifts;
+ SKP_Silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */
+
+ /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */
+ SKP_Silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */
+ if( corr_rshifts[ k ] > rr_shifts ) {
+ rr[ k ] = SKP_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */
+ }
+ SKP_assert( rr[ k ] >= 0 );
+
+ regu = 1;
+ regu = SKP_SMLAWB( regu, rr[ k ], SKP_FIX_CONST( LTP_DAMPING/3, 16 ) );
+ regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) );
+ regu = SKP_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SKP_FIX_CONST( LTP_DAMPING/3, 16 ) );
+ SKP_Silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );
+
+ SKP_Silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */
+
+ /* Limit and store in Q14 */
+ SKP_Silk_fit_LTP( b_Q16, b_Q14_ptr );
+
+ /* Calculate residual energy */
+ nrg[ k ] = SKP_Silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */
+
+ /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */
+ extra_shifts = SKP_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );
+ denom32 = SKP_LSHIFT_SAT32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */
+ SKP_RSHIFT( SKP_SMULWB( subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */
+ denom32 = SKP_max( denom32, 1 );
+ SKP_assert( ((SKP_int64)Wght_Q15[ k ] << 16 ) < SKP_int32_MAX ); /* Wght always < 0.5 in Q0 */
+ temp32 = SKP_DIV32( SKP_LSHIFT( ( SKP_int32 )Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
+ temp32 = SKP_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */
+
+ /* Limit temp such that the below scaling never wraps around */
+ WLTP_max = 0;
+ for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
+ WLTP_max = SKP_max( WLTP_ptr[ i ], WLTP_max );
+ }
+ lshift = SKP_Silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
+ SKP_assert( 26 - 18 + lshift >= 0 );
+ if( 26 - 18 + lshift < 31 ) {
+ temp32 = SKP_min_32( temp32, SKP_LSHIFT( ( SKP_int32 )1, 26 - 18 + lshift ) );
+ }
+
+ SKP_Silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
+
+ w[ k ] = matrix_ptr( WLTP_ptr, ( LTP_ORDER >> 1 ), ( LTP_ORDER >> 1 ), LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */
+ SKP_assert( w[k] >= 0 );
+
+ r_ptr += subfr_length;
+ b_Q14_ptr += LTP_ORDER;
+ WLTP_ptr += LTP_ORDER * LTP_ORDER;
+ }
+
+ maxRshifts = 0;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ maxRshifts = SKP_max_int( corr_rshifts[ k ], maxRshifts );
+ }
+
+ /* Compute LTP coding gain */
+ if( LTPredCodGain_Q7 != NULL ) {
+ LPC_LTP_res_nrg = 0;
+ LPC_res_nrg = 0;
+ SKP_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ LPC_res_nrg = SKP_ADD32( LPC_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
+ LPC_LTP_res_nrg = SKP_ADD32( LPC_LTP_res_nrg, SKP_RSHIFT( SKP_ADD32( SKP_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
+ }
+ LPC_LTP_res_nrg = SKP_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */
+
+ div_Q16 = SKP_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );
+ *LTPredCodGain_Q7 = ( SKP_int )SKP_SMULBB( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) );
+
+ SKP_assert( *LTPredCodGain_Q7 == ( SKP_int )SKP_SAT16( SKP_MUL( 3, SKP_Silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );
+ }
+
+ /* smoothing */
+ /* d = sum( B, 1 ); */
+ b_Q14_ptr = b_Q14;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ d_Q14[ k ] = 0;
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ d_Q14[ k ] += b_Q14_ptr[ i ];
+ }
+ b_Q14_ptr += LTP_ORDER;
+ }
+
+ /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
+
+ /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */
+ max_abs_d_Q14 = 0;
+ max_w_bits = 0;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ max_abs_d_Q14 = SKP_max_32( max_abs_d_Q14, SKP_abs( d_Q14[ k ] ) );
+ /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */
+ /* Find bits needed in Q( 18 - maxRshifts ) */
+ max_w_bits = SKP_max_32( max_w_bits, 32 - SKP_Silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts );
+ }
+
+ /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -SKP_int16_MIN */
+ SKP_assert( max_abs_d_Q14 <= ( 5 << 15 ) );
+
+ /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */
+ extra_shifts = max_w_bits + 32 - SKP_Silk_CLZ32( max_abs_d_Q14 ) - 14;
+
+ /* Subtract what we got available; bits in output var plus maxRshifts */
+ extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */
+ extra_shifts = SKP_max_int( extra_shifts, 0 );
+
+ maxRshifts_wxtra = maxRshifts + extra_shifts;
+
+ temp32 = SKP_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */
+ wd = 0;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ /* w has at least 2 bits of headroom so no overflow should happen */
+ temp32 = SKP_ADD32( temp32, SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */
+ wd = SKP_ADD32( wd, SKP_LSHIFT( SKP_SMULWW( SKP_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */
+ }
+ m_Q12 = SKP_DIV32_varQ( wd, temp32, 12 );
+
+ b_Q14_ptr = b_Q14;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */
+ if( 2 - corr_rshifts[k] > 0 ) {
+ temp32 = SKP_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );
+ } else {
+ temp32 = SKP_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );
+ }
+
+ g_Q26 = SKP_MUL(
+ SKP_DIV32(
+ SKP_FIX_CONST( LTP_SMOOTHING, 26 ),
+ SKP_RSHIFT( SKP_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */
+ SKP_LSHIFT_SAT32( SKP_SUB_SAT32( ( SKP_int32 )m_Q12, SKP_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */
+
+ temp32 = 0;
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ delta_b_Q14[ i ] = SKP_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */
+ temp32 += delta_b_Q14[ i ]; /* Q14 */
+ }
+ temp32 = SKP_DIV32( g_Q26, temp32 ); /* Q14->Q12 */
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ b_Q14_ptr[ i ] = SKP_LIMIT_32( ( SKP_int32 )b_Q14_ptr[ i ] + SKP_SMULWB( SKP_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
+ }
+ b_Q14_ptr += LTP_ORDER;
+ }
+}
+
+void SKP_Silk_fit_LTP(
+ SKP_int32 LTP_coefs_Q16[ LTP_ORDER ],
+ SKP_int16 LTP_coefs_Q14[ LTP_ORDER ]
+)
+{
+ SKP_int i;
+
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ LTP_coefs_Q14[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_find_pitch_lags_FIX.c b/pkg/silk/csilk/SKP_Silk_find_pitch_lags_FIX.c
new file mode 100644
index 0000000..a8fe42e
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_find_pitch_lags_FIX.c
@@ -0,0 +1,125 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/* Find pitch lags */
+void SKP_Silk_find_pitch_lags_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
+ SKP_int16 res[], /* O residual */
+ const SKP_int16 x[] /* I Speech signal */
+)
+{
+ SKP_Silk_predict_state_FIX *psPredSt = &psEnc->sPred;
+ SKP_int buf_len, i, scale;
+ SKP_int32 thrhld_Q15, res_nrg;
+ const SKP_int16 *x_buf, *x_buf_ptr;
+ SKP_int16 Wsig[ FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr;
+ SKP_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
+ SKP_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ];
+ SKP_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ];
+ SKP_int32 FiltState[ MAX_FIND_PITCH_LPC_ORDER ];
+ SKP_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
+
+ /******************************************/
+ /* Setup buffer lengths etc based on Fs */
+ /******************************************/
+ buf_len = SKP_ADD_LSHIFT( psEnc->sCmn.la_pitch, psEnc->sCmn.frame_length, 1 );
+
+ /* Safty check */
+ SKP_assert( buf_len >= psPredSt->pitch_LPC_win_length );
+
+ x_buf = x - psEnc->sCmn.frame_length;
+
+ /*************************************/
+ /* Estimate LPC AR coefficients */
+ /*************************************/
+
+ /* Calculate windowed signal */
+
+ /* First LA_LTP samples */
+ x_buf_ptr = x_buf + buf_len - psPredSt->pitch_LPC_win_length;
+ Wsig_ptr = Wsig;
+ SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
+
+ /* Middle un - windowed samples */
+ Wsig_ptr += psEnc->sCmn.la_pitch;
+ x_buf_ptr += psEnc->sCmn.la_pitch;
+ SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( SKP_int16 ) );
+
+ /* Last LA_LTP samples */
+ Wsig_ptr += psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );
+ x_buf_ptr += psPredSt->pitch_LPC_win_length - SKP_LSHIFT( psEnc->sCmn.la_pitch, 1 );
+ SKP_Silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
+
+ /* Calculate autocorrelation sequence */
+ SKP_Silk_autocorr( auto_corr, &scale, Wsig, psPredSt->pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );
+
+ /* Add white noise, as fraction of energy */
+ auto_corr[ 0 ] = SKP_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
+
+ /* Calculate the reflection coefficients using schur */
+ res_nrg = SKP_Silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
+
+ /* Prediction gain */
+ psEncCtrl->predGain_Q16 = SKP_DIV32_varQ( auto_corr[ 0 ], SKP_max_int( res_nrg, 1 ), 16 );
+
+ /* Convert reflection coefficients to prediction coefficients */
+ SKP_Silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );
+
+ /* Convert From 32 bit Q24 to 16 bit Q12 coefs */
+ for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
+ A_Q12[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT( A_Q24[ i ], 12 ) );
+ }
+
+ /* Do BWE */
+ SKP_Silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SKP_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) );
+
+ /*****************************************/
+ /* LPC analysis filtering */
+ /*****************************************/
+ SKP_memset( FiltState, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_int32 ) ); /* Not really necessary, but Valgrind will complain otherwise */
+ SKP_Silk_MA_Prediction( x_buf, A_Q12, FiltState, res, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );
+ SKP_memset( res, 0, psEnc->sCmn.pitchEstimationLPCOrder * sizeof( SKP_int16 ) );
+
+ /* Threshold for pitch estimator */
+ thrhld_Q15 = SKP_FIX_CONST( 0.45, 15 );
+ thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder );
+ thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( -0.1, 7 ), psEnc->speech_activity_Q8 );
+ thrhld_Q15 = SKP_SMLABB( thrhld_Q15, SKP_FIX_CONST( 0.15, 15 ), psEnc->sCmn.prev_sigtype );
+ thrhld_Q15 = SKP_SMLAWB( thrhld_Q15, SKP_FIX_CONST( -0.1, 16 ), psEncCtrl->input_tilt_Q15 );
+ thrhld_Q15 = SKP_SAT16( thrhld_Q15 );
+
+ /*****************************************/
+ /* Call pitch estimator */
+ /*****************************************/
+ psEncCtrl->sCmn.sigtype = SKP_Silk_pitch_analysis_core( res, psEncCtrl->sCmn.pitchL, &psEncCtrl->sCmn.lagIndex,
+ &psEncCtrl->sCmn.contourIndex, &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
+ ( SKP_int16 )thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, SKP_FALSE );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_find_pred_coefs_FIX.c b/pkg/silk/csilk/SKP_Silk_find_pred_coefs_FIX.c
new file mode 100644
index 0000000..11764a6
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_find_pred_coefs_FIX.c
@@ -0,0 +1,132 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+
+void SKP_Silk_find_pred_coefs_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
+ const SKP_int16 res_pitch[] /* I Residual from pitch analysis */
+)
+{
+ SKP_int i;
+ SKP_int32 WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ];
+ SKP_int32 invGains_Q16[ NB_SUBFR ], local_gains[ NB_SUBFR ], Wght_Q15[ NB_SUBFR ];
+ SKP_int NLSF_Q15[ MAX_LPC_ORDER ];
+ const SKP_int16 *x_ptr;
+ SKP_int16 *x_pre_ptr, LPC_in_pre[ NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
+ SKP_int32 tmp, min_gain_Q16;
+ SKP_int LTP_corrs_rshift[ NB_SUBFR ];
+
+
+ /* weighting for weighted least squares */
+ min_gain_Q16 = SKP_int32_MAX >> 6;
+ for( i = 0; i < NB_SUBFR; i++ ) {
+ min_gain_Q16 = SKP_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );
+ }
+ for( i = 0; i < NB_SUBFR; i++ ) {
+ /* Divide to Q16 */
+ SKP_assert( psEncCtrl->Gains_Q16[ i ] > 0 );
+ /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
+ invGains_Q16[ i ] = SKP_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
+
+ /* Ensure Wght_Q15 a minimum value 1 */
+ invGains_Q16[ i ] = SKP_max( invGains_Q16[ i ], 363 );
+
+ /* Square the inverted gains */
+ SKP_assert( invGains_Q16[ i ] == SKP_SAT16( invGains_Q16[ i ] ) );
+ tmp = SKP_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] );
+ Wght_Q15[ i ] = SKP_RSHIFT( tmp, 1 );
+
+ /* Invert the inverted and normalized gains */
+ local_gains[ i ] = SKP_DIV32( ( 1 << 16 ), invGains_Q16[ i ] );
+ }
+
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ /**********/
+ /* VOICED */
+ /**********/
+ SKP_assert( psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->sCmn.pitchL[ 0 ] + LTP_ORDER / 2 );
+
+ /* LTP analysis */
+ SKP_Silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, res_pitch,
+ res_pitch + SKP_RSHIFT( psEnc->sCmn.frame_length, 1 ), psEncCtrl->sCmn.pitchL, Wght_Q15,
+ psEnc->sCmn.subfr_length, psEnc->sCmn.frame_length, LTP_corrs_rshift );
+
+
+ /* Quantize LTP gain parameters */
+ SKP_Silk_quant_LTP_gains_FIX( psEncCtrl->LTPCoef_Q14, psEncCtrl->sCmn.LTPIndex, &psEncCtrl->sCmn.PERIndex,
+ WLTP, psEnc->mu_LTP_Q8, psEnc->sCmn.LTPQuantLowComplexity );
+
+ /* Control LTP scaling */
+ SKP_Silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl );
+
+ /* Create LTP residual */
+ SKP_Silk_LTP_analysis_filter_FIX( LPC_in_pre, psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder,
+ psEncCtrl->LTPCoef_Q14, psEncCtrl->sCmn.pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder );
+
+ } else {
+ /************/
+ /* UNVOICED */
+ /************/
+ /* Create signal with prepended subframes, scaled by inverse gains */
+ x_ptr = psEnc->x_buf + psEnc->sCmn.frame_length - psEnc->sCmn.predictLPCOrder;
+ x_pre_ptr = LPC_in_pre;
+ for( i = 0; i < NB_SUBFR; i++ ) {
+ SKP_Silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ],
+ psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
+ x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
+ x_ptr += psEnc->sCmn.subfr_length;
+ }
+
+ SKP_memset( psEncCtrl->LTPCoef_Q14, 0, NB_SUBFR * LTP_ORDER * sizeof( SKP_int16 ) );
+ psEncCtrl->LTPredCodGain_Q7 = 0;
+ }
+
+ /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
+ TIC(FIND_LPC)
+ SKP_Silk_find_LPC_FIX( NLSF_Q15, &psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sPred.prev_NLSFq_Q15,
+ psEnc->sCmn.useInterpolatedNLSFs * ( 1 - psEnc->sCmn.first_frame_after_reset ), psEnc->sCmn.predictLPCOrder,
+ LPC_in_pre, psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
+ TOC(FIND_LPC)
+
+
+ /* Quantize LSFs */
+ TIC(PROCESS_LSFS)
+ SKP_Silk_process_NLSFs_FIX( psEnc, psEncCtrl, NLSF_Q15 );
+ TOC(PROCESS_LSFS)
+
+ /* Calculate residual energy using quantized LPC coefficients */
+ SKP_Silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,
+ psEnc->sCmn.subfr_length, psEnc->sCmn.predictLPCOrder );
+
+ /* Copy to prediction struct for use in next frame for fluctuation reduction */
+ SKP_memcpy( psEnc->sPred.prev_NLSFq_Q15, NLSF_Q15, psEnc->sCmn.predictLPCOrder * sizeof( SKP_int ) );
+
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_gain_quant.c b/pkg/silk/csilk/SKP_Silk_gain_quant.c
new file mode 100644
index 0000000..c33fe49
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_gain_quant.c
@@ -0,0 +1,94 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+#define OFFSET ( ( MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 )
+#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) )
+#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) )
+
+/* Gain scalar quantization with hysteresis, uniform on log scale */
+void SKP_Silk_gains_quant(
+ SKP_int ind[ NB_SUBFR ], /* O gain indices */
+ SKP_int32 gain_Q16[ NB_SUBFR ], /* I/O gains (quantized out) */
+ SKP_int *prev_ind, /* I/O last index in previous frame */
+ const SKP_int conditional /* I first gain is delta coded if 1 */
+)
+{
+ SKP_int k;
+
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ /* Add half of previous quantization error, convert to log scale, scale, floor() */
+ ind[ k ] = SKP_SMULWB( SCALE_Q16, SKP_Silk_lin2log( gain_Q16[ k ] ) - OFFSET );
+
+ /* Round towards previous quantized gain (hysteresis) */
+ if( ind[ k ] < *prev_ind ) {
+ ind[ k ]++;
+ }
+
+ /* Compute delta indices and limit */
+ if( k == 0 && conditional == 0 ) {
+ /* Full index */
+ ind[ k ] = SKP_LIMIT_int( ind[ k ], 0, N_LEVELS_QGAIN - 1 );
+ ind[ k ] = SKP_max_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT );
+ *prev_ind = ind[ k ];
+ } else {
+ /* Delta index */
+ ind[ k ] = SKP_LIMIT_int( ind[ k ] - *prev_ind, MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT );
+ /* Accumulate deltas */
+ *prev_ind += ind[ k ];
+ /* Shift to make non-negative */
+ ind[ k ] -= MIN_DELTA_GAIN_QUANT;
+ }
+
+ /* Convert to linear scale and scale */
+ gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3968 = 31 in Q7 */
+ }
+}
+
+/* Gains scalar dequantization, uniform on log scale */
+void SKP_Silk_gains_dequant(
+ SKP_int32 gain_Q16[ NB_SUBFR ], /* O quantized gains */
+ const SKP_int ind[ NB_SUBFR ], /* I gain indices */
+ SKP_int *prev_ind, /* I/O last index in previous frame */
+ const SKP_int conditional /* I first gain is delta coded if 1 */
+)
+{
+ SKP_int k;
+
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ if( k == 0 && conditional == 0 ) {
+ *prev_ind = ind[ k ];
+ } else {
+ /* Delta index */
+ *prev_ind += ind[ k ] + MIN_DELTA_GAIN_QUANT;
+ }
+
+ /* Convert to linear scale and scale */
+ gain_Q16[ k ] = SKP_Silk_log2lin( SKP_min_32( SKP_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3968 = 31 in Q7 */
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_init_encoder_FIX.c b/pkg/silk/csilk/SKP_Silk_init_encoder_FIX.c
new file mode 100644
index 0000000..7fa445c
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_init_encoder_FIX.c
@@ -0,0 +1,56 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/*********************************/
+/* Initialize Silk Encoder state */
+/*********************************/
+SKP_int SKP_Silk_init_encoder_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */
+) {
+ SKP_int ret = 0;
+ /* Clear the entire encoder state */
+ SKP_memset( psEnc, 0, sizeof( SKP_Silk_encoder_state_FIX ) );
+
+#if HIGH_PASS_INPUT
+ psEnc->variable_HP_smth1_Q15 = 200844; /* = SKP_Silk_log2(70)_Q0; */
+ psEnc->variable_HP_smth2_Q15 = 200844; /* = SKP_Silk_log2(70)_Q0; */
+#endif
+
+ /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */
+ psEnc->sCmn.first_frame_after_reset = 1;
+
+ /* Initialize Silk VAD */
+ ret += SKP_Silk_VAD_Init( &psEnc->sCmn.sVAD );
+
+ /* Initialize NSQ */
+ psEnc->sCmn.sNSQ.prev_inv_gain_Q16 = 65536;
+ psEnc->sCmn.sNSQ_LBRR.prev_inv_gain_Q16 = 65536;
+
+ return( ret );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_inner_prod_aligned.c b/pkg/silk/csilk/SKP_Silk_inner_prod_aligned.c
new file mode 100644
index 0000000..8e738f2
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_inner_prod_aligned.c
@@ -0,0 +1,73 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_inner_prod_aligned.c *
+ * *
+ * *
+ * Copyright 2008-2010 (c), Skype Limited *
+ * Date: 080601 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* sum= for(i=0;i6, memory access can be reduced by half. */
+
+#if (EMBEDDED_ARM<5)
+SKP_int32 SKP_Silk_inner_prod_aligned(
+ const SKP_int16* const inVec1, /* I input vector 1 */
+ const SKP_int16* const inVec2, /* I input vector 2 */
+ const SKP_int len /* I vector lengths */
+)
+{
+ SKP_int i;
+ SKP_int32 sum = 0;
+ for( i = 0; i < len; i++ ) {
+ sum = SKP_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
+ }
+ return sum;
+}
+#endif
+
+#if (EMBEDDED_ARM<5)
+SKP_int64 SKP_Silk_inner_prod16_aligned_64(
+ const SKP_int16 *inVec1, /* I input vector 1 */
+ const SKP_int16 *inVec2, /* I input vector 2 */
+ const SKP_int len /* I vector lengths */
+)
+{
+ SKP_int i;
+ SKP_int64 sum = 0;
+ for( i = 0; i < len; i++ ) {
+ sum = SKP_SMLALBB( sum, inVec1[ i ], inVec2[ i ] );
+ }
+ return sum;
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_interpolate.c b/pkg/silk/csilk/SKP_Silk_interpolate.c
new file mode 100644
index 0000000..73b9eb5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_interpolate.c
@@ -0,0 +1,47 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Interpolate two vectors */
+void SKP_Silk_interpolate(
+ SKP_int xi[ MAX_LPC_ORDER ], /* O interpolated vector */
+ const SKP_int x0[ MAX_LPC_ORDER ], /* I first vector */
+ const SKP_int x1[ MAX_LPC_ORDER ], /* I second vector */
+ const SKP_int ifact_Q2, /* I interp. factor, weight on 2nd vector */
+ const SKP_int d /* I number of parameters */
+)
+{
+ SKP_int i;
+
+ SKP_assert( ifact_Q2 >= 0 );
+ SKP_assert( ifact_Q2 <= ( 1 << 2 ) );
+
+ for( i = 0; i < d; i++ ) {
+ xi[ i ] = ( SKP_int )( ( SKP_int32 )x0[ i ] + SKP_RSHIFT( SKP_MUL( ( SKP_int32 )x1[ i ] - ( SKP_int32 )x0[ i ], ifact_Q2 ), 2 ) );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_k2a.c b/pkg/silk/csilk/SKP_Silk_k2a.c
new file mode 100644
index 0000000..3d3d19a
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_k2a.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_k2a.c *
+ * *
+ * Step up function, converts reflection coefficients to prediction *
+ * coefficients *
+ * *
+ * Copyright 2008 (c), Skype Limited *
+ * Date: 080103 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void SKP_Silk_k2a(
+ SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
+ const SKP_int16 *rc_Q15, /* I: Reflection coefficients [order] Q15 */
+ const SKP_int32 order /* I: Prediction order */
+)
+{
+ SKP_int k, n;
+ SKP_int32 Atmp[ SKP_Silk_MAX_ORDER_LPC ];
+
+ for( k = 0; k < order; k++ ) {
+ for( n = 0; n < k; n++ ) {
+ Atmp[ n ] = A_Q24[ n ];
+ }
+ for( n = 0; n < k; n++ ) {
+ A_Q24[ n ] = SKP_SMLAWB( A_Q24[ n ], SKP_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );
+ }
+ A_Q24[ k ] = -SKP_LSHIFT( (SKP_int32)rc_Q15[ k ], 9 );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_k2a_Q16.c b/pkg/silk/csilk/SKP_Silk_k2a_Q16.c
new file mode 100644
index 0000000..176f24e
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_k2a_Q16.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_k2a.c *
+ * *
+ * Step up function, converts reflection coefficients to prediction *
+ * coefficients *
+ * *
+ * Copyright 2008 (c), Skype Limited *
+ * Date: 080103 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Step up function, converts reflection coefficients to prediction coefficients */
+void SKP_Silk_k2a_Q16(
+ SKP_int32 *A_Q24, /* O: Prediction coefficients [order] Q24 */
+ const SKP_int32 *rc_Q16, /* I: Reflection coefficients [order] Q16 */
+ const SKP_int32 order /* I: Prediction order */
+)
+{
+ SKP_int k, n;
+ SKP_int32 Atmp[ SKP_Silk_MAX_ORDER_LPC ];
+
+ for( k = 0; k < order; k++ ) {
+ for( n = 0; n < k; n++ ) {
+ Atmp[ n ] = A_Q24[ n ];
+ }
+ for( n = 0; n < k; n++ ) {
+ A_Q24[ n ] = SKP_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] );
+ }
+ A_Q24[ k ] = -SKP_LSHIFT( rc_Q16[ k ], 8 );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_lin2log.c b/pkg/silk/csilk/SKP_Silk_lin2log.c
new file mode 100644
index 0000000..b917c97
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_lin2log.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_lin2log.c *
+ * *
+ * Convert input to a log scale *
+ * Approximation of 128 * log2() *
+ * *
+ * Copyright 2006 (c), Skype Limited *
+ * Date: 060221 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+#if EMBEDDED_ARM<4
+/* Approximation of 128 * log2() (very close inverse of approx 2^() below) */
+/* Convert input to a log scale */
+SKP_int32 SKP_Silk_lin2log( const SKP_int32 inLin ) /* I: Input in linear scale */
+{
+ SKP_int32 lz, frac_Q7;
+
+ SKP_Silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );
+
+ /* Piece-wise parabolic approximation */
+ return( SKP_LSHIFT( 31 - lz, 7 ) + SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), 179 ) );
+}
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_log2lin.c b/pkg/silk/csilk/SKP_Silk_log2lin.c
new file mode 100644
index 0000000..0124c30
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_log2lin.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_log2lin.c *
+ * *
+ * Convert input to a linear scale *
+ * *
+ * Copyright 2006 (c), Skype Limited *
+ * Date: 060221 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Approximation of 2^() (very close inverse of SKP_Silk_lin2log()) */
+/* Convert input to a linear scale */
+SKP_int32 SKP_Silk_log2lin( const SKP_int32 inLog_Q7 ) /* I: Input on log scale */
+{
+ SKP_int32 out, frac_Q7;
+
+ if( inLog_Q7 < 0 ) {
+ return( 0 );
+ } else if( inLog_Q7 >= ( 31 << 7 ) ) {
+ /* Saturate, and prevent wrap-around */
+ return( SKP_int32_MAX );
+ }
+
+ out = SKP_LSHIFT( 1, SKP_RSHIFT( inLog_Q7, 7 ) );
+ frac_Q7 = inLog_Q7 & 0x7F;
+ if( inLog_Q7 < 2048 ) {
+ /* Piece-wise parabolic approximation */
+ out = SKP_ADD_RSHIFT( out, SKP_MUL( out, SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 );
+ } else {
+ /* Piece-wise parabolic approximation */
+ out = SKP_MLA( out, SKP_RSHIFT( out, 7 ), SKP_SMLAWB( frac_Q7, SKP_MUL( frac_Q7, 128 - frac_Q7 ), -174 ) );
+ }
+ return out;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_macros.h b/pkg/silk/csilk/SKP_Silk_macros.h
new file mode 100644
index 0000000..9ccd750
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_macros.h
@@ -0,0 +1,125 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 _SKP_SILK_API_C_H_
+#define _SKP_SILK_API_C_H_
+
+// This is an inline header file for general platform.
+
+// (a32 * (SKP_int32)((SKP_int16)(b32))) >> 16 output have to be 32bit int
+#define SKP_SMULWB(a32, b32) ((((a32) >> 16) * (SKP_int32)((SKP_int16)(b32))) + ((((a32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(b32))) >> 16))
+
+// a32 + (b32 * (SKP_int32)((SKP_int16)(c32))) >> 16 output have to be 32bit int
+#define SKP_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (SKP_int32)((SKP_int16)(c32))) + ((((b32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(c32))) >> 16)))
+
+// (a32 * (b32 >> 16)) >> 16
+#define SKP_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))
+
+// a32 + (b32 * (c32 >> 16)) >> 16
+#define SKP_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
+
+// (SKP_int32)((SKP_int16)(a3))) * (SKP_int32)((SKP_int16)(b32)) output have to be 32bit int
+#define SKP_SMULBB(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * (SKP_int32)((SKP_int16)(b32)))
+
+// a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32)) output have to be 32bit int
+#define SKP_SMLABB(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32)))
+
+// (SKP_int32)((SKP_int16)(a32)) * (b32 >> 16)
+#define SKP_SMULBT(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * ((b32) >> 16))
+
+// a32 + (SKP_int32)((SKP_int16)(b32)) * (c32 >> 16)
+#define SKP_SMLABT(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * ((c32) >> 16))
+
+// a64 + (b32 * c32)
+#define SKP_SMLAL(a64, b32, c32) (SKP_ADD64((a64), ((SKP_int64)(b32) * (SKP_int64)(c32))))
+
+// (a32 * b32) >> 16
+#define SKP_SMULWW(a32, b32) SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16))
+
+// a32 + ((b32 * c32) >> 16)
+#define SKP_SMLAWW(a32, b32, c32) SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16))
+
+// (SKP_int32)(((SKP_int64)a32 * b32) >> 32)
+#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
+
+/* add/subtract with output saturated */
+#define SKP_ADD_SAT32(a, b) ((((a) + (b)) & 0x80000000) == 0 ? \
+ ((((a) & (b)) & 0x80000000) != 0 ? SKP_int32_MIN : (a)+(b)) : \
+ ((((a) | (b)) & 0x80000000) == 0 ? SKP_int32_MAX : (a)+(b)) )
+
+#define SKP_SUB_SAT32(a, b) ((((a)-(b)) & 0x80000000) == 0 ? \
+ (( (a) & ((b)^0x80000000) & 0x80000000) ? SKP_int32_MIN : (a)-(b)) : \
+ ((((a)^0x80000000) & (b) & 0x80000000) ? SKP_int32_MAX : (a)-(b)) )
+
+SKP_INLINE SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16)
+{
+ SKP_int32 out32 = 0;
+ if( in16 == 0 ) {
+ return 16;
+ }
+ /* test nibbles */
+ if( in16 & 0xFF00 ) {
+ if( in16 & 0xF000 ) {
+ in16 >>= 12;
+ } else {
+ out32 += 4;
+ in16 >>= 8;
+ }
+ } else {
+ if( in16 & 0xFFF0 ) {
+ out32 += 8;
+ in16 >>= 4;
+ } else {
+ out32 += 12;
+ }
+ }
+ /* test bits and return */
+ if( in16 & 0xC ) {
+ if( in16 & 0x8 )
+ return out32 + 0;
+ else
+ return out32 + 1;
+ } else {
+ if( in16 & 0xE )
+ return out32 + 2;
+ else
+ return out32 + 3;
+ }
+}
+
+SKP_INLINE SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32)
+{
+ /* test highest 16 bits and convert to SKP_int16 */
+ if( in32 & 0xFFFF0000 ) {
+ return SKP_Silk_CLZ16((SKP_int16)(in32 >> 16));
+ } else {
+ return SKP_Silk_CLZ16((SKP_int16)in32) + 16;
+ }
+}
+
+#endif //_SKP_SILK_API_C_H_
+
diff --git a/pkg/silk/csilk/SKP_Silk_macros_arm.h b/pkg/silk/csilk/SKP_Silk_macros_arm.h
new file mode 100644
index 0000000..4e9d3c2
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_macros_arm.h
@@ -0,0 +1,248 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 _SKP_SILK_API_ARM_H_
+#define _SKP_SILK_API_ARM_H_
+
+// This is an inline header file for embedded arm platform.
+
+#if EMBEDDED_ARM==4
+extern SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16);
+extern SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32);
+
+// (a32 * (SKP_int32)((SKP_int16)(b32))) >> 16
+#define SKP_SMULWB(a32, b32) ((((a32) >> 16) * (SKP_int32)((SKP_int16)(b32))) + ((((a32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(b32))) >> 16))
+
+// a32 + (b32 * (SKP_int32)((SKP_int16)(c32))) >> 16
+#define SKP_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (SKP_int32)((SKP_int16)(c32))) + ((((b32) & 0x0000FFFF) * (SKP_int32)((SKP_int16)(c32))) >> 16)))
+
+/*SKP_INLINE SKP_int32 SKP_SMULWT(SKP_int32 a32, SKP_int32 b32)
+{
+ SKP_int32 out32, tmp;
+ SKP_int32 tmp32=0xFFFF0000;
+ asm volatile("and %1, %3, %4 \n\t smull %3, %0, %2, %1" : "=&r" (out32), "=&r" (tmp) : "r" (a32), "r" (b32), "r" (tmp32));
+ return(out32);
+}*/
+
+// (a32 * (b32 >> 16)) >> 16
+#define SKP_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))
+
+// a32 + (b32 * (c32 >> 16)) >> 16
+#define SKP_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
+
+// (SKP_int32)((SKP_int16)(a3))) * (SKP_int32)((SKP_int16)(b32))
+#define SKP_SMULBB(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * (SKP_int32)((SKP_int16)(b32)))
+
+// a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32))
+#define SKP_SMLABB(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32)))
+
+// a32 + (SKP_int32)((SKP_int16)(b32)) * (SKP_int32)((SKP_int16)(c32))
+#define SKP_SMLABB_ovflw(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * (SKP_int32)((SKP_int16)(c32)))
+
+// (SKP_int32)((SKP_int16)(a32)) * (b32 >> 16)
+#define SKP_SMULBT(a32, b32) ((SKP_int32)((SKP_int16)(a32)) * ((b32) >> 16))
+
+// a32 + (SKP_int32)((SKP_int16)(b32)) * (c32 >> 16)
+#define SKP_SMLABT(a32, b32, c32) ((a32) + ((SKP_int32)((SKP_int16)(b32))) * ((c32) >> 16))
+
+SKP_INLINE SKP_int64 SKP_SMLAL(SKP_int64 a64, SKP_int32 b32, SKP_int32 c32)
+{
+#ifdef IPHONE
+ // IPHONE LLVM compiler doesn't understand Q/R representation.
+ a64 = (SKP_int64)b32 * c32;
+ return(a64);
+#else
+ __asm__ __volatile__ ("smlal %Q0, %R0, %2, %3" : "=r" (a64) : "0" (a64), "r" (b32), "r" (c32));
+ return(a64);
+#endif
+}
+
+// (a32 * b32) >> 16
+#define SKP_SMULWW(a32, b32) SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16))
+
+// a32 + ((b32 * c32) >> 16)
+#define SKP_SMLAWW(a32, b32, c32) SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16))
+
+/* add/subtract with output saturated */
+#define SKP_ADD_SAT32(a, b) ((((a) + (b)) & 0x80000000) == 0 ? \
+ ((((a) & (b)) & 0x80000000) != 0 ? SKP_int32_MIN : (a)+(b)) : \
+ ((((a) | (b)) & 0x80000000) == 0 ? SKP_int32_MAX : (a)+(b)) )
+
+#define SKP_SUB_SAT32(a, b) ((((a)-(b)) & 0x80000000) == 0 ? \
+ (( (a) & ((b)^0x80000000) & 0x80000000) ? SKP_int32_MIN : (a)-(b)) : \
+ ((((a)^0x80000000) & (b) & 0x80000000) ? SKP_int32_MAX : (a)-(b)) )
+
+#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
+
+
+#else
+SKP_INLINE SKP_int32 SKP_SMULWB(SKP_int32 a32, SKP_int32 b32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smulwb %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+
+SKP_INLINE SKP_int32 SKP_SMLAWB(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smlawb %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMULWT(SKP_int32 a32, SKP_int32 b32)
+{
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smulwt %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMLAWT(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32)
+{
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smlawt %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMULBB(SKP_int32 a32, SKP_int32 b32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smulbb %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMLABB(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smlabb %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMLABB_ovflw(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smlabb %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMULBT(SKP_int32 a32, SKP_int32 b32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smulbt %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMLABT(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smlabt %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int64 SKP_SMLAL(SKP_int64 a64, SKP_int32 b32, SKP_int32 c32)
+{
+#ifdef IPHONE
+ // IPHONE LLVM compiler doesn't understand Q/R representation.
+ a64 = (SKP_int64)b32 * c32;
+ return(a64);
+#else
+ __asm__ __volatile__ ("smlal %Q0, %R0, %2, %3" : "=r" (a64) : "0" (a64), "r" (b32), "r" (c32));
+ return(a64);
+#endif
+}
+
+#define SKP_SMULWW(a32, b32) SKP_MLA(SKP_SMULWB((a32), (b32)), (a32), SKP_RSHIFT_ROUND((b32), 16))
+
+/*SKP_INLINE SKP_int32 SKP_SMULWW(SKP_int32 a32, SKP_int32 b32)
+{
+ SKP_int64 tmp;
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smull %Q1, %R1, %2, %3 \n\t mov %0, %R1, lsl #16 \n\t add %0, %0, %Q1, lsr #16" : "=&r" (out32), "=&r" (tmp) : "r" (a32), "r" (b32));
+ return(out32);
+}*/
+#define SKP_SMLAWW(a32, b32, c32) SKP_MLA(SKP_SMLAWB((a32), (b32), (c32)), (b32), SKP_RSHIFT_ROUND((c32), 16))
+/*SKP_INLINE SKP_int32 SKP_SMLAWW(a32, b32, c32){
+ SKP_int64 tmp;
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smull %Q1, %R1, %3, %4 \n\t add %0, %2, %R1, lsl #16 \n\t add %0, %0, %Q1, lsr #16" : "=&r" (out32), "=&r" (tmp) : "r" (a32), "r" (b32), "r" (c32));
+ return(out32);
+}*/
+
+SKP_INLINE SKP_int32 SKP_ADD_SAT32(SKP_int32 a32, SKP_int32 b32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("qadd %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SUB_SAT32(SKP_int32 a32, SKP_int32 b32) {
+ SKP_int32 out32;
+ __asm__ __volatile__ ("qsub %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_Silk_CLZ16(SKP_int16 in16)
+{
+ SKP_int32 out32;
+ __asm__ __volatile__ ("movs %0, %1, lsl #16 \n\tclz %0, %0 \n\t it eq \n\t moveq %0, #16" : "=r" (out32) : "r" (in16) : "cc");
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_Silk_CLZ32(SKP_int32 in32)
+{
+ SKP_int32 out32;
+ __asm__ __volatile__ ("clz %0, %1" : "=r" (out32) : "r" (in32));
+ return(out32);
+}
+#if EMBEDDED_ARM < 6
+#define SKP_SMMUL(a32, b32) (SKP_int32)SKP_RSHIFT64(SKP_SMULL((a32), (b32)), 32)
+#endif
+#endif
+
+// Some ARMv6 specific instructions:
+
+#if EMBEDDED_ARM>=6
+
+SKP_INLINE SKP_int32 SKP_SMMUL(SKP_int32 a32, SKP_int32 b32){
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smmul %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMUAD(SKP_int32 a32, SKP_int32 b32)
+{
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smuad %0, %1, %2" : "=r" (out32) : "r" (a32), "r" (b32));
+ return(out32);
+}
+
+SKP_INLINE SKP_int32 SKP_SMLAD(SKP_int32 a32, SKP_int32 b32, SKP_int32 c32)
+{
+ SKP_int32 out32;
+ __asm__ __volatile__ ("smlad %0, %2, %3, %1" : "=r" (out32) : "r" (a32), "r" (b32), "r" (c32));
+ return(out32);
+}
+
+#endif
+
+#endif // _SKP_SILK_API_ARM_H_
+
+
+
diff --git a/pkg/silk/csilk/SKP_Silk_main.h b/pkg/silk/csilk/SKP_Silk_main.h
new file mode 100644
index 0000000..bba7fa7
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_main.h
@@ -0,0 +1,388 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_MAIN_H
+#define SKP_SILK_MAIN_H
+
+#include "SKP_Silk_SigProc_FIX.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "SKP_Silk_define.h"
+#include "SKP_Silk_structs.h"
+#include "SKP_Silk_tables.h"
+#include "SKP_Silk_PLC.h"
+
+
+/* Encodes signs of excitation */
+void SKP_Silk_encode_signs(
+ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
+ const SKP_int8 q[], /* I pulse signal */
+ const SKP_int length, /* I length of input */
+ const SKP_int sigtype, /* I Signal type */
+ const SKP_int QuantOffsetType, /* I Quantization offset type */
+ const SKP_int RateLevelIndex /* I Rate Level Index */
+);
+
+/* Decodes signs of excitation */
+void SKP_Silk_decode_signs(
+ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
+ SKP_int q[], /* I/O pulse signal */
+ const SKP_int length, /* I length of output */
+ const SKP_int sigtype, /* I Signal type */
+ const SKP_int QuantOffsetType, /* I Quantization offset type */
+ const SKP_int RateLevelIndex /* I Rate Level Index */
+);
+
+/* Control internal sampling rate */
+SKP_int SKP_Silk_control_audio_bandwidth(
+ SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
+ const SKP_int32 TargetRate_bps /* I Target max bitrate (bps) */
+);
+
+/***************/
+/* Shell coder */
+/***************/
+
+/* Encode quantization indices of excitation */
+void SKP_Silk_encode_pulses(
+ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
+ const SKP_int sigtype, /* I Sigtype */
+ const SKP_int QuantOffsetType, /* I QuantOffsetType */
+ const SKP_int8 q[], /* I quantization indices */
+ const SKP_int frame_length /* I Frame length */
+);
+
+/* Shell encoder, operates on one shell code frame of 16 pulses */
+void SKP_Silk_shell_encoder(
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_int *pulses0 /* I data: nonnegative pulse amplitudes */
+);
+
+/* Shell decoder, operates on one shell code frame of 16 pulses */
+void SKP_Silk_shell_decoder(
+ SKP_int *pulses0, /* O data: nonnegative pulse amplitudes */
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_int pulses4 /* I number of pulses per pulse-subframe */
+);
+
+/***************/
+/* Range coder */
+/***************/
+/* Range encoder for one symbol */
+void SKP_Silk_range_encoder(
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_int data, /* I uncompressed data */
+ const SKP_uint16 prob[] /* I cumulative density functions */
+);
+
+/* Range encoder for multiple symbols */
+void SKP_Silk_range_encoder_multi(
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_int data[], /* I uncompressed data [nSymbols] */
+ const SKP_uint16 * const prob[], /* I cumulative density functions */
+ const SKP_int nSymbols /* I number of data symbols */
+);
+
+/* Range decoder for one symbol */
+void SKP_Silk_range_decoder(
+ SKP_int data[], /* O uncompressed data */
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_uint16 prob[], /* I cumulative density function */
+ SKP_int probIx /* I initial (middle) entry of cdf */
+);
+
+/* Range decoder for multiple symbols */
+void SKP_Silk_range_decoder_multi(
+ SKP_int data[], /* O uncompressed data [nSymbols] */
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_uint16 * const prob[], /* I cumulative density functions */
+ const SKP_int probStartIx[], /* I initial (middle) entries of cdfs [nSymbols] */
+ const SKP_int nSymbols /* I number of data symbols */
+);
+
+/* Initialize range coder structure for encoder */
+void SKP_Silk_range_enc_init(
+ SKP_Silk_range_coder_state *psRC /* O compressor data structure */
+);
+
+/* Initialize range coder structure for decoder */
+void SKP_Silk_range_dec_init(
+ SKP_Silk_range_coder_state *psRC, /* O compressor data structure */
+ const SKP_uint8 buffer[], /* I buffer for compressed data [bufferLength] */
+ const SKP_int32 bufferLength /* I buffer length (in bytes) */
+);
+
+/* Determine length of bitstream */
+SKP_int SKP_Silk_range_coder_get_length( /* O returns number of BITS in stream */
+ const SKP_Silk_range_coder_state *psRC, /* I compressed data structure */
+ SKP_int *nBytes /* O number of BYTES in stream */
+);
+
+/* Write decodable stream to buffer, and determine its length */
+void SKP_Silk_range_enc_wrap_up(
+ SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */
+);
+
+/* Check that any remaining bits in the last byte are set to 1 */
+void SKP_Silk_range_coder_check_after_decoding(
+ SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */
+);
+
+/* Gain scalar quantization with hysteresis, uniform on log scale */
+void SKP_Silk_gains_quant(
+ SKP_int ind[ NB_SUBFR ], /* O gain indices */
+ SKP_int32 gain_Q16[ NB_SUBFR ], /* I/O gains (quantized out) */
+ SKP_int *prev_ind, /* I/O last index in previous frame */
+ const SKP_int conditional /* I first gain is delta coded if 1 */
+);
+
+/* Gains scalar dequantization, uniform on log scale */
+void SKP_Silk_gains_dequant(
+ SKP_int32 gain_Q16[ NB_SUBFR ], /* O quantized gains */
+ const SKP_int ind[ NB_SUBFR ], /* I gain indices */
+ SKP_int *prev_ind, /* I/O last index in previous frame */
+ const SKP_int conditional /* I first gain is delta coded if 1 */
+);
+
+/* Convert NLSF parameters to stable AR prediction filter coefficients */
+void SKP_Silk_NLSF2A_stable(
+ SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */
+ const SKP_int pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */
+ const SKP_int LPC_order /* I LPC/LSF order */
+);
+
+/* Interpolate two vectors */
+void SKP_Silk_interpolate(
+ SKP_int xi[ MAX_LPC_ORDER ], /* O interpolated vector */
+ const SKP_int x0[ MAX_LPC_ORDER ], /* I first vector */
+ const SKP_int x1[ MAX_LPC_ORDER ], /* I second vector */
+ const SKP_int ifact_Q2, /* I interp. factor, weight on 2nd vector */
+ const SKP_int d /* I number of parameters */
+);
+
+/***********************************/
+/* Noise shaping quantization (NSQ)*/
+/***********************************/
+void SKP_Silk_NSQ(
+ SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
+ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ const SKP_int16 x[], /* I prefiltered input signal */
+ SKP_int8 q[], /* O quantized qulse signal */
+ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
+ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefficients */
+ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I Long term prediction coefficients */
+ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
+ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
+ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
+ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int Lambda_Q10, /* I */
+ const SKP_int LTP_scale_Q14 /* I LTP state scaling */
+);
+
+/* Noise shaping using delayed decision */
+void SKP_Silk_NSQ_del_dec(
+ SKP_Silk_encoder_state *psEncC, /* I/O Encoder State */
+ SKP_Silk_encoder_control *psEncCtrlC, /* I Encoder Control */
+ SKP_Silk_nsq_state *NSQ, /* I/O NSQ state */
+ const SKP_int16 x[], /* I Prefiltered input signal */
+ SKP_int8 q[], /* O Quantized pulse signal */
+ const SKP_int LSFInterpFactor_Q2, /* I LSF interpolation factor in Q2 */
+ const SKP_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Prediction coefs */
+ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ], /* I LT prediction coefs */
+ const SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I */
+ const SKP_int HarmShapeGain_Q14[ NB_SUBFR ], /* I */
+ const SKP_int Tilt_Q14[ NB_SUBFR ], /* I Spectral tilt */
+ const SKP_int32 LF_shp_Q14[ NB_SUBFR ], /* I */
+ const SKP_int32 Gains_Q16[ NB_SUBFR ], /* I */
+ const SKP_int Lambda_Q10, /* I */
+ const SKP_int LTP_scale_Q14 /* I LTP state scaling */
+);
+
+/************/
+/* Silk VAD */
+/************/
+/* Initialize the Silk VAD */
+SKP_int SKP_Silk_VAD_Init( /* O Return value, 0 if success */
+ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
+);
+
+/* Silk VAD noise level estimation */
+void SKP_Silk_VAD_GetNoiseLevels(
+ const SKP_int32 pX[ VAD_N_BANDS ], /* I subband energies */
+ SKP_Silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
+);
+
+/* Get speech activity level in Q8 */
+SKP_int SKP_Silk_VAD_GetSA_Q8( /* O Return value, 0 if success */
+ SKP_Silk_VAD_state *psSilk_VAD, /* I/O Silk VAD state */
+ SKP_int *pSA_Q8, /* O Speech activity level in Q8 */
+ SKP_int *pSNR_dB_Q7, /* O SNR for current frame in Q7 */
+ SKP_int pQuality_Q15[ VAD_N_BANDS ], /* O Smoothed SNR for each band */
+ SKP_int *pTilt_Q15, /* O current frame's frequency tilt */
+ const SKP_int16 pIn[], /* I PCM input [framelength] */
+ const SKP_int framelength /* I Input frame length */
+);
+
+/* Detect signal in 8 - 12 khz range */
+void SKP_Silk_detect_SWB_input(
+ SKP_Silk_detect_SWB_state *psSWBdetect, /* I/O Encoder state */
+ const SKP_int16 samplesIn[], /* I Input to encoder */
+ SKP_int nSamplesIn /* I Length of input */
+);
+
+#if SWITCH_TRANSITION_FILTERING
+/* Low-pass filter with variable cutoff frequency based on */
+/* piece-wise linear interpolation between elliptic filters */
+/* Start by setting transition_frame_no = 1; */
+void SKP_Silk_LP_variable_cutoff(
+ SKP_Silk_LP_state *psLP, /* I/O LP filter state */
+ SKP_int16 *out, /* O Low-pass filtered output signal */
+ const SKP_int16 *in, /* I Input signal */
+ const SKP_int frame_length /* I Frame length */
+);
+#endif
+
+/****************************************************/
+/* Decoder Functions */
+/****************************************************/
+SKP_int SKP_Silk_create_decoder(
+ SKP_Silk_decoder_state **ppsDec /* I/O Decoder state pointer pointer */
+);
+
+SKP_int SKP_Silk_free_decoder(
+ SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */
+);
+
+SKP_int SKP_Silk_init_decoder(
+ SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */
+);
+
+/* Set decoder sampling rate */
+void SKP_Silk_decoder_set_fs(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state pointer */
+ SKP_int fs_kHz /* I Sampling frequency (kHz) */
+);
+
+/****************/
+/* Decode frame */
+/****************/
+SKP_int SKP_Silk_decode_frame(
+ SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */
+ SKP_int16 pOut[], /* O Pointer to output speech frame */
+ SKP_int16 *pN, /* O Pointer to size of output frame */
+ const SKP_uint8 pCode[], /* I Pointer to payload */
+ const SKP_int nBytes, /* I Payload length */
+ SKP_int action, /* I Action from Jitter Buffer */
+ SKP_int *decBytes /* O Used bytes to decode this frame */
+);
+
+/* Decode parameters from payload */
+void SKP_Silk_decode_parameters(
+ SKP_Silk_decoder_state *psDec, /* I/O State */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int q[], /* O Excitation signal */
+ const SKP_int fullDecoding /* I Flag to tell if only arithmetic decoding */
+);
+
+/* Core decoder. Performs inverse NSQ operation LTP + LPC */
+void SKP_Silk_decode_core(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I Decoder control */
+ SKP_int16 xq[], /* O Decoded speech */
+ const SKP_int q[ MAX_FRAME_LENGTH ] /* I Pulse signal */
+);
+
+/* NLSF vector decoder */
+void SKP_Silk_NLSF_MSVQ_decode(
+ SKP_int *pNLSF_Q15, /* O Pointer to decoded output [LPC_ORDER x 1] */
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Pointer to NLSF codebook struct */
+ const SKP_int *NLSFIndices, /* I Pointer to NLSF indices [nStages x 1] */
+ const SKP_int LPC_order /* I LPC order */
+);
+
+/**********************/
+/* Arithmetic coding */
+/*********************/
+
+/* Decode quantization indices of excitation (Shell coding) */
+void SKP_Silk_decode_pulses(
+ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int q[], /* O Excitation signal */
+ const SKP_int frame_length /* I Frame length (preliminary) */
+);
+
+/******************/
+/* CNG */
+/******************/
+
+/* Reset CNG */
+void SKP_Silk_CNG_Reset(
+ SKP_Silk_decoder_state *psDec /* I/O Decoder state */
+);
+
+/* Updates CNG estimate, and applies the CNG when packet was lost */
+void SKP_Silk_CNG(
+ SKP_Silk_decoder_state *psDec, /* I/O Decoder state */
+ SKP_Silk_decoder_control *psDecCtrl, /* I/O Decoder control */
+ SKP_int16 signal[], /* I/O Signal */
+ SKP_int length /* I Length of residual */
+);
+
+/* Encoding of various parameters */
+void SKP_Silk_encode_parameters(
+ SKP_Silk_encoder_state *psEncC, /* I/O Encoder state */
+ SKP_Silk_encoder_control *psEncCtrlC, /* I/O Encoder control */
+ SKP_Silk_range_coder_state *psRC, /* I/O Range coder state */
+ const SKP_int8 *q /* I Quantization indices */
+);
+
+/* Extract lowest layer encoding */
+void SKP_Silk_get_low_layer_internal(
+ const SKP_uint8 *indata, /* I: Encoded input vector */
+ const SKP_int16 nBytesIn, /* I: Number of input Bytes */
+ SKP_uint8 *Layer0data, /* O: Layer0 payload */
+ SKP_int16 *nLayer0Bytes /* O: Number of FEC Bytes */
+);
+
+/* Resets LBRR buffer, used if packet size changes */
+void SKP_Silk_LBRR_reset(
+ SKP_Silk_encoder_state *psEncC /* I/O Pointer to Silk encoder state */
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_main_FIX.h b/pkg/silk/csilk/SKP_Silk_main_FIX.h
new file mode 100644
index 0000000..4d760a4
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_main_FIX.h
@@ -0,0 +1,338 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_MAIN_FIX_H
+#define SKP_SILK_MAIN_FIX_H
+
+#include
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_structs_FIX.h"
+#include "SKP_Silk_main.h"
+#include "SKP_Silk_PLC.h"
+#define TIC(TAG_NAME)
+#define TOC(TAG_NAME)
+
+#ifndef FORCE_CPP_BUILD
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#endif
+
+/*********************/
+/* Encoder Functions */
+/*********************/
+
+/* Initializes the Silk encoder state */
+SKP_int SKP_Silk_init_encoder_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */
+);
+
+/* Control the Silk encoder */
+SKP_int SKP_Silk_control_encoder_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk encoder state */
+ const SKP_int PacketSize_ms, /* I Packet length (ms) */
+ const SKP_int32 TargetRate_bps, /* I Target max bitrate (bps) */
+ const SKP_int PacketLoss_perc, /* I Packet loss rate (in percent) */
+ const SKP_int DTX_enabled, /* I Enable / disable DTX */
+ const SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */
+);
+
+/* Encoder main function */
+SKP_int SKP_Silk_encode_frame_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
+ SKP_uint8 *pCode, /* O Pointer to payload */
+ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes; */
+ /* input: max length; output: used */
+ const SKP_int16 *pIn /* I Pointer to input speech frame */
+);
+
+/* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode with lower bitrate */
+void SKP_Silk_LBRR_encode_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
+ SKP_uint8 *pCode, /* O Pointer to payload */
+ SKP_int16 *pnBytesOut, /* I/O Pointer to number of payload bytes */
+ SKP_int16 xfw[] /* I Input signal */
+);
+
+/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
+void SKP_Silk_HP_variable_cutoff_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
+ SKP_int16 *out, /* O high-pass filtered output signal */
+ const SKP_int16 *in /* I input signal */
+);
+
+/****************/
+/* Prefiltering */
+/****************/
+void SKP_Silk_prefilter_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
+ const SKP_Silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
+ SKP_int16 xw[], /* O Weighted signal */
+ const SKP_int16 x[] /* I Speech signal */
+);
+
+/**************************************************************/
+/* Compute noise shaping coefficients and initial gain values */
+/**************************************************************/
+void SKP_Silk_noise_shape_analysis_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
+ const SKP_int16 *pitch_res, /* I LPC residual from pitch analysis */
+ const SKP_int16 *x /* I Input signal [ frame_length + la_shape ] */
+);
+
+/* Autocorrelations for a warped frequency axis */
+void SKP_Silk_warped_autocorrelation_FIX(
+ SKP_int32 *corr, /* O Result [order + 1] */
+ SKP_int *scale, /* O Scaling of the correlation vector */
+ const SKP_int16 *input, /* I Input data to correlate */
+ const SKP_int16 warping_Q16, /* I Warping coefficient */
+ const SKP_int length, /* I Length of input */
+ const SKP_int order /* I Correlation order (even) */
+);
+
+/* Processing of gains */
+void SKP_Silk_process_gains_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control */
+);
+
+/* Control low bitrate redundancy usage */
+void SKP_Silk_LBRR_ctrl_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
+ SKP_Silk_encoder_control *psEncCtrlC /* I/O encoder control */
+);
+
+/* Calculation of LTP state scaling */
+void SKP_Silk_LTP_scale_ctrl_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O encoder control */
+);
+
+/**********************************************/
+/* Prediction Analysis */
+/**********************************************/
+
+/* Find pitch lags */
+void SKP_Silk_find_pitch_lags_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
+ SKP_int16 res[], /* O residual */
+ const SKP_int16 x[] /* I Speech signal */
+);
+
+void SKP_Silk_find_pred_coefs_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
+ const SKP_int16 res_pitch[] /* I Residual from pitch analysis */
+);
+
+void SKP_Silk_find_LPC_FIX(
+ SKP_int NLSF_Q15[], /* O NLSFs */
+ SKP_int *interpIndex, /* O NLSF interpolation index, only used for NLSF interpolation */
+ const SKP_int prev_NLSFq_Q15[], /* I previous NLSFs, only used for NLSF interpolation */
+ const SKP_int useInterpolatedLSFs, /* I Flag */
+ const SKP_int LPC_order, /* I LPC order */
+ const SKP_int16 x[], /* I Input signal */
+ const SKP_int subfr_length /* I Input signal subframe length including preceeding samples */
+);
+
+void SKP_Silk_warped_LPC_analysis_filter_FIX(
+ SKP_int32 state[], /* I/O State [order + 1] */
+ SKP_int16 res[], /* O Residual signal [length] */
+ const SKP_int16 coef_Q13[], /* I Coefficients [order] */
+ const SKP_int16 input[], /* I Input signal [length] */
+ const SKP_int16 lambda_Q16, /* I Warping factor */
+ const SKP_int length, /* I Length of input signal */
+ const SKP_int order /* I Filter order (even) */
+);
+
+void SKP_Silk_LTP_analysis_filter_FIX(
+ SKP_int16 *LTP_res, /* O: LTP residual signal of length NB_SUBFR * ( pre_length + subfr_length ) */
+ const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */
+ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each NB_SUBFR subframe */
+ const SKP_int pitchL[ NB_SUBFR ], /* I: Pitch lag, one for each subframe */
+ const SKP_int32 invGains_Q16[ NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */
+ const SKP_int subfr_length, /* I: Length of each subframe */
+ const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */
+);
+
+/* Finds LTP vector from correlations */
+void SKP_Silk_find_LTP_FIX(
+ SKP_int16 b_Q14[ NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
+ SKP_int32 WLTP[ NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
+ SKP_int *LTPredCodGain_Q7, /* O LTP coding gain */
+ const SKP_int16 r_first[], /* I residual signal after LPC signal + state for first 10 ms */
+ const SKP_int16 r_last[], /* I residual signal after LPC signal + state for last 10 ms */
+ const SKP_int lag[ NB_SUBFR ], /* I LTP lags */
+ const SKP_int32 Wght_Q15[ NB_SUBFR ], /* I weights */
+ const SKP_int subfr_length, /* I subframe length */
+ const SKP_int mem_offset, /* I number of samples in LTP memory */
+ SKP_int corr_rshifts[ NB_SUBFR ] /* O right shifts applied to correlations */
+);
+
+/* LTP tap quantizer */
+void SKP_Silk_quant_LTP_gains_FIX(
+ SKP_int16 B_Q14[], /* I/O (un)quantized LTP gains */
+ SKP_int cbk_index[], /* O Codebook Index */
+ SKP_int *periodicity_index, /* O Periodicity Index */
+ const SKP_int32 W_Q18[], /* I Error Weights in Q18 */
+ SKP_int mu_Q8, /* I Mu value (R/D tradeoff) */
+ SKP_int lowComplexity /* I Flag for low complexity */
+);
+
+/******************/
+/* NLSF Quantizer */
+/******************/
+
+/* Limit, stabilize, convert and quantize NLSFs. */
+void SKP_Silk_process_NLSFs_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O encoder state */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
+ SKP_int *pNLSF_Q15 /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
+);
+
+/* NLSF vector encoder */
+void SKP_Silk_NLSF_MSVQ_encode_FIX(
+ SKP_int *NLSFIndices, /* O Codebook path vector [ CB_STAGES ] */
+ SKP_int *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
+ const SKP_int *pNLSF_q_Q15_prev, /* I Prev. quantized NLSF vector [LPC_ORDER] */
+ const SKP_int *pW_Q6, /* I NLSF weight vector [ LPC_ORDER ] */
+ const SKP_int NLSF_mu_Q15, /* I Rate weight for the RD optimization */
+ const SKP_int NLSF_mu_fluc_red_Q16, /* I Fluctuation reduction error weight */
+ const SKP_int NLSF_MSVQ_Survivors, /* I Max survivors from each stage */
+ const SKP_int LPC_order, /* I LPC order */
+ const SKP_int deactivate_fluc_red /* I Deactivate fluctuation reduction */
+);
+
+/* Rate-Distortion calculations for multiple input data vectors */
+void SKP_Silk_NLSF_VQ_rate_distortion_FIX(
+ SKP_int32 *pRD_Q20, /* O Rate-distortion values [psNLSF_CBS->nVectors*N] */
+ const SKP_Silk_NLSF_CBS *psNLSF_CBS, /* I NLSF codebook stage struct */
+ const SKP_int *in_Q15, /* I Input vectors to be quantized */
+ const SKP_int *w_Q6, /* I Weight vector */
+ const SKP_int32 *rate_acc_Q5, /* I Accumulated rates from previous stage */
+ const SKP_int mu_Q15, /* I Weight between weighted error and rate */
+ const SKP_int N, /* I Number of input vectors to be quantized */
+ const SKP_int LPC_order /* I LPC order */
+);
+
+/* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */
+void SKP_Silk_NLSF_VQ_sum_error_FIX(
+ SKP_int32 *err_Q20, /* O Weighted quantization errors [N*K] */
+ const SKP_int *in_Q15, /* I Input vectors to be quantized [N*LPC_order] */
+ const SKP_int *w_Q6, /* I Weighting vectors [N*LPC_order] */
+ const SKP_int16 *pCB_Q15, /* I Codebook vectors [K*LPC_order] */
+ const SKP_int N, /* I Number of input vectors */
+ const SKP_int K, /* I Number of codebook vectors */
+ const SKP_int LPC_order /* I Number of LPCs */
+);
+
+/* Entropy constrained MATRIX-weighted VQ, for a single input data vector */
+void SKP_Silk_VQ_WMat_EC_FIX(
+ SKP_int *ind, /* O index of best codebook vector */
+ SKP_int32 *rate_dist_Q14, /* O best weighted quantization error + mu * rate*/
+ const SKP_int16 *in_Q14, /* I input vector to be quantized */
+ const SKP_int32 *W_Q18, /* I weighting matrix */
+ const SKP_int16 *cb_Q14, /* I codebook */
+ const SKP_int16 *cl_Q6, /* I code length for each codebook vector */
+ const SKP_int mu_Q8, /* I tradeoff between weighted error and rate */
+ SKP_int L /* I number of vectors in codebook */
+);
+
+/******************/
+/* Linear Algebra */
+/******************/
+
+/* Calculates correlation matrix X'*X */
+void SKP_Silk_corrMatrix_FIX(
+ const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
+ const SKP_int L, /* I Length of vectors */
+ const SKP_int order, /* I Max lag for correlation */
+ const SKP_int head_room, /* I Desired headroom */
+ SKP_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ]*/
+ SKP_int *rshifts /* I/O Right shifts of correlations */
+);
+
+/* Calculates correlation vector X'*t */
+void SKP_Silk_corrVector_FIX(
+ const SKP_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
+ const SKP_int16 *t, /* I Target vector [L] */
+ const SKP_int L, /* I Length of vectors */
+ const SKP_int order, /* I Max lag for correlation */
+ SKP_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
+ const SKP_int rshifts /* I Right shifts of correlations */
+);
+
+/* Add noise to matrix diagonal */
+void SKP_Silk_regularize_correlations_FIX(
+ SKP_int32 *XX, /* I/O Correlation matrices */
+ SKP_int32 *xx, /* I/O Correlation values */
+ SKP_int32 noise, /* I Noise to add */
+ SKP_int D /* I Dimension of XX */
+);
+
+/* Solves Ax = b, assuming A is symmetric */
+void SKP_Silk_solve_LDL_FIX(
+ SKP_int32 *A, /* I Pointer to symetric square matrix A */
+ SKP_int M, /* I Size of matrix */
+ const SKP_int32 *b, /* I Pointer to b vector */
+ SKP_int32 *x_Q16 /* O Pointer to x solution vector */
+);
+
+/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
+SKP_int32 SKP_Silk_residual_energy16_covar_FIX(
+ const SKP_int16 *c, /* I Prediction vector */
+ const SKP_int32 *wXX, /* I Correlation matrix */
+ const SKP_int32 *wXx, /* I Correlation vector */
+ SKP_int32 wxx, /* I Signal energy */
+ SKP_int D, /* I Dimension */
+ SKP_int cQ /* I Q value for c vector 0 - 15 */
+);
+
+/* Calculates residual energies of input subframes where all subframes have LPC_order */
+/* of preceeding samples */
+void SKP_Silk_residual_energy_FIX(
+ SKP_int32 nrgs[ NB_SUBFR ], /* O Residual energy per subframe */
+ SKP_int nrgsQ[ NB_SUBFR ], /* O Q value per subframe */
+ const SKP_int16 x[], /* I Input signal */
+ SKP_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ],/* I AR coefs for each frame half */
+ const SKP_int32 gains[ NB_SUBFR ], /* I Quantization gains */
+ const SKP_int subfr_length, /* I Subframe length */
+ const SKP_int LPC_order /* I LPC order */
+);
+
+#ifndef FORCE_CPP_BUILD
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* FORCE_CPP_BUILD */
+#endif /* SKP_SILK_MAIN_FIX_H */
diff --git a/pkg/silk/csilk/SKP_Silk_noise_shape_analysis_FIX.c b/pkg/silk/csilk/SKP_Silk_noise_shape_analysis_FIX.c
new file mode 100644
index 0000000..459cc69
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_noise_shape_analysis_FIX.c
@@ -0,0 +1,477 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
+/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
+SKP_INLINE SKP_int32 warped_gain( // gain in Q16
+ const SKP_int32 *coefs_Q24,
+ SKP_int lambda_Q16,
+ SKP_int order
+) {
+ SKP_int i;
+ SKP_int32 gain_Q24;
+
+ lambda_Q16 = -lambda_Q16;
+ gain_Q24 = coefs_Q24[ order - 1 ];
+ for( i = order - 2; i >= 0; i-- ) {
+ gain_Q24 = SKP_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
+ }
+ gain_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
+ return SKP_INVERSE32_varQ( gain_Q24, 40 );
+}
+
+/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
+/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
+SKP_INLINE void limit_warped_coefs(
+ SKP_int32 *coefs_syn_Q24,
+ SKP_int32 *coefs_ana_Q24,
+ SKP_int lambda_Q16,
+ SKP_int32 limit_Q24,
+ SKP_int order
+) {
+ SKP_int i, iter, ind = 0;
+ SKP_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16;
+ SKP_int32 nom_Q16, den_Q24;
+
+ /* Convert to monic coefficients */
+ lambda_Q16 = -lambda_Q16;
+ for( i = order - 1; i > 0; i-- ) {
+ coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+ coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+ }
+ lambda_Q16 = -lambda_Q16;
+ nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 );
+ den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
+ gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
+ gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ for( i = 0; i < order; i++ ) {
+ coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+ coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+ }
+
+ for( iter = 0; iter < 10; iter++ ) {
+ /* Find maximum absolute value */
+ maxabs_Q24 = -1;
+ for( i = 0; i < order; i++ ) {
+ tmp = SKP_max( SKP_abs_int32( coefs_syn_Q24[ i ] ), SKP_abs_int32( coefs_ana_Q24[ i ] ) );
+ if( tmp > maxabs_Q24 ) {
+ maxabs_Q24 = tmp;
+ ind = i;
+ }
+ }
+ if( maxabs_Q24 <= limit_Q24 ) {
+ /* Coefficients are within range - done */
+ return;
+ }
+
+ /* Convert back to true warped coefficients */
+ for( i = 1; i < order; i++ ) {
+ coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+ coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+ }
+ gain_syn_Q16 = SKP_INVERSE32_varQ( gain_syn_Q16, 32 );
+ gain_ana_Q16 = SKP_INVERSE32_varQ( gain_ana_Q16, 32 );
+ for( i = 0; i < order; i++ ) {
+ coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+ coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+ }
+
+ /* Apply bandwidth expansion */
+ chirp_Q16 = SKP_FIX_CONST( 0.99, 16 ) - SKP_DIV32_varQ(
+ SKP_SMULWB( maxabs_Q24 - limit_Q24, SKP_SMLABB( SKP_FIX_CONST( 0.8, 10 ), SKP_FIX_CONST( 0.1, 10 ), iter ) ),
+ SKP_MUL( maxabs_Q24, ind + 1 ), 22 );
+ SKP_Silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 );
+ SKP_Silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 );
+
+ /* Convert to monic warped coefficients */
+ lambda_Q16 = -lambda_Q16;
+ for( i = order - 1; i > 0; i-- ) {
+ coefs_syn_Q24[ i - 1 ] = SKP_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+ coefs_ana_Q24[ i - 1 ] = SKP_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+ }
+ lambda_Q16 = -lambda_Q16;
+ nom_Q16 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 16 ), -lambda_Q16, lambda_Q16 );
+ den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
+ gain_syn_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ den_Q24 = SKP_SMLAWB( SKP_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
+ gain_ana_Q16 = SKP_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ for( i = 0; i < order; i++ ) {
+ coefs_syn_Q24[ i ] = SKP_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+ coefs_ana_Q24[ i ] = SKP_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+ }
+ }
+ SKP_assert( 0 );
+}
+
+/**************************************************************/
+/* Compute noise shaping coefficients and initial gain values */
+/**************************************************************/
+void SKP_Silk_noise_shape_analysis_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
+ const SKP_int16 *pitch_res, /* I LPC residual from pitch analysis */
+ const SKP_int16 *x /* I Input signal [ frame_length + la_shape ] */
+)
+{
+ SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
+ SKP_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
+ SKP_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
+ SKP_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
+ SKP_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
+ SKP_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
+ SKP_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
+ SKP_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ];
+ SKP_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ];
+ SKP_int16 x_windowed[ SHAPE_LPC_WIN_MAX ];
+ const SKP_int16 *x_ptr, *pitch_res_ptr;
+
+ /* Point to start of first LPC analysis block */
+ x_ptr = x - psEnc->sCmn.la_shape;
+
+ /****************/
+ /* CONTROL SNR */
+ /****************/
+ /* Reduce SNR_dB values if recent bitstream has exceeded TargetRate */
+ psEncCtrl->current_SNR_dB_Q7 = psEnc->SNR_dB_Q7 - SKP_SMULWB( SKP_LSHIFT( ( SKP_int32 )psEnc->BufferedInChannel_ms, 7 ),
+ SKP_FIX_CONST( 0.05, 16 ) );
+
+ /* Reduce SNR_dB if inband FEC used */
+ if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
+ psEncCtrl->current_SNR_dB_Q7 -= SKP_RSHIFT( psEnc->inBandFEC_SNR_comp_Q8, 1 );
+ }
+
+ /****************/
+ /* GAIN CONTROL */
+ /****************/
+ /* Input quality is the average of the quality in the lowest two VAD bands */
+ psEncCtrl->input_quality_Q14 = ( SKP_int )SKP_RSHIFT( ( SKP_int32 )psEncCtrl->input_quality_bands_Q15[ 0 ]
+ + psEncCtrl->input_quality_bands_Q15[ 1 ], 2 );
+
+ /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
+ psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->current_SNR_dB_Q7 -
+ SKP_FIX_CONST( 18.0, 7 ), 4 ) ), 1 );
+
+ /* Reduce coding SNR during low speech activity */
+ b_Q8 = SKP_FIX_CONST( 1.0, 8 ) - psEnc->speech_activity_Q8;
+ b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 );
+ SNR_adj_dB_Q7 = SKP_SMLAWB( psEncCtrl->current_SNR_dB_Q7,
+ SKP_SMULBB( SKP_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), // Q11
+ SKP_SMULWB( SKP_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); // Q12
+
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ /* Reduce gains for periodic signals */
+ SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
+ } else {
+ /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
+ SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7,
+ SKP_SMLAWB( SKP_FIX_CONST( 6.0, 9 ), -SKP_FIX_CONST( 0.4, 18 ), psEncCtrl->current_SNR_dB_Q7 ),
+ SKP_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
+ }
+
+ /*************************/
+ /* SPARSENESS PROCESSING */
+ /*************************/
+ /* Set quantizer offset */
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ /* Initally set to 0; may be overruled in process_gains(..) */
+ psEncCtrl->sCmn.QuantOffsetType = 0;
+ psEncCtrl->sparseness_Q8 = 0;
+ } else {
+ /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
+ nSamples = SKP_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
+ energy_variation_Q7 = 0;
+ log_energy_prev_Q7 = 0;
+ pitch_res_ptr = pitch_res;
+ for( k = 0; k < FRAME_LENGTH_MS / 2; k++ ) {
+ SKP_Silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
+ nrg += SKP_RSHIFT( nSamples, scale ); // Q(-scale)
+
+ log_energy_Q7 = SKP_Silk_lin2log( nrg );
+ if( k > 0 ) {
+ energy_variation_Q7 += SKP_abs( log_energy_Q7 - log_energy_prev_Q7 );
+ }
+ log_energy_prev_Q7 = log_energy_Q7;
+ pitch_res_ptr += nSamples;
+ }
+
+ psEncCtrl->sparseness_Q8 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_SMULWB( energy_variation_Q7 -
+ SKP_FIX_CONST( 5.0, 7 ), SKP_FIX_CONST( 0.1, 16 ) ) ), 7 );
+
+ /* Set quantization offset depending on sparseness measure */
+ if( psEncCtrl->sparseness_Q8 > SKP_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
+ psEncCtrl->sCmn.QuantOffsetType = 0;
+ } else {
+ psEncCtrl->sCmn.QuantOffsetType = 1;
+ }
+
+ /* Increase coding SNR for sparse signals */
+ SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SKP_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SKP_FIX_CONST( 0.5, 8 ) );
+ }
+
+ /*******************************/
+ /* Control bandwidth expansion */
+ /*******************************/
+ /* More BWE for signals with high prediction gain */
+ strength_Q16 = SKP_SMULWB( psEncCtrl->predGain_Q16, SKP_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
+ BWExp1_Q16 = BWExp2_Q16 = SKP_DIV32_varQ( SKP_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
+ SKP_SMLAWW( SKP_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
+ delta_Q16 = SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
+ SKP_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
+ BWExp1_Q16 = SKP_SUB32( BWExp1_Q16, delta_Q16 );
+ BWExp2_Q16 = SKP_ADD32( BWExp2_Q16, delta_Q16 );
+ /* BWExp1 will be applied after BWExp2, so make it relative */
+ BWExp1_Q16 = SKP_DIV32_16( SKP_LSHIFT( BWExp1_Q16, 14 ), SKP_RSHIFT( BWExp2_Q16, 2 ) );
+
+ if( psEnc->sCmn.warping_Q16 > 0 ) {
+ /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
+ warping_Q16 = SKP_SMLAWB( psEnc->sCmn.warping_Q16, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( 0.01, 18 ) );
+ } else {
+ warping_Q16 = 0;
+ }
+
+ /********************************************/
+ /* Compute noise shaping AR coefs and gains */
+ /********************************************/
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ /* Apply window: sine slope followed by flat part followed by cosine slope */
+ SKP_int shift, slope_part, flat_part;
+ flat_part = psEnc->sCmn.fs_kHz * 5;
+ slope_part = SKP_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
+
+ SKP_Silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
+ shift = slope_part;
+ SKP_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(SKP_int16) );
+ shift += flat_part;
+ SKP_Silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
+
+ /* Update pointer: next LPC analysis block */
+ x_ptr += psEnc->sCmn.subfr_length;
+
+ if( psEnc->sCmn.warping_Q16 > 0 ) {
+ /* Calculate warped auto correlation */
+ SKP_Silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
+ } else {
+ /* Calculate regular auto correlation */
+ SKP_Silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );
+ }
+
+ /* Add white noise, as a fraction of energy */
+ auto_corr[0] = SKP_ADD32( auto_corr[0], SKP_max_32( SKP_SMULWB( SKP_RSHIFT( auto_corr[ 0 ], 4 ),
+ SKP_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
+
+ /* Calculate the reflection coefficients using schur */
+ nrg = SKP_Silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
+ SKP_assert( nrg >= 0 );
+
+ /* Convert reflection coefficients to prediction coefficients */
+ SKP_Silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
+
+ Qnrg = -scale; // range: -12...30
+ SKP_assert( Qnrg >= -12 );
+ SKP_assert( Qnrg <= 30 );
+
+ /* Make sure that Qnrg is an even number */
+ if( Qnrg & 1 ) {
+ Qnrg -= 1;
+ nrg >>= 1;
+ }
+
+ tmp32 = SKP_Silk_SQRT_APPROX( nrg );
+ Qnrg >>= 1; // range: -6...15
+
+ psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( tmp32, 16 - Qnrg );
+
+ if( psEnc->sCmn.warping_Q16 > 0 ) {
+ /* Adjust gain for warping */
+ gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
+ SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
+ psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
+ if( psEncCtrl->Gains_Q16[ k ] < 0 ) {
+ psEncCtrl->Gains_Q16[ k ] = SKP_int32_MAX;
+ }
+ }
+
+ /* Bandwidth expansion for synthesis filter shaping */
+ SKP_Silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
+
+ /* Compute noise shaping filter coefficients */
+ SKP_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( SKP_int32 ) );
+
+ /* Bandwidth expansion for analysis filter shaping */
+ SKP_assert( BWExp1_Q16 <= SKP_FIX_CONST( 1.0, 16 ) );
+ SKP_Silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
+
+ /* Ratio of prediction gains, in energy domain */
+ SKP_Silk_LPC_inverse_pred_gain_Q24( &pre_nrg_Q30, AR2_Q24, psEnc->sCmn.shapingLPCOrder );
+ SKP_Silk_LPC_inverse_pred_gain_Q24( &nrg, AR1_Q24, psEnc->sCmn.shapingLPCOrder );
+
+ //psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;
+ pre_nrg_Q30 = SKP_LSHIFT32( SKP_SMULWB( pre_nrg_Q30, SKP_FIX_CONST( 0.7, 15 ) ), 1 );
+ psEncCtrl->GainsPre_Q14[ k ] = ( SKP_int ) SKP_FIX_CONST( 0.3, 14 ) + SKP_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
+
+ /* Convert to monic warped prediction coefficients and limit absolute values */
+ limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SKP_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
+
+ /* Convert from Q24 to Q13 and store in int16 */
+ for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
+ psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
+ psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
+ }
+ }
+
+ /*****************/
+ /* Gain tweaking */
+ /*****************/
+ /* Increase gains during low speech activity and put lower limit on gains */
+ gain_mult_Q16 = SKP_Silk_log2lin( -SKP_SMLAWB( -SKP_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SKP_FIX_CONST( 0.16, 16 ) ) );
+ gain_add_Q16 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( NOISE_FLOOR_dB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) );
+ tmp32 = SKP_Silk_log2lin( SKP_SMLAWB( SKP_FIX_CONST( 16.0, 7 ), SKP_FIX_CONST( RELATIVE_MIN_GAIN_dB, 7 ), SKP_FIX_CONST( 0.16, 16 ) ) );
+ tmp32 = SKP_SMULWW( psEnc->avgGain_Q16, tmp32 );
+ gain_add_Q16 = SKP_ADD_SAT32( gain_add_Q16, tmp32 );
+ SKP_assert( gain_mult_Q16 >= 0 );
+
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
+ if( psEncCtrl->Gains_Q16[ k ] < 0 ) {
+ psEncCtrl->Gains_Q16[ k ] = SKP_int32_MAX;
+ }
+ }
+
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
+ psEnc->avgGain_Q16 = SKP_ADD_SAT32(
+ psEnc->avgGain_Q16,
+ SKP_SMULWB(
+ psEncCtrl->Gains_Q16[ k ] - psEnc->avgGain_Q16,
+ SKP_RSHIFT_ROUND( SKP_SMULBB( psEnc->speech_activity_Q8, SKP_FIX_CONST( GAIN_SMOOTHING_COEF, 10 ) ), 2 )
+ ) );
+ }
+
+ /************************************************/
+ /* Decrease level during fricatives (de-essing) */
+ /************************************************/
+ gain_mult_Q16 = SKP_FIX_CONST( 1.0, 16 ) + SKP_RSHIFT_ROUND( SKP_MLA( SKP_FIX_CONST( INPUT_TILT, 26 ),
+ psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
+
+ if( psEncCtrl->input_tilt_Q15 <= 0 && psEncCtrl->sCmn.sigtype == SIG_TYPE_UNVOICED ) {
+ if( psEnc->sCmn.fs_kHz == 24 ) {
+ SKP_int32 essStrength_Q15 = SKP_SMULWW( -psEncCtrl->input_tilt_Q15,
+ SKP_SMULBB( psEnc->speech_activity_Q8, SKP_FIX_CONST( 1.0, 8 ) - psEncCtrl->sparseness_Q8 ) );
+ tmp32 = SKP_Silk_log2lin( SKP_FIX_CONST( 16.0, 7 ) - SKP_SMULWB( essStrength_Q15,
+ SKP_SMULWB( SKP_FIX_CONST( DE_ESSER_COEF_SWB_dB, 7 ), SKP_FIX_CONST( 0.16, 17 ) ) ) );
+ gain_mult_Q16 = SKP_SMULWW( gain_mult_Q16, tmp32 );
+ } else if( psEnc->sCmn.fs_kHz == 16 ) {
+ SKP_int32 essStrength_Q15 = SKP_SMULWW(-psEncCtrl->input_tilt_Q15,
+ SKP_SMULBB( psEnc->speech_activity_Q8, SKP_FIX_CONST( 1.0, 8 ) - psEncCtrl->sparseness_Q8 ));
+ tmp32 = SKP_Silk_log2lin( SKP_FIX_CONST( 16.0, 7 ) - SKP_SMULWB( essStrength_Q15,
+ SKP_SMULWB( SKP_FIX_CONST( DE_ESSER_COEF_WB_dB, 7 ), SKP_FIX_CONST( 0.16, 17 ) ) ) );
+ gain_mult_Q16 = SKP_SMULWW( gain_mult_Q16, tmp32 );
+ } else {
+ SKP_assert( psEnc->sCmn.fs_kHz == 12 || psEnc->sCmn.fs_kHz == 8 );
+ }
+ }
+
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ psEncCtrl->GainsPre_Q14[ k ] = SKP_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
+ }
+
+ /************************************************/
+ /* Control low-frequency shaping and noise tilt */
+ /************************************************/
+ /* Less low frequency shaping for noisy inputs */
+ strength_Q16 = SKP_MUL( SKP_FIX_CONST( LOW_FREQ_SHAPING, 0 ), SKP_FIX_CONST( 1.0, 16 ) +
+ SKP_SMULBB( SKP_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 1 ), psEncCtrl->input_quality_bands_Q15[ 0 ] - SKP_FIX_CONST( 1.0, 15 ) ) );
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
+ /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
+ SKP_int fs_kHz_inv = SKP_DIV32_16( SKP_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ b_Q14 = fs_kHz_inv + SKP_DIV32_16( SKP_FIX_CONST( 3.0, 14 ), psEncCtrl->sCmn.pitchL[ k ] );
+ /* Pack two coefficients in one int32 */
+ psEncCtrl->LF_shp_Q14[ k ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, b_Q14 ), 16 );
+ psEncCtrl->LF_shp_Q14[ k ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) );
+ }
+ SKP_assert( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SKP_FIX_CONST( 0.5, 24 ) ); // Guarantees that second argument to SMULWB() is within range of an SKP_int16
+ Tilt_Q16 = - SKP_FIX_CONST( HP_NOISE_COEF, 16 ) -
+ SKP_SMULWB( SKP_FIX_CONST( 1.0, 16 ) - SKP_FIX_CONST( HP_NOISE_COEF, 16 ),
+ SKP_SMULWB( SKP_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->speech_activity_Q8 ) );
+ } else {
+ b_Q14 = SKP_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); // 1.3_Q0 = 21299_Q14
+ /* Pack two coefficients in one int32 */
+ psEncCtrl->LF_shp_Q14[ 0 ] = SKP_LSHIFT( SKP_FIX_CONST( 1.0, 14 ) - b_Q14 -
+ SKP_SMULWB( strength_Q16, SKP_SMULWB( SKP_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
+ psEncCtrl->LF_shp_Q14[ 0 ] |= (SKP_uint16)( b_Q14 - SKP_FIX_CONST( 1.0, 14 ) );
+ for( k = 1; k < NB_SUBFR; k++ ) {
+ psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
+ }
+ Tilt_Q16 = -SKP_FIX_CONST( HP_NOISE_COEF, 16 );
+ }
+
+ /****************************/
+ /* HARMONIC SHAPING CONTROL */
+ /****************************/
+ /* Control boosting of harmonic frequencies */
+ HarmBoost_Q16 = SKP_SMULWB( SKP_SMULWB( SKP_FIX_CONST( 1.0, 17 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
+ psEnc->LTPCorr_Q15 ), SKP_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
+
+ /* More harmonic boost for noisy input signals */
+ HarmBoost_Q16 = SKP_SMLAWB( HarmBoost_Q16,
+ SKP_FIX_CONST( 1.0, 16 ) - SKP_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SKP_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
+
+ if( USE_HARM_SHAPING && psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ /* More harmonic noise shaping for high bitrates or noisy input */
+ HarmShapeGain_Q16 = SKP_SMLAWB( SKP_FIX_CONST( HARMONIC_SHAPING, 16 ),
+ SKP_FIX_CONST( 1.0, 16 ) - SKP_SMULWB( SKP_FIX_CONST( 1.0, 18 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
+ psEncCtrl->input_quality_Q14 ), SKP_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
+
+ /* Less harmonic noise shaping for less periodic signals */
+ HarmShapeGain_Q16 = SKP_SMULWB( SKP_LSHIFT( HarmShapeGain_Q16, 1 ),
+ SKP_Silk_SQRT_APPROX( SKP_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
+ } else {
+ HarmShapeGain_Q16 = 0;
+ }
+
+ /*************************/
+ /* Smooth over subframes */
+ /*************************/
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ psShapeSt->HarmBoost_smth_Q16 =
+ SKP_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
+ psShapeSt->HarmShapeGain_smth_Q16 =
+ SKP_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
+ psShapeSt->Tilt_smth_Q16 =
+ SKP_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SKP_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
+
+ psEncCtrl->HarmBoost_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 );
+ psEncCtrl->HarmShapeGain_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
+ psEncCtrl->Tilt_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_pitch_analysis_core.c b/pkg/silk/csilk/SKP_Silk_pitch_analysis_core.c
new file mode 100644
index 0000000..7000ff4
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_pitch_analysis_core.c
@@ -0,0 +1,706 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/***********************************************************
+* Pitch analyser function
+********************************************************** */
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_pitch_est_defines.h"
+#include "SKP_Silk_common_pitch_est_defines.h"
+
+#define SCRATCH_SIZE 22
+
+/************************************************************/
+/* Internally used functions */
+/************************************************************/
+void SKP_FIX_P_Ana_calc_corr_st3(
+ SKP_int32 cross_corr_st3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX][PITCH_EST_NB_STAGE3_LAGS],/* (O) 3 DIM correlation array */
+ const SKP_int16 signal[], /* I vector to correlate */
+ SKP_int start_lag, /* I lag offset to search around */
+ SKP_int sf_length, /* I length of a 5 ms subframe */
+ SKP_int complexity /* I Complexity setting */
+);
+
+void SKP_FIX_P_Ana_calc_energy_st3(
+ SKP_int32 energies_st3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX][PITCH_EST_NB_STAGE3_LAGS],/* (O) 3 DIM energy array */
+ const SKP_int16 signal[], /* I vector to calc energy in */
+ SKP_int start_lag, /* I lag offset to search around */
+ SKP_int sf_length, /* I length of one 5 ms subframe */
+ SKP_int complexity /* I Complexity setting */
+);
+
+SKP_int32 SKP_FIX_P_Ana_find_scaling(
+ const SKP_int16 *signal,
+ const SKP_int signal_length,
+ const SKP_int sum_sqr_len
+);
+
+/*************************************************************/
+/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
+/*************************************************************/
+SKP_int SKP_Silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
+ const SKP_int16 *signal, /* I Signal of length PITCH_EST_FRAME_LENGTH_MS*Fs_kHz */
+ SKP_int *pitch_out, /* O 4 pitch lag values */
+ SKP_int *lagIndex, /* O Lag Index */
+ SKP_int *contourIndex, /* O Pitch contour Index */
+ SKP_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
+ SKP_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
+ const SKP_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
+ const SKP_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */
+ const SKP_int Fs_kHz, /* I Sample frequency (kHz) */
+ const SKP_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
+ const SKP_int forLJC /* I 1 if this function is called from LJC code, 0 otherwise. */
+)
+{
+ SKP_int16 signal_8kHz[ PITCH_EST_MAX_FRAME_LENGTH_ST_2 ];
+ SKP_int16 signal_4kHz[ PITCH_EST_MAX_FRAME_LENGTH_ST_1 ];
+ SKP_int32 scratch_mem[ 3 * PITCH_EST_MAX_FRAME_LENGTH ];
+ SKP_int16 *input_signal_ptr;
+ SKP_int32 filt_state[ PITCH_EST_MAX_DECIMATE_STATE_LENGTH ];
+ SKP_int i, k, d, j;
+ SKP_int16 C[ PITCH_EST_NB_SUBFR ][ ( PITCH_EST_MAX_LAG >> 1 ) + 5 ];
+ const SKP_int16 *target_ptr, *basis_ptr;
+ SKP_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;
+ SKP_int d_srch[ PITCH_EST_D_SRCH_LENGTH ];
+ SKP_int16 d_comp[ ( PITCH_EST_MAX_LAG >> 1 ) + 5 ];
+ SKP_int Cmax, length_d_srch, length_d_comp;
+ SKP_int32 sum, threshold, temp32;
+ SKP_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
+ SKP_int32 CC[ PITCH_EST_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;
+ SKP_int32 energies_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ];
+ SKP_int32 crosscorr_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ];
+ SKP_int32 lag_counter;
+ SKP_int frame_length, frame_length_8kHz, frame_length_4kHz, max_sum_sq_length;
+ SKP_int sf_length, sf_length_8kHz;
+ SKP_int min_lag, min_lag_8kHz, min_lag_4kHz;
+ SKP_int max_lag, max_lag_8kHz, max_lag_4kHz;
+ SKP_int32 contour_bias, diff;
+ SKP_int32 lz, lshift;
+ SKP_int cbk_offset, cbk_size, nb_cbks_stage2;
+ SKP_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q15, corr_thres_Q15;
+
+ /* Check for valid sampling frequency */
+ SKP_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 || Fs_kHz == 24 );
+
+ /* Check for valid complexity setting */
+ SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX );
+ SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX );
+
+ SKP_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
+ SKP_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) );
+
+ /* Setup frame lengths max / min lag for the sampling frequency */
+ frame_length = PITCH_EST_FRAME_LENGTH_MS * Fs_kHz;
+ frame_length_4kHz = PITCH_EST_FRAME_LENGTH_MS * 4;
+ frame_length_8kHz = PITCH_EST_FRAME_LENGTH_MS * 8;
+ sf_length = SKP_RSHIFT( frame_length, 3 );
+ sf_length_8kHz = SKP_RSHIFT( frame_length_8kHz, 3 );
+ min_lag = PITCH_EST_MIN_LAG_MS * Fs_kHz;
+ min_lag_4kHz = PITCH_EST_MIN_LAG_MS * 4;
+ min_lag_8kHz = PITCH_EST_MIN_LAG_MS * 8;
+ max_lag = PITCH_EST_MAX_LAG_MS * Fs_kHz;
+ max_lag_4kHz = PITCH_EST_MAX_LAG_MS * 4;
+ max_lag_8kHz = PITCH_EST_MAX_LAG_MS * 8;
+
+ SKP_memset( C, 0, sizeof( SKP_int16 ) * PITCH_EST_NB_SUBFR * ( ( PITCH_EST_MAX_LAG >> 1 ) + 5) );
+
+ /* Resample from input sampled at Fs_kHz to 8 kHz */
+ if( Fs_kHz == 16 ) {
+ SKP_memset( filt_state, 0, 2 * sizeof( SKP_int32 ) );
+ SKP_Silk_resampler_down2( filt_state, signal_8kHz, signal, frame_length );
+ } else if ( Fs_kHz == 12 ) {
+ SKP_int32 R23[ 6 ];
+ SKP_memset( R23, 0, 6 * sizeof( SKP_int32 ) );
+ SKP_Silk_resampler_down2_3( R23, signal_8kHz, signal, PITCH_EST_FRAME_LENGTH_MS * 12 );
+ } else if( Fs_kHz == 24 ) {
+ SKP_int32 filt_state_fix[ 8 ];
+ SKP_memset( filt_state_fix, 0, 8 * sizeof(SKP_int32) );
+ SKP_Silk_resampler_down3( filt_state_fix, signal_8kHz, signal, 24 * PITCH_EST_FRAME_LENGTH_MS );
+ } else {
+ SKP_assert( Fs_kHz == 8 );
+ SKP_memcpy( signal_8kHz, signal, frame_length_8kHz * sizeof(SKP_int16) );
+ }
+ /* Decimate again to 4 kHz */
+ SKP_memset( filt_state, 0, 2 * sizeof( SKP_int32 ) );/* Set state to zero */
+ SKP_Silk_resampler_down2( filt_state, signal_4kHz, signal_8kHz, frame_length_8kHz );
+
+ /* Low-pass filter */
+ for( i = frame_length_4kHz - 1; i > 0; i-- ) {
+ signal_4kHz[ i ] = SKP_ADD_SAT16( signal_4kHz[ i ], signal_4kHz[ i - 1 ] );
+ }
+
+ /*******************************************************************************
+ ** Scale 4 kHz signal down to prevent correlations measures from overflowing
+ ** find scaling as max scaling for each 8kHz(?) subframe
+ *******************************************************************************/
+
+ /* Inner product is calculated with different lengths, so scale for the worst case */
+ max_sum_sq_length = SKP_max_32( sf_length_8kHz, SKP_RSHIFT( frame_length_4kHz, 1 ) );
+ shift = SKP_FIX_P_Ana_find_scaling( signal_4kHz, frame_length_4kHz, max_sum_sq_length );
+ if( shift > 0 ) {
+ for( i = 0; i < frame_length_4kHz; i++ ) {
+ signal_4kHz[ i ] = SKP_RSHIFT( signal_4kHz[ i ], shift );
+ }
+ }
+
+ /******************************************************************************
+ * FIRST STAGE, operating in 4 khz
+ ******************************************************************************/
+ target_ptr = &signal_4kHz[ SKP_RSHIFT( frame_length_4kHz, 1 ) ];
+ for( k = 0; k < 2; k++ ) {
+ /* Check that we are within range of the array */
+ SKP_assert( target_ptr >= signal_4kHz );
+ SKP_assert( target_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz );
+
+ basis_ptr = target_ptr - min_lag_4kHz;
+
+ /* Check that we are within range of the array */
+ SKP_assert( basis_ptr >= signal_4kHz );
+ SKP_assert( basis_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz );
+
+ normalizer = 0;
+ cross_corr = 0;
+ /* Calculate first vector products before loop */
+ cross_corr = SKP_Silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+ normalizer = SKP_Silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz );
+ normalizer = SKP_ADD_SAT32( normalizer, SKP_SMULBB( sf_length_8kHz, 4000 ) );
+
+ temp32 = SKP_DIV32( cross_corr, SKP_Silk_SQRT_APPROX( normalizer ) + 1 );
+ C[ k ][ min_lag_4kHz ] = (SKP_int16)SKP_SAT16( temp32 ); /* Q0 */
+
+ /* From now on normalizer is computed recursively */
+ for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
+ basis_ptr--;
+
+ /* Check that we are within range of the array */
+ SKP_assert( basis_ptr >= signal_4kHz );
+ SKP_assert( basis_ptr + sf_length_8kHz <= signal_4kHz + frame_length_4kHz );
+
+ cross_corr = SKP_Silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+
+ /* Add contribution of new sample and remove contribution from oldest sample */
+ normalizer +=
+ SKP_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
+ SKP_SMULBB( basis_ptr[ sf_length_8kHz ], basis_ptr[ sf_length_8kHz ] );
+
+ temp32 = SKP_DIV32( cross_corr, SKP_Silk_SQRT_APPROX( normalizer ) + 1 );
+ C[ k ][ d ] = (SKP_int16)SKP_SAT16( temp32 ); /* Q0 */
+ }
+ /* Update target pointer */
+ target_ptr += sf_length_8kHz;
+ }
+
+ /* Combine two subframes into single correlation measure and apply short-lag bias */
+ for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
+ sum = (SKP_int32)C[ 0 ][ i ] + (SKP_int32)C[ 1 ][ i ]; /* Q0 */
+ SKP_assert( SKP_RSHIFT( sum, 1 ) == SKP_SAT16( SKP_RSHIFT( sum, 1 ) ) );
+ sum = SKP_RSHIFT( sum, 1 ); /* Q-1 */
+ SKP_assert( SKP_LSHIFT( (SKP_int32)-i, 4 ) == SKP_SAT16( SKP_LSHIFT( (SKP_int32)-i, 4 ) ) );
+ sum = SKP_SMLAWB( sum, sum, SKP_LSHIFT( -i, 4 ) ); /* Q-1 */
+ SKP_assert( sum == SKP_SAT16( sum ) );
+ C[ 0 ][ i ] = (SKP_int16)sum; /* Q-1 */
+ }
+
+ /* Sort */
+ length_d_srch = 4 + 2 * complexity;
+ SKP_assert( 3 * length_d_srch <= PITCH_EST_D_SRCH_LENGTH );
+ SKP_Silk_insertion_sort_decreasing_int16( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
+
+ /* Escape if correlation is very low already here */
+ target_ptr = &signal_4kHz[ SKP_RSHIFT( frame_length_4kHz, 1 ) ];
+ energy = SKP_Silk_inner_prod_aligned( target_ptr, target_ptr, SKP_RSHIFT( frame_length_4kHz, 1 ) );
+ energy = SKP_ADD_POS_SAT32( energy, 1000 ); /* Q0 */
+ Cmax = (SKP_int)C[ 0 ][ min_lag_4kHz ]; /* Q-1 */
+ threshold = SKP_SMULBB( Cmax, Cmax ); /* Q-2 */
+ /* Compare in Q-2 domain */
+ if( SKP_RSHIFT( energy, 4 + 2 ) > threshold ) {
+ SKP_memset( pitch_out, 0, PITCH_EST_NB_SUBFR * sizeof( SKP_int ) );
+ *LTPCorr_Q15 = 0;
+ *lagIndex = 0;
+ *contourIndex = 0;
+ return 1;
+ }
+
+ threshold = SKP_SMULWB( search_thres1_Q16, Cmax );
+ for( i = 0; i < length_d_srch; i++ ) {
+ /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
+ if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
+ d_srch[ i ] = ( d_srch[ i ] + min_lag_4kHz ) << 1;
+ } else {
+ length_d_srch = i;
+ break;
+ }
+ }
+ SKP_assert( length_d_srch > 0 );
+
+ for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
+ d_comp[ i ] = 0;
+ }
+ for( i = 0; i < length_d_srch; i++ ) {
+ d_comp[ d_srch[ i ] ] = 1;
+ }
+
+ /* Convolution */
+ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
+ d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
+ }
+
+ length_d_srch = 0;
+ for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
+ if( d_comp[ i + 1 ] > 0 ) {
+ d_srch[ length_d_srch ] = i;
+ length_d_srch++;
+ }
+ }
+
+ /* Convolution */
+ for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
+ d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
+ }
+
+ length_d_comp = 0;
+ for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
+ if( d_comp[ i ] > 0 ) {
+ d_comp[ length_d_comp ] = i - 2;
+ length_d_comp++;
+ }
+ }
+
+ /**********************************************************************************
+ ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
+ *************************************************************************************/
+
+ /******************************************************************************
+ ** Scale signal down to avoid correlations measures from overflowing
+ *******************************************************************************/
+ /* find scaling as max scaling for each subframe */
+ shift = SKP_FIX_P_Ana_find_scaling( signal_8kHz, frame_length_8kHz, sf_length_8kHz );
+ if( shift > 0 ) {
+ for( i = 0; i < frame_length_8kHz; i++ ) {
+ signal_8kHz[ i ] = SKP_RSHIFT( signal_8kHz[ i ], shift );
+ }
+ }
+
+ /*********************************************************************************
+ * Find energy of each subframe projected onto its history, for a range of delays
+ *********************************************************************************/
+ SKP_memset( C, 0, PITCH_EST_NB_SUBFR * ( ( PITCH_EST_MAX_LAG >> 1 ) + 5 ) * sizeof( SKP_int16 ) );
+
+ target_ptr = &signal_8kHz[ frame_length_4kHz ]; /* point to middle of frame */
+ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
+
+ /* Check that we are within range of the array */
+ SKP_assert( target_ptr >= signal_8kHz );
+ SKP_assert( target_ptr + sf_length_8kHz <= signal_8kHz + frame_length_8kHz );
+
+ energy_target = SKP_Silk_inner_prod_aligned( target_ptr, target_ptr, sf_length_8kHz );
+ // ToDo: Calculate 1 / energy_target here and save one division inside next for loop
+ for( j = 0; j < length_d_comp; j++ ) {
+ d = d_comp[ j ];
+ basis_ptr = target_ptr - d;
+
+ /* Check that we are within range of the array */
+ SKP_assert( basis_ptr >= signal_8kHz );
+ SKP_assert( basis_ptr + sf_length_8kHz <= signal_8kHz + frame_length_8kHz );
+
+ cross_corr = SKP_Silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+ energy_basis = SKP_Silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz );
+ if( cross_corr > 0 ) {
+ energy = SKP_max( energy_target, energy_basis ); /* Find max to make sure first division < 1.0 */
+ lz = SKP_Silk_CLZ32( cross_corr );
+ lshift = SKP_LIMIT_32( lz - 1, 0, 15 );
+ temp32 = SKP_DIV32( SKP_LSHIFT( cross_corr, lshift ), SKP_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15 */
+ SKP_assert( temp32 == SKP_SAT16( temp32 ) );
+ temp32 = SKP_SMULWB( cross_corr, temp32 ); /* Q(-1), cc * ( cc / max(b, t) ) */
+ temp32 = SKP_ADD_SAT32( temp32, temp32 ); /* Q(0) */
+ lz = SKP_Silk_CLZ32( temp32 );
+ lshift = SKP_LIMIT_32( lz - 1, 0, 15 );
+ energy = SKP_min( energy_target, energy_basis );
+ C[ k ][ d ] = SKP_DIV32( SKP_LSHIFT( temp32, lshift ), SKP_RSHIFT( energy, 15 - lshift ) + 1 ); // Q15
+ } else {
+ C[ k ][ d ] = 0;
+ }
+ }
+ target_ptr += sf_length_8kHz;
+ }
+
+ /* search over lag range and lags codebook */
+ /* scale factor for lag codebook, as a function of center lag */
+
+ CCmax = SKP_int32_MIN;
+ CCmax_b = SKP_int32_MIN;
+
+ CBimax = 0; /* To avoid returning undefined lag values */
+ lag = -1; /* To check if lag with strong enough correlation has been found */
+
+ if( prevLag > 0 ) {
+ if( Fs_kHz == 12 ) {
+ prevLag = SKP_DIV32_16( SKP_LSHIFT( prevLag, 1 ), 3 );
+ } else if( Fs_kHz == 16 ) {
+ prevLag = SKP_RSHIFT( prevLag, 1 );
+ } else if( Fs_kHz == 24 ) {
+ prevLag = SKP_DIV32_16( prevLag, 3 );
+ }
+ prevLag_log2_Q7 = SKP_Silk_lin2log( (SKP_int32)prevLag );
+ } else {
+ prevLag_log2_Q7 = 0;
+ }
+ SKP_assert( search_thres2_Q15 == SKP_SAT16( search_thres2_Q15 ) );
+ corr_thres_Q15 = SKP_RSHIFT( SKP_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 13 );
+
+ /* If input is 8 khz use a larger codebook here because it is last stage */
+ if( Fs_kHz == 8 && complexity > SKP_Silk_PITCH_EST_MIN_COMPLEX ) {
+ nb_cbks_stage2 = PITCH_EST_NB_CBKS_STAGE2_EXT;
+ } else {
+ nb_cbks_stage2 = PITCH_EST_NB_CBKS_STAGE2;
+ }
+
+ for( k = 0; k < length_d_srch; k++ ) {
+ d = d_srch[ k ];
+ for( j = 0; j < nb_cbks_stage2; j++ ) {
+ CC[ j ] = 0;
+ for( i = 0; i < PITCH_EST_NB_SUBFR; i++ ) {
+ /* Try all codebooks */
+ CC[ j ] = CC[ j ] + (SKP_int32)C[ i ][ d + SKP_Silk_CB_lags_stage2[ i ][ j ] ];
+ }
+ }
+ /* Find best codebook */
+ CCmax_new = SKP_int32_MIN;
+ CBimax_new = 0;
+ for( i = 0; i < nb_cbks_stage2; i++ ) {
+ if( CC[ i ] > CCmax_new ) {
+ CCmax_new = CC[ i ];
+ CBimax_new = i;
+ }
+ }
+
+ /* Bias towards shorter lags */
+ lag_log2_Q7 = SKP_Silk_lin2log( (SKP_int32)d ); /* Q7 */
+ SKP_assert( lag_log2_Q7 == SKP_SAT16( lag_log2_Q7 ) );
+ SKP_assert( PITCH_EST_NB_SUBFR * PITCH_EST_SHORTLAG_BIAS_Q15 == SKP_SAT16( PITCH_EST_NB_SUBFR * PITCH_EST_SHORTLAG_BIAS_Q15 ) );
+
+ if (forLJC) {
+ CCmax_new_b = CCmax_new;
+ } else {
+ CCmax_new_b = CCmax_new - SKP_RSHIFT( SKP_SMULBB( PITCH_EST_NB_SUBFR * PITCH_EST_SHORTLAG_BIAS_Q15, lag_log2_Q7 ), 7 ); /* Q15 */
+ }
+
+ /* Bias towards previous lag */
+ SKP_assert( PITCH_EST_NB_SUBFR * PITCH_EST_PREVLAG_BIAS_Q15 == SKP_SAT16( PITCH_EST_NB_SUBFR * PITCH_EST_PREVLAG_BIAS_Q15 ) );
+ if( prevLag > 0 ) {
+ delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7;
+ SKP_assert( delta_lag_log2_sqr_Q7 == SKP_SAT16( delta_lag_log2_sqr_Q7 ) );
+ delta_lag_log2_sqr_Q7 = SKP_RSHIFT( SKP_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 );
+ prev_lag_bias_Q15 = SKP_RSHIFT( SKP_SMULBB( PITCH_EST_NB_SUBFR * PITCH_EST_PREVLAG_BIAS_Q15, ( *LTPCorr_Q15 ) ), 15 ); /* Q15 */
+ prev_lag_bias_Q15 = SKP_DIV32( SKP_MUL( prev_lag_bias_Q15, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + ( 1 << 6 ) );
+ CCmax_new_b -= prev_lag_bias_Q15; /* Q15 */
+ }
+
+ if ( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
+ CCmax_new > corr_thres_Q15 && /* Correlation needs to be high enough to be voiced */
+ SKP_Silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */
+ ) {
+ CCmax_b = CCmax_new_b;
+ CCmax = CCmax_new;
+ lag = d;
+ CBimax = CBimax_new;
+ }
+ }
+
+ if( lag == -1 ) {
+ /* No suitable candidate found */
+ SKP_memset( pitch_out, 0, PITCH_EST_NB_SUBFR * sizeof( SKP_int ) );
+ *LTPCorr_Q15 = 0;
+ *lagIndex = 0;
+ *contourIndex = 0;
+ return 1;
+ }
+
+ if( Fs_kHz > 8 ) {
+
+ /******************************************************************************
+ ** Scale input signal down to avoid correlations measures from overflowing
+ *******************************************************************************/
+ /* find scaling as max scaling for each subframe */
+ shift = SKP_FIX_P_Ana_find_scaling( signal, frame_length, sf_length );
+ if( shift > 0 ) {
+ /* Move signal to scratch mem because the input signal should be unchanged */
+ /* Reuse the 32 bit scratch mem vector, use a 16 bit pointer from now */
+ input_signal_ptr = (SKP_int16*)scratch_mem;
+ for( i = 0; i < frame_length; i++ ) {
+ input_signal_ptr[ i ] = SKP_RSHIFT( signal[ i ], shift );
+ }
+ } else {
+ input_signal_ptr = (SKP_int16*)signal;
+ }
+ /*********************************************************************************/
+
+ /* Search in original signal */
+
+ CBimax_old = CBimax;
+ /* Compensate for decimation */
+ SKP_assert( lag == SKP_SAT16( lag ) );
+ if( Fs_kHz == 12 ) {
+ lag = SKP_RSHIFT( SKP_SMULBB( lag, 3 ), 1 );
+ } else if( Fs_kHz == 16 ) {
+ lag = SKP_LSHIFT( lag, 1 );
+ } else {
+ lag = SKP_SMULBB( lag, 3 );
+ }
+
+ lag = SKP_LIMIT_int( lag, min_lag, max_lag );
+ start_lag = SKP_max_int( lag - 2, min_lag );
+ end_lag = SKP_min_int( lag + 2, max_lag );
+ lag_new = lag; /* to avoid undefined lag */
+ CBimax = 0; /* to avoid undefined lag */
+ SKP_assert( SKP_LSHIFT( CCmax, 13 ) >= 0 );
+ *LTPCorr_Q15 = (SKP_int)SKP_Silk_SQRT_APPROX( SKP_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */
+
+ CCmax = SKP_int32_MIN;
+ /* pitch lags according to second stage */
+ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
+ pitch_out[ k ] = lag + 2 * SKP_Silk_CB_lags_stage2[ k ][ CBimax_old ];
+ }
+ /* Calculate the correlations and energies needed in stage 3 */
+ SKP_FIX_P_Ana_calc_corr_st3( crosscorr_st3, input_signal_ptr, start_lag, sf_length, complexity );
+ SKP_FIX_P_Ana_calc_energy_st3( energies_st3, input_signal_ptr, start_lag, sf_length, complexity );
+
+ lag_counter = 0;
+ SKP_assert( lag == SKP_SAT16( lag ) );
+ contour_bias = SKP_DIV32_16( PITCH_EST_FLATCONTOUR_BIAS_Q20, lag );
+
+ /* Setup cbk parameters acording to complexity setting */
+ cbk_size = (SKP_int)SKP_Silk_cbk_sizes_stage3[ complexity ];
+ cbk_offset = (SKP_int)SKP_Silk_cbk_offsets_stage3[ complexity ];
+
+ for( d = start_lag; d <= end_lag; d++ ) {
+ for( j = cbk_offset; j < ( cbk_offset + cbk_size ); j++ ) {
+ cross_corr = 0;
+ energy = 0;
+ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
+ SKP_assert( PITCH_EST_NB_SUBFR == 4 );
+ energy += SKP_RSHIFT( energies_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */
+ SKP_assert( energy >= 0 );
+ cross_corr += SKP_RSHIFT( crosscorr_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */
+ }
+ if( cross_corr > 0 ) {
+ /* Divide cross_corr / energy and get result in Q15 */
+ lz = SKP_Silk_CLZ32( cross_corr );
+ /* Divide with result in Q13, cross_corr could be larger than energy */
+ lshift = SKP_LIMIT_32( lz - 1, 0, 13 );
+ CCmax_new = SKP_DIV32( SKP_LSHIFT( cross_corr, lshift ), SKP_RSHIFT( energy, 13 - lshift ) + 1 );
+ CCmax_new = SKP_SAT16( CCmax_new );
+ CCmax_new = SKP_SMULWB( cross_corr, CCmax_new );
+ /* Saturate */
+ if( CCmax_new > SKP_RSHIFT( SKP_int32_MAX, 3 ) ) {
+ CCmax_new = SKP_int32_MAX;
+ } else {
+ CCmax_new = SKP_LSHIFT( CCmax_new, 3 );
+ }
+ /* Reduce depending on flatness of contour */
+ diff = j - SKP_RSHIFT( PITCH_EST_NB_CBKS_STAGE3_MAX, 1 );
+ diff = SKP_MUL( diff, diff );
+ diff = SKP_int16_MAX - SKP_RSHIFT( SKP_MUL( contour_bias, diff ), 5 ); /* Q20 -> Q15 */
+ SKP_assert( diff == SKP_SAT16( diff ) );
+ CCmax_new = SKP_LSHIFT( SKP_SMULWB( CCmax_new, diff ), 1 );
+ } else {
+ CCmax_new = 0;
+ }
+
+ if( CCmax_new > CCmax &&
+ ( d + (SKP_int)SKP_Silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag
+ ) {
+ CCmax = CCmax_new;
+ lag_new = d;
+ CBimax = j;
+ }
+ }
+ lag_counter++;
+ }
+
+ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
+ pitch_out[ k ] = lag_new + SKP_Silk_CB_lags_stage3[ k ][ CBimax ];
+ }
+ *lagIndex = lag_new - min_lag;
+ *contourIndex = CBimax;
+ } else {
+ /* Save Lags and correlation */
+ CCmax = SKP_max( CCmax, 0 );
+ *LTPCorr_Q15 = (SKP_int)SKP_Silk_SQRT_APPROX( SKP_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */
+ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
+ pitch_out[ k ] = lag + SKP_Silk_CB_lags_stage2[ k ][ CBimax ];
+ }
+ *lagIndex = lag - min_lag_8kHz;
+ *contourIndex = CBimax;
+ }
+ SKP_assert( *lagIndex >= 0 );
+ /* return as voiced */
+ return 0;
+}
+
+/*************************************************************************/
+/* Calculates the correlations used in stage 3 search. In order to cover */
+/* the whole lag codebook for all the searched offset lags (lag +- 2), */
+/*************************************************************************/
+void SKP_FIX_P_Ana_calc_corr_st3(
+ SKP_int32 cross_corr_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */
+ const SKP_int16 signal[], /* I vector to correlate */
+ SKP_int start_lag, /* I lag offset to search around */
+ SKP_int sf_length, /* I length of a 5 ms subframe */
+ SKP_int complexity /* I Complexity setting */
+)
+{
+ const SKP_int16 *target_ptr, *basis_ptr;
+ SKP_int32 cross_corr;
+ SKP_int i, j, k, lag_counter;
+ SKP_int cbk_offset, cbk_size, delta, idx;
+ SKP_int32 scratch_mem[ SCRATCH_SIZE ];
+
+ SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX );
+ SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX );
+
+ cbk_offset = SKP_Silk_cbk_offsets_stage3[ complexity ];
+ cbk_size = SKP_Silk_cbk_sizes_stage3[ complexity ];
+
+ target_ptr = &signal[ SKP_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
+ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
+ lag_counter = 0;
+
+ /* Calculate the correlations for each subframe */
+ for( j = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ]; j <= SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ]; j++ ) {
+ basis_ptr = target_ptr - ( start_lag + j );
+ cross_corr = SKP_Silk_inner_prod_aligned( (SKP_int16*)target_ptr, (SKP_int16*)basis_ptr, sf_length );
+ SKP_assert( lag_counter < SCRATCH_SIZE );
+ scratch_mem[ lag_counter ] = cross_corr;
+ lag_counter++;
+ }
+
+ delta = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ];
+ for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) {
+ /* Fill out the 3 dim array that stores the correlations for */
+ /* each code_book vector for each start lag */
+ idx = SKP_Silk_CB_lags_stage3[ k ][ i ] - delta;
+ for( j = 0; j < PITCH_EST_NB_STAGE3_LAGS; j++ ) {
+ SKP_assert( idx + j < SCRATCH_SIZE );
+ SKP_assert( idx + j < lag_counter );
+ cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
+ }
+ }
+ target_ptr += sf_length;
+ }
+}
+
+/********************************************************************/
+/* Calculate the energies for first two subframes. The energies are */
+/* calculated recursively. */
+/********************************************************************/
+void SKP_FIX_P_Ana_calc_energy_st3(
+ SKP_int32 energies_st3[ PITCH_EST_NB_SUBFR ][ PITCH_EST_NB_CBKS_STAGE3_MAX ][ PITCH_EST_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */
+ const SKP_int16 signal[], /* I vector to calc energy in */
+ SKP_int start_lag, /* I lag offset to search around */
+ SKP_int sf_length, /* I length of one 5 ms subframe */
+ SKP_int complexity /* I Complexity setting */
+)
+{
+ const SKP_int16 *target_ptr, *basis_ptr;
+ SKP_int32 energy;
+ SKP_int k, i, j, lag_counter;
+ SKP_int cbk_offset, cbk_size, delta, idx;
+ SKP_int32 scratch_mem[ SCRATCH_SIZE ];
+
+ SKP_assert( complexity >= SKP_Silk_PITCH_EST_MIN_COMPLEX );
+ SKP_assert( complexity <= SKP_Silk_PITCH_EST_MAX_COMPLEX );
+
+ cbk_offset = SKP_Silk_cbk_offsets_stage3[ complexity ];
+ cbk_size = SKP_Silk_cbk_sizes_stage3[ complexity ];
+
+ target_ptr = &signal[ SKP_LSHIFT( sf_length, 2 ) ];
+ for( k = 0; k < PITCH_EST_NB_SUBFR; k++ ) {
+ lag_counter = 0;
+
+ /* Calculate the energy for first lag */
+ basis_ptr = target_ptr - ( start_lag + SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ] );
+ energy = SKP_Silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length );
+ SKP_assert( energy >= 0 );
+ scratch_mem[ lag_counter ] = energy;
+ lag_counter++;
+
+ for( i = 1; i < ( SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 1 ] - SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ] + 1 ); i++ ) {
+ /* remove part outside new window */
+ energy -= SKP_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] );
+ SKP_assert( energy >= 0 );
+
+ /* add part that comes into window */
+ energy = SKP_ADD_SAT32( energy, SKP_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) );
+ SKP_assert( energy >= 0 );
+ SKP_assert( lag_counter < SCRATCH_SIZE );
+ scratch_mem[ lag_counter ] = energy;
+ lag_counter++;
+ }
+
+ delta = SKP_Silk_Lag_range_stage3[ complexity ][ k ][ 0 ];
+ for( i = cbk_offset; i < ( cbk_offset + cbk_size ); i++ ) {
+ /* Fill out the 3 dim array that stores the correlations for */
+ /* each code_book vector for each start lag */
+ idx = SKP_Silk_CB_lags_stage3[ k ][ i ] - delta;
+ for( j = 0; j < PITCH_EST_NB_STAGE3_LAGS; j++ ) {
+ SKP_assert( idx + j < SCRATCH_SIZE );
+ SKP_assert( idx + j < lag_counter );
+ energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
+ SKP_assert( energies_st3[ k ][ i ][ j ] >= 0.0f );
+ }
+ }
+ target_ptr += sf_length;
+ }
+}
+
+SKP_int32 SKP_FIX_P_Ana_find_scaling(
+ const SKP_int16 *signal,
+ const SKP_int signal_length,
+ const SKP_int sum_sqr_len
+)
+{
+ SKP_int32 nbits, x_max;
+
+ x_max = SKP_Silk_int16_array_maxabs( signal, signal_length );
+
+ if( x_max < SKP_int16_MAX ) {
+ /* Number of bits needed for the sum of the squares */
+ nbits = 32 - SKP_Silk_CLZ32( SKP_SMULBB( x_max, x_max ) );
+ } else {
+ /* Here we don't know if x_max should have been SKP_int16_MAX + 1, so we expect the worst case */
+ nbits = 30;
+ }
+ nbits += 17 - SKP_Silk_CLZ16( sum_sqr_len );
+
+ /* Without a guarantee of saturation, we need to keep the 31st bit free */
+ if( nbits < 31 ) {
+ return 0;
+ } else {
+ return( nbits - 30 );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_pitch_est_defines.h b/pkg/silk/csilk/SKP_Silk_pitch_est_defines.h
new file mode 100644
index 0000000..df299b4
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_pitch_est_defines.h
@@ -0,0 +1,40 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SIGPROCFIX_PITCH_EST_DEFINES_H
+#define SIGPROCFIX_PITCH_EST_DEFINES_H
+
+/************************************************************/
+/* Definitions For Fix pitch estimator */
+/************************************************************/
+
+#define PITCH_EST_SHORTLAG_BIAS_Q15 6554 /* 0.2f. for logarithmic weighting */
+#define PITCH_EST_PREVLAG_BIAS_Q15 6554 /* Prev lag bias */
+#define PITCH_EST_FLATCONTOUR_BIAS_Q20 52429 /* 0.05f */
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_pitch_est_tables.c b/pkg/silk/csilk/SKP_Silk_pitch_est_tables.c
new file mode 100644
index 0000000..26902b3
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_pitch_est_tables.c
@@ -0,0 +1,89 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_typedef.h"
+#include "SKP_Silk_common_pitch_est_defines.h"
+
+/********************************************************/
+/* Auto Generated File from generate_pitch_est_tables.m */
+/********************************************************/
+
+const SKP_int16 SKP_Silk_CB_lags_stage2[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE2_EXT] =
+{
+ {0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1},
+ {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1}
+};
+
+const SKP_int16 SKP_Silk_CB_lags_stage3[PITCH_EST_NB_SUBFR][PITCH_EST_NB_CBKS_STAGE3_MAX] =
+{
+ {-9,-7,-6,-5,-5,-4,-4,-3,-3,-2,-2,-2,-1,-1,-1, 0, 0, 0, 1, 1, 0, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 5, 6, 8},
+ {-3,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0,-1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 2, 1, 2, 2, 2, 2, 3},
+ { 3, 3, 2, 2, 2, 2, 1, 2, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,-1, 0, 0,-1,-1,-1,-1,-1,-2,-2,-2},
+ { 9, 8, 6, 5, 6, 5, 4, 4, 3, 3, 2, 2, 2, 1, 0, 1, 1, 0, 0, 0,-1,-1,-1,-2,-2,-2,-3,-3,-4,-4,-5,-5,-6,-7}
+ };
+
+const SKP_int16 SKP_Silk_Lag_range_stage3[ SKP_Silk_PITCH_EST_MAX_COMPLEX + 1 ] [ PITCH_EST_NB_SUBFR ][ 2 ] =
+{
+ /* Lags to search for low number of stage3 cbks */
+ {
+ {-2,6},
+ {-1,5},
+ {-1,5},
+ {-2,7}
+ },
+ /* Lags to search for middle number of stage3 cbks */
+ {
+ {-4,8},
+ {-1,6},
+ {-1,6},
+ {-4,9}
+ },
+ /* Lags to search for max number of stage3 cbks */
+ {
+ {-9,12},
+ {-3,7},
+ {-2,7},
+ {-7,13}
+ }
+};
+
+const SKP_int16 SKP_Silk_cbk_sizes_stage3[SKP_Silk_PITCH_EST_MAX_COMPLEX + 1] =
+{
+ PITCH_EST_NB_CBKS_STAGE3_MIN,
+ PITCH_EST_NB_CBKS_STAGE3_MID,
+ PITCH_EST_NB_CBKS_STAGE3_MAX
+};
+
+const SKP_int16 SKP_Silk_cbk_offsets_stage3[SKP_Silk_PITCH_EST_MAX_COMPLEX + 1] =
+{
+ ((PITCH_EST_NB_CBKS_STAGE3_MAX - PITCH_EST_NB_CBKS_STAGE3_MIN) >> 1),
+ ((PITCH_EST_NB_CBKS_STAGE3_MAX - PITCH_EST_NB_CBKS_STAGE3_MID) >> 1),
+ 0
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_prefilter_FIX.c b/pkg/silk/csilk/SKP_Silk_prefilter_FIX.c
new file mode 100644
index 0000000..7b626b9
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_prefilter_FIX.c
@@ -0,0 +1,224 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */
+SKP_INLINE void SKP_Silk_prefilt_FIX(
+ SKP_Silk_prefilter_state_FIX *P, /* I/O state */
+ SKP_int32 st_res_Q12[], /* I short term residual signal */
+ SKP_int16 xw[], /* O prefiltered signal */
+ SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
+ SKP_int Tilt_Q14, /* I Tilt shaping coeficient */
+ SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/
+ SKP_int lag, /* I Lag for harmonic shaping */
+ SKP_int length /* I Length of signals */
+);
+#if EMBEDDED_ARM<6
+void SKP_Silk_warped_LPC_analysis_filter_FIX(
+ SKP_int32 state[], /* I/O State [order + 1] */
+ SKP_int16 res[], /* O Residual signal [length] */
+ const SKP_int16 coef_Q13[], /* I Coefficients [order] */
+ const SKP_int16 input[], /* I Input signal [length] */
+ const SKP_int16 lambda_Q16, /* I Warping factor */
+ const SKP_int length, /* I Length of input signal */
+ const SKP_int order /* I Filter order (even) */
+)
+{
+ SKP_int n, i;
+ SKP_int32 acc_Q11, tmp1, tmp2;
+
+ /* Order must be even */
+ SKP_assert( ( order & 1 ) == 0 );
+
+ for( n = 0; n < length; n++ ) {
+ /* Output of lowpass section */
+ tmp2 = SKP_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
+ state[ 0 ] = SKP_LSHIFT( input[ n ], 14 );
+ /* Output of allpass section */
+ tmp1 = SKP_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
+ state[ 1 ] = tmp2;
+ acc_Q11 = SKP_SMULWB( tmp2, coef_Q13[ 0 ] );
+ /* Loop over allpass sections */
+ for( i = 2; i < order; i += 2 ) {
+ /* Output of allpass section */
+ tmp2 = SKP_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
+ state[ i ] = tmp1;
+ acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
+ /* Output of allpass section */
+ tmp1 = SKP_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
+ state[ i + 1 ] = tmp2;
+ acc_Q11 = SKP_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
+ }
+ state[ order ] = tmp1;
+ acc_Q11 = SKP_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
+ res[ n ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )input[ n ] - SKP_RSHIFT_ROUND( acc_Q11, 11 ) );
+ }
+}
+#endif
+
+void SKP_Silk_prefilter_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
+ const SKP_Silk_encoder_control_FIX *psEncCtrl, /* I Encoder control FIX */
+ SKP_int16 xw[], /* O Weighted signal */
+ const SKP_int16 x[] /* I Speech signal */
+)
+{
+ SKP_Silk_prefilter_state_FIX *P = &psEnc->sPrefilt;
+ SKP_int j, k, lag;
+ SKP_int32 tmp_32;
+ const SKP_int16 *AR1_shp_Q13;
+ const SKP_int16 *px;
+ SKP_int16 *pxw;
+ SKP_int HarmShapeGain_Q12, Tilt_Q14;
+ SKP_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
+ SKP_int32 x_filt_Q12[ MAX_FRAME_LENGTH / NB_SUBFR ];
+ SKP_int16 st_res[ ( MAX_FRAME_LENGTH / NB_SUBFR ) + MAX_SHAPE_LPC_ORDER ];
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ SKP_int32 B_Q12;
+#else
+ SKP_int16 B_Q12[ 2 ];
+#endif
+
+ /* Setup pointers */
+ px = x;
+ pxw = xw;
+ lag = P->lagPrev;
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ /* Update Variables that change per sub frame */
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ lag = psEncCtrl->sCmn.pitchL[ k ];
+ }
+
+ /* Noise shape parameters */
+ HarmShapeGain_Q12 = SKP_SMULWB( psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );
+ SKP_assert( HarmShapeGain_Q12 >= 0 );
+ HarmShapeFIRPacked_Q12 = SKP_RSHIFT( HarmShapeGain_Q12, 2 );
+ HarmShapeFIRPacked_Q12 |= SKP_LSHIFT( ( SKP_int32 )SKP_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );
+ Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ];
+ LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ];
+ AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ];
+
+ /* Short term FIR filtering*/
+ SKP_Silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res, AR1_shp_Q13, px,
+ psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
+
+ /* reduce (mainly) low frequencies during harmonic emphasis */
+#if !defined(_SYSTEM_IS_BIG_ENDIAN)
+ /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the */
+ /* SMLABB and SMLABT instructions. On a big-endian CPU the two int16 variables would be */
+ /* loaded in reverse order and the code will give the wrong result. In that case swapping */
+ /* the SMLABB and SMLABT instructions should solve the problem. */
+ B_Q12 = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 );
+ tmp_32 = SKP_SMLABB( SKP_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */
+ tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */
+ tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */
+ tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 ); /* Q12 */
+ B_Q12 |= SKP_LSHIFT( SKP_SAT16( tmp_32 ), 16 );
+
+ x_filt_Q12[ 0 ] = SKP_SMLABT( SKP_SMULBB( st_res[ 0 ], B_Q12 ), P->sHarmHP, B_Q12 );
+ for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
+ x_filt_Q12[ j ] = SKP_SMLABT( SKP_SMULBB( st_res[ j ], B_Q12 ), st_res[ j - 1 ], B_Q12 );
+ }
+#else
+ B_Q12[ 0 ] = SKP_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 2 );
+ tmp_32 = SKP_SMLABB( SKP_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */
+ tmp_32 = SKP_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SKP_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */
+ tmp_32 = SKP_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */
+ tmp_32 = SKP_RSHIFT_ROUND( tmp_32, 12 ); /* Q12 */
+ B_Q12[ 1 ]= SKP_SAT16( tmp_32 );
+
+ x_filt_Q12[ 0 ] = SKP_SMLABB( SKP_SMULBB( st_res[ 0 ], B_Q12[ 0 ] ), P->sHarmHP, B_Q12[ 1 ] );
+ for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
+ x_filt_Q12[ j ] = SKP_SMLABB( SKP_SMULBB( st_res[ j ], B_Q12[ 0 ] ), st_res[ j - 1 ], B_Q12[ 1 ] );
+ }
+#endif
+ P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
+
+ SKP_Silk_prefilt_FIX( P, x_filt_Q12, pxw, HarmShapeFIRPacked_Q12, Tilt_Q14,
+ LF_shp_Q14, lag, psEnc->sCmn.subfr_length );
+
+ px += psEnc->sCmn.subfr_length;
+ pxw += psEnc->sCmn.subfr_length;
+ }
+
+ P->lagPrev = psEncCtrl->sCmn.pitchL[ NB_SUBFR - 1 ];
+}
+
+/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal */
+SKP_INLINE void SKP_Silk_prefilt_FIX(
+ SKP_Silk_prefilter_state_FIX *P, /* I/O state */
+ SKP_int32 st_res_Q12[], /* I short term residual signal */
+ SKP_int16 xw[], /* O prefiltered signal */
+ SKP_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
+ SKP_int Tilt_Q14, /* I Tilt shaping coeficient */
+ SKP_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients*/
+ SKP_int lag, /* I Lag for harmonic shaping */
+ SKP_int length /* I Length of signals */
+)
+{
+ SKP_int i, idx, LTP_shp_buf_idx;
+ SKP_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
+ SKP_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
+ SKP_int16 *LTP_shp_buf;
+
+ /* To speed up use temp variables instead of using the struct */
+ LTP_shp_buf = P->sLTP_shp;
+ LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
+ sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12;
+ sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12;
+
+ for( i = 0; i < length; i++ ) {
+ if( lag > 0 ) {
+ /* unrolled loop */
+ SKP_assert( HARM_SHAPE_FIR_TAPS == 3 );
+ idx = lag + LTP_shp_buf_idx;
+ n_LTP_Q12 = SKP_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ } else {
+ n_LTP_Q12 = 0;
+ }
+
+ n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
+ n_LF_Q10 = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
+
+ sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) );
+ sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12, SKP_LSHIFT( n_LF_Q10, 2 ) );
+
+ LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
+ LTP_shp_buf[ LTP_shp_buf_idx ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
+
+ xw[i] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) );
+ }
+
+ /* Copy temp variable back to state */
+ P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12;
+ P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12;
+ P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_process_NLSFs_FIX.c b/pkg/silk/csilk/SKP_Silk_process_NLSFs_FIX.c
new file mode 100644
index 0000000..28b8e77
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_process_NLSFs_FIX.c
@@ -0,0 +1,127 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/* Limit, stabilize, convert and quantize NLSFs. */
+void SKP_Silk_process_NLSFs_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
+ SKP_Silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
+ SKP_int *pNLSF_Q15 /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
+)
+{
+ SKP_int doInterpolate;
+ SKP_int pNLSFW_Q6[ MAX_LPC_ORDER ];
+ SKP_int NLSF_mu_Q15, NLSF_mu_fluc_red_Q16;
+ SKP_int32 i_sqr_Q15;
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB;
+
+ /* Used only for NLSF interpolation */
+ SKP_int pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
+ SKP_int pNLSFW0_temp_Q6[ MAX_LPC_ORDER ];
+ SKP_int i;
+
+ SKP_assert( psEnc->speech_activity_Q8 >= 0 );
+ SKP_assert( psEnc->speech_activity_Q8 <= 256 );
+ SKP_assert( psEncCtrl->sparseness_Q8 >= 0 );
+ SKP_assert( psEncCtrl->sparseness_Q8 <= 256 );
+ SKP_assert( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED || psEncCtrl->sCmn.sigtype == SIG_TYPE_UNVOICED );
+
+ /***********************/
+ /* Calculate mu values */
+ /***********************/
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ /* NLSF_mu = 0.002f - 0.001f * psEnc->speech_activity; */
+ /* NLSF_mu_fluc_red = 0.1f - 0.05f * psEnc->speech_activity; */
+ NLSF_mu_Q15 = SKP_SMLAWB( 66, -8388, psEnc->speech_activity_Q8 );
+ NLSF_mu_fluc_red_Q16 = SKP_SMLAWB( 6554, -838848, psEnc->speech_activity_Q8 );
+ } else {
+ /* NLSF_mu = 0.005f - 0.004f * psEnc->speech_activity; */
+ /* NLSF_mu_fluc_red = 0.2f - 0.1f * psEnc->speech_activity - 0.1f * psEncCtrl->sparseness; */
+ NLSF_mu_Q15 = SKP_SMLAWB( 164, -33554, psEnc->speech_activity_Q8 );
+ NLSF_mu_fluc_red_Q16 = SKP_SMLAWB( 13107, -1677696, psEnc->speech_activity_Q8 + psEncCtrl->sparseness_Q8 );
+ }
+ SKP_assert( NLSF_mu_Q15 >= 0 );
+ SKP_assert( NLSF_mu_Q15 <= 164 );
+ SKP_assert( NLSF_mu_fluc_red_Q16 >= 0 );
+ SKP_assert( NLSF_mu_fluc_red_Q16 <= 13107 );
+
+ NLSF_mu_Q15 = SKP_max( NLSF_mu_Q15, 1 );
+
+ /* Calculate NLSF weights */
+ TIC(NLSF_weights_FIX)
+ SKP_Silk_NLSF_VQ_weights_laroia( pNLSFW_Q6, pNLSF_Q15, psEnc->sCmn.predictLPCOrder );
+ TOC(NLSF_weights_FIX)
+
+ /* Update NLSF weights for interpolated NLSFs */
+ doInterpolate = ( psEnc->sCmn.useInterpolatedNLSFs == 1 ) && ( psEncCtrl->sCmn.NLSFInterpCoef_Q2 < ( 1 << 2 ) );
+ if( doInterpolate ) {
+
+ /* Calculate the interpolated NLSF vector for the first half */
+ SKP_Silk_interpolate( pNLSF0_temp_Q15, psEnc->sPred.prev_NLSFq_Q15, pNLSF_Q15,
+ psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sCmn.predictLPCOrder );
+
+ /* Calculate first half NLSF weights for the interpolated NLSFs */
+ TIC(NLSF_weights_FIX)
+ SKP_Silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_Q6, pNLSF0_temp_Q15, psEnc->sCmn.predictLPCOrder );
+ TOC(NLSF_weights_FIX)
+
+ /* Update NLSF weights with contribution from first half */
+ i_sqr_Q15 = SKP_LSHIFT( SKP_SMULBB( psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->sCmn.NLSFInterpCoef_Q2 ), 11 );
+ for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) {
+ pNLSFW_Q6[ i ] = SKP_SMLAWB( SKP_RSHIFT( pNLSFW_Q6[ i ], 1 ), pNLSFW0_temp_Q6[ i ], i_sqr_Q15 );
+ SKP_assert( pNLSFW_Q6[ i ] <= SKP_int16_MAX );
+ SKP_assert( pNLSFW_Q6[ i ] >= 1 );
+ }
+ }
+
+ /* Set pointer to the NLSF codebook for the current signal type and LPC order */
+ psNLSF_CB = psEnc->sCmn.psNLSF_CB[ psEncCtrl->sCmn.sigtype ];
+
+ /* Quantize NLSF parameters given the trained NLSF codebooks */
+ TIC(MSVQ_encode_FIX)
+ SKP_Silk_NLSF_MSVQ_encode_FIX( psEncCtrl->sCmn.NLSFIndices, pNLSF_Q15, psNLSF_CB,
+ psEnc->sPred.prev_NLSFq_Q15, pNLSFW_Q6, NLSF_mu_Q15, NLSF_mu_fluc_red_Q16,
+ psEnc->sCmn.NLSF_MSVQ_Survivors, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.first_frame_after_reset );
+ TOC(MSVQ_encode_FIX)
+
+ /* Convert quantized NLSFs back to LPC coefficients */
+ SKP_Silk_NLSF2A_stable( psEncCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psEnc->sCmn.predictLPCOrder );
+
+ if( doInterpolate ) {
+ /* Calculate the interpolated, quantized LSF vector for the first half */
+ SKP_Silk_interpolate( pNLSF0_temp_Q15, psEnc->sPred.prev_NLSFq_Q15, pNLSF_Q15,
+ psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEnc->sCmn.predictLPCOrder );
+
+ /* Convert back to LPC coefficients */
+ SKP_Silk_NLSF2A_stable( psEncCtrl->PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEnc->sCmn.predictLPCOrder );
+
+ } else {
+ /* Copy LPC coefficients for first half from second half */
+ SKP_memcpy( psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->PredCoef_Q12[ 1 ], psEnc->sCmn.predictLPCOrder * sizeof( SKP_int16 ) );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_process_gains_FIX.c b/pkg/silk/csilk/SKP_Silk_process_gains_FIX.c
new file mode 100644
index 0000000..518152a
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_process_gains_FIX.c
@@ -0,0 +1,108 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/* Processing of gains */
+void SKP_Silk_process_gains_FIX(
+ SKP_Silk_encoder_state_FIX *psEnc, /* I/O Encoder state_FIX */
+ SKP_Silk_encoder_control_FIX *psEncCtrl /* I/O Encoder control_FIX */
+)
+{
+ SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
+ SKP_int k;
+ SKP_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;
+
+ /* Gain reduction when LTP coding gain is high */
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ /*s = -0.5f * SKP_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */
+ s_Q16 = -SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SKP_FIX_CONST( 12.0, 7 ), 4 ) );
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ psEncCtrl->Gains_Q16[ k ] = SKP_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );
+ }
+ }
+
+ /* Limit the quantized signal */
+ InvMaxSqrVal_Q16 = SKP_DIV32_16( SKP_Silk_log2lin(
+ SKP_SMULWB( SKP_FIX_CONST( 70.0, 7 ) - psEncCtrl->current_SNR_dB_Q7, SKP_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length );
+
+ for( k = 0; k < NB_SUBFR; k++ ) {
+ /* Soft limit on ratio residual energy and squared gains */
+ ResNrg = psEncCtrl->ResNrg[ k ];
+ ResNrgPart = SKP_SMULWW( ResNrg, InvMaxSqrVal_Q16 );
+ if( psEncCtrl->ResNrgQ[ k ] > 0 ) {
+ if( psEncCtrl->ResNrgQ[ k ] < 32 ) {
+ ResNrgPart = SKP_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );
+ } else {
+ ResNrgPart = 0;
+ }
+ } else if( psEncCtrl->ResNrgQ[k] != 0 ) {
+ if( ResNrgPart > SKP_RSHIFT( SKP_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {
+ ResNrgPart = SKP_int32_MAX;
+ } else {
+ ResNrgPart = SKP_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );
+ }
+ }
+ gain = psEncCtrl->Gains_Q16[ k ];
+ gain_squared = SKP_ADD_SAT32( ResNrgPart, SKP_SMMUL( gain, gain ) );
+ if( gain_squared < SKP_int16_MAX ) {
+ /* recalculate with higher precision */
+ gain_squared = SKP_SMLAWW( SKP_LSHIFT( ResNrgPart, 16 ), gain, gain );
+ SKP_assert( gain_squared > 0 );
+ gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q8 */
+ psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 8 ); /* Q16 */
+ } else {
+ gain = SKP_Silk_SQRT_APPROX( gain_squared ); /* Q0 */
+ psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( gain, 16 ); /* Q16 */
+ }
+ }
+
+ /* Noise shaping quantization */
+ SKP_Silk_gains_quant( psEncCtrl->sCmn.GainsIndices, psEncCtrl->Gains_Q16,
+ &psShapeSt->LastGainIndex, psEnc->sCmn.nFramesInPayloadBuf );
+ /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
+ if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {
+ if( psEncCtrl->LTPredCodGain_Q7 + SKP_RSHIFT( psEncCtrl->input_tilt_Q15, 8 ) > SKP_FIX_CONST( 1.0, 7 ) ) {
+ psEncCtrl->sCmn.QuantOffsetType = 0;
+ } else {
+ psEncCtrl->sCmn.QuantOffsetType = 1;
+ }
+ }
+
+ /* Quantizer boundary adjustment */
+ quant_offset_Q10 = SKP_Silk_Quantization_Offsets_Q10[ psEncCtrl->sCmn.sigtype ][ psEncCtrl->sCmn.QuantOffsetType ];
+ psEncCtrl->Lambda_Q10 = SKP_FIX_CONST( LAMBDA_OFFSET, 10 )
+ + SKP_SMULBB( SKP_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )
+ + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->speech_activity_Q8 )
+ + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 )
+ + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 )
+ + SKP_SMULWB( SKP_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 );
+
+ SKP_assert( psEncCtrl->Lambda_Q10 > 0 );
+ SKP_assert( psEncCtrl->Lambda_Q10 < SKP_FIX_CONST( 2, 10 ) );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_quant_LTP_gains_FIX.c b/pkg/silk/csilk/SKP_Silk_quant_LTP_gains_FIX.c
new file mode 100644
index 0000000..6caf0ff
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_quant_LTP_gains_FIX.c
@@ -0,0 +1,104 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+void SKP_Silk_quant_LTP_gains_FIX(
+ SKP_int16 B_Q14[], /* I/O (un)quantized LTP gains */
+ SKP_int cbk_index[], /* O Codebook Index */
+ SKP_int *periodicity_index, /* O Periodicity Index */
+ const SKP_int32 W_Q18[], /* I Error Weights in Q18 */
+ SKP_int mu_Q8, /* I Mu value (R/D tradeoff) */
+ SKP_int lowComplexity /* I Flag for low complexity */
+)
+{
+ SKP_int j, k, temp_idx[ NB_SUBFR ], cbk_size;
+ const SKP_int16 *cl_ptr;
+ const SKP_int16 *cbk_ptr_Q14;
+ const SKP_int16 *b_Q14_ptr;
+ const SKP_int32 *W_Q18_ptr;
+ SKP_int32 rate_dist_subfr, rate_dist, min_rate_dist;
+
+
+
+ /***************************************************/
+ /* iterate over different codebooks with different */
+ /* rates/distortions, and choose best */
+ /***************************************************/
+ min_rate_dist = SKP_int32_MAX;
+ for( k = 0; k < 3; k++ ) {
+ cl_ptr = SKP_Silk_LTP_gain_BITS_Q6_ptrs[ k ];
+ cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ k ];
+ cbk_size = SKP_Silk_LTP_vq_sizes[ k ];
+
+ /* Setup pointer to first subframe */
+ W_Q18_ptr = W_Q18;
+ b_Q14_ptr = B_Q14;
+
+ rate_dist = 0;
+ for( j = 0; j < NB_SUBFR; j++ ) {
+
+ SKP_Silk_VQ_WMat_EC_FIX(
+ &temp_idx[ j ], /* O index of best codebook vector */
+ &rate_dist_subfr, /* O best weighted quantization error + mu * rate */
+ b_Q14_ptr, /* I input vector to be quantized */
+ W_Q18_ptr, /* I weighting matrix */
+ cbk_ptr_Q14, /* I codebook */
+ cl_ptr, /* I code length for each codebook vector */
+ mu_Q8, /* I tradeoff between weighted error and rate */
+ cbk_size /* I number of vectors in codebook */
+ );
+
+ rate_dist = SKP_ADD_POS_SAT32( rate_dist, rate_dist_subfr );
+
+ b_Q14_ptr += LTP_ORDER;
+ W_Q18_ptr += LTP_ORDER * LTP_ORDER;
+ }
+
+ /* Avoid never finding a codebook */
+ rate_dist = SKP_min( SKP_int32_MAX - 1, rate_dist );
+
+ if( rate_dist < min_rate_dist ) {
+ min_rate_dist = rate_dist;
+ SKP_memcpy( cbk_index, temp_idx, NB_SUBFR * sizeof( SKP_int ) );
+ *periodicity_index = k;
+ }
+
+ /* Break early in low-complexity mode if rate distortion is below threshold */
+ if( lowComplexity && ( rate_dist < SKP_Silk_LTP_gain_middle_avg_RD_Q14 ) ) {
+ break;
+ }
+ }
+
+ cbk_ptr_Q14 = SKP_Silk_LTP_vq_ptrs_Q14[ *periodicity_index ];
+ for( j = 0; j < NB_SUBFR; j++ ) {
+ for( k = 0; k < LTP_ORDER; k++ ) {
+ B_Q14[ j * LTP_ORDER + k ] = cbk_ptr_Q14[ SKP_MLA( k, cbk_index[ j ], LTP_ORDER ) ];
+ }
+ }
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_range_coder.c b/pkg/silk/csilk/SKP_Silk_range_coder.c
new file mode 100644
index 0000000..45f9ce4
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_range_coder.c
@@ -0,0 +1,372 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* Range encoder for one symbol */
+void SKP_Silk_range_encoder(
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_int data, /* I uncompressed data */
+ const SKP_uint16 prob[] /* I cumulative density functions */
+)
+{
+ SKP_uint32 low_Q16, high_Q16;
+ SKP_uint32 base_tmp, range_Q32;
+
+ /* Copy structure data */
+ SKP_uint32 base_Q32 = psRC->base_Q32;
+ SKP_uint32 range_Q16 = psRC->range_Q16;
+ SKP_int32 bufferIx = psRC->bufferIx;
+ SKP_uint8 *buffer = psRC->buffer;
+
+ if( psRC->error ) {
+ return;
+ }
+
+ /* Update interval */
+ low_Q16 = prob[ data ];
+ high_Q16 = prob[ data + 1 ];
+ base_tmp = base_Q32; /* save current base, to test for carry */
+ base_Q32 += SKP_MUL_uint( range_Q16, low_Q16 );
+ range_Q32 = SKP_MUL_uint( range_Q16, high_Q16 - low_Q16 );
+
+ /* Check for carry */
+ if( base_Q32 < base_tmp ) {
+ /* Propagate carry in buffer */
+ SKP_int bufferIx_tmp = bufferIx;
+ while( ( ++buffer[ --bufferIx_tmp ] ) == 0 );
+ }
+
+ /* Check normalization */
+ if( range_Q32 & 0xFF000000 ) {
+ /* No normalization */
+ range_Q16 = SKP_RSHIFT_uint( range_Q32, 16 );
+ } else {
+ if( range_Q32 & 0xFFFF0000 ) {
+ /* Normalization of 8 bits shift */
+ range_Q16 = SKP_RSHIFT_uint( range_Q32, 8 );
+ } else {
+ /* Normalization of 16 bits shift */
+ range_Q16 = range_Q32;
+ /* Make sure not to write beyond buffer */
+ if( bufferIx >= psRC->bufferLength ) {
+ psRC->error = RANGE_CODER_WRITE_BEYOND_BUFFER;
+ return;
+ }
+ /* Write one byte to buffer */
+ buffer[ bufferIx++ ] = (SKP_uint8)( SKP_RSHIFT_uint( base_Q32, 24 ) );
+ base_Q32 = SKP_LSHIFT_ovflw( base_Q32, 8 );
+ }
+ /* Make sure not to write beyond buffer */
+ if( bufferIx >= psRC->bufferLength ) {
+ psRC->error = RANGE_CODER_WRITE_BEYOND_BUFFER;
+ return;
+ }
+ /* Write one byte to buffer */
+ buffer[ bufferIx++ ] = (SKP_uint8)( SKP_RSHIFT_uint( base_Q32, 24 ) );
+ base_Q32 = SKP_LSHIFT_ovflw( base_Q32, 8 );
+ }
+
+ /* Copy structure data back */
+ psRC->base_Q32 = base_Q32;
+ psRC->range_Q16 = range_Q16;
+ psRC->bufferIx = bufferIx;
+}
+
+/* Range encoder for multiple symbols */
+void SKP_Silk_range_encoder_multi(
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_int data[], /* I uncompressed data [nSymbols] */
+ const SKP_uint16 * const prob[], /* I cumulative density functions */
+ const SKP_int nSymbols /* I number of data symbols */
+)
+{
+ SKP_int k;
+ for( k = 0; k < nSymbols; k++ ) {
+ SKP_Silk_range_encoder( psRC, data[ k ], prob[ k ] );
+ }
+}
+
+/* Range decoder for one symbol */
+void SKP_Silk_range_decoder(
+ SKP_int data[], /* O uncompressed data */
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_uint16 prob[], /* I cumulative density function */
+ SKP_int probIx /* I initial (middle) entry of cdf */
+)
+{
+ SKP_uint32 low_Q16, high_Q16;
+ SKP_uint32 base_tmp, range_Q32;
+
+ /* Copy structure data */
+ SKP_uint32 base_Q32 = psRC->base_Q32;
+ SKP_uint32 range_Q16 = psRC->range_Q16;
+ SKP_int32 bufferIx = psRC->bufferIx;
+ SKP_uint8 *buffer = &psRC->buffer[ 4 ];
+
+ if( psRC->error ) {
+ /* Set output to zero */
+ *data = 0;
+ return;
+ }
+
+ high_Q16 = prob[ probIx ];
+ base_tmp = SKP_MUL_uint( range_Q16, high_Q16 );
+ if( base_tmp > base_Q32 ) {
+ while( 1 ) {
+ low_Q16 = prob[ --probIx ];
+ base_tmp = SKP_MUL_uint( range_Q16, low_Q16 );
+ if( base_tmp <= base_Q32 ) {
+ break;
+ }
+ high_Q16 = low_Q16;
+ /* Test for out of range */
+ if( high_Q16 == 0 ) {
+ psRC->error = RANGE_CODER_CDF_OUT_OF_RANGE;
+ /* Set output to zero */
+ *data = 0;
+ return;
+ }
+ }
+ } else {
+ while( 1 ) {
+ low_Q16 = high_Q16;
+ high_Q16 = prob[ ++probIx ];
+ base_tmp = SKP_MUL_uint( range_Q16, high_Q16 );
+ if( base_tmp > base_Q32 ) {
+ probIx--;
+ break;
+ }
+ /* Test for out of range */
+ if( high_Q16 == 0xFFFF ) {
+ psRC->error = RANGE_CODER_CDF_OUT_OF_RANGE;
+ /* Set output to zero */
+ *data = 0;
+ return;
+ }
+ }
+ }
+ *data = probIx;
+ base_Q32 -= SKP_MUL_uint( range_Q16, low_Q16 );
+ range_Q32 = SKP_MUL_uint( range_Q16, high_Q16 - low_Q16 );
+
+ /* Check normalization */
+ if( range_Q32 & 0xFF000000 ) {
+ /* No normalization */
+ range_Q16 = SKP_RSHIFT_uint( range_Q32, 16 );
+ } else {
+ if( range_Q32 & 0xFFFF0000 ) {
+ /* Normalization of 8 bits shift */
+ range_Q16 = SKP_RSHIFT_uint( range_Q32, 8 );
+ /* Check for errors */
+ if( SKP_RSHIFT_uint( base_Q32, 24 ) ) {
+ psRC->error = RANGE_CODER_NORMALIZATION_FAILED;
+ /* Set output to zero */
+ *data = 0;
+ return;
+ }
+ } else {
+ /* Normalization of 16 bits shift */
+ range_Q16 = range_Q32;
+ /* Check for errors */
+ if( SKP_RSHIFT( base_Q32, 16 ) ) {
+ psRC->error = RANGE_CODER_NORMALIZATION_FAILED;
+ /* Set output to zero */
+ *data = 0;
+ return;
+ }
+ /* Update base */
+ base_Q32 = SKP_LSHIFT_uint( base_Q32, 8 );
+ /* Make sure not to read beyond buffer */
+ if( bufferIx < psRC->bufferLength ) {
+ /* Read one byte from buffer */
+ base_Q32 |= (SKP_uint32)buffer[ bufferIx++ ];
+ }
+ }
+ /* Update base */
+ base_Q32 = SKP_LSHIFT_uint( base_Q32, 8 );
+ /* Make sure not to read beyond buffer */
+ if( bufferIx < psRC->bufferLength ) {
+ /* Read one byte from buffer */
+ base_Q32 |= (SKP_uint32)buffer[ bufferIx++ ];
+ }
+ }
+
+ /* Check for zero interval length */
+ if( range_Q16 == 0 ) {
+ psRC->error = RANGE_CODER_ZERO_INTERVAL_WIDTH;
+ /* Set output to zero */
+ *data = 0;
+ return;
+ }
+
+ /* Copy structure data back */
+ psRC->base_Q32 = base_Q32;
+ psRC->range_Q16 = range_Q16;
+ psRC->bufferIx = bufferIx;
+}
+
+/* Range decoder for multiple symbols */
+void SKP_Silk_range_decoder_multi(
+ SKP_int data[], /* O uncompressed data [nSymbols] */
+ SKP_Silk_range_coder_state *psRC, /* I/O compressor data structure */
+ const SKP_uint16 * const prob[], /* I cumulative density functions */
+ const SKP_int probStartIx[], /* I initial (middle) entries of cdfs [nSymbols] */
+ const SKP_int nSymbols /* I number of data symbols */
+)
+{
+ SKP_int k;
+ for( k = 0; k < nSymbols; k++ ) {
+ SKP_Silk_range_decoder( &data[ k ], psRC, prob[ k ], probStartIx[ k ] );
+ }
+}
+
+/* Initialize range encoder */
+void SKP_Silk_range_enc_init(
+ SKP_Silk_range_coder_state *psRC /* O compressor data structure */
+)
+{
+ /* Initialize structure */
+ psRC->bufferLength = MAX_ARITHM_BYTES;
+ psRC->range_Q16 = 0x0000FFFF;
+ psRC->bufferIx = 0;
+ psRC->base_Q32 = 0;
+ psRC->error = 0;
+}
+
+/* Initialize range decoder */
+void SKP_Silk_range_dec_init(
+ SKP_Silk_range_coder_state *psRC, /* O compressor data structure */
+ const SKP_uint8 buffer[], /* I buffer for compressed data [bufferLength] */
+ const SKP_int32 bufferLength /* I buffer length (in bytes) */
+)
+{
+ /* check input */
+ if( ( bufferLength > MAX_ARITHM_BYTES ) || ( bufferLength < 0 ) ) {
+ psRC->error = RANGE_CODER_DEC_PAYLOAD_TOO_LONG;
+ return;
+ }
+ /* Initialize structure */
+ /* Copy to internal buffer */
+ SKP_memcpy( psRC->buffer, buffer, bufferLength * sizeof( SKP_uint8 ) );
+ psRC->bufferLength = bufferLength;
+ psRC->bufferIx = 0;
+ psRC->base_Q32 =
+ SKP_LSHIFT_uint( (SKP_uint32)buffer[ 0 ], 24 ) |
+ SKP_LSHIFT_uint( (SKP_uint32)buffer[ 1 ], 16 ) |
+ SKP_LSHIFT_uint( (SKP_uint32)buffer[ 2 ], 8 ) |
+ (SKP_uint32)buffer[ 3 ];
+ psRC->range_Q16 = 0x0000FFFF;
+ psRC->error = 0;
+}
+
+/* Determine length of bitstream */
+SKP_int SKP_Silk_range_coder_get_length( /* O returns number of BITS in stream */
+ const SKP_Silk_range_coder_state *psRC, /* I compressed data structure */
+ SKP_int *nBytes /* O number of BYTES in stream */
+)
+{
+ SKP_int nBits;
+
+ /* Number of bits in stream */
+ nBits = SKP_LSHIFT( psRC->bufferIx, 3 ) + SKP_Silk_CLZ32( psRC->range_Q16 - 1 ) - 14;
+
+ *nBytes = SKP_RSHIFT( nBits + 7, 3 );
+
+ /* Return number of bits in bitstream */
+ return nBits;
+}
+
+/* Write shortest uniquely decodable stream to buffer, and determine its length */
+void SKP_Silk_range_enc_wrap_up(
+ SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */
+)
+{
+ SKP_int bufferIx_tmp, bits_to_store, bits_in_stream, nBytes, mask;
+ SKP_uint32 base_Q24;
+
+ /* Lower limit of interval, shifted 8 bits to the right */
+ base_Q24 = SKP_RSHIFT_uint( psRC->base_Q32, 8 );
+
+ bits_in_stream = SKP_Silk_range_coder_get_length( psRC, &nBytes );
+
+ /* Number of additional bits (1..9) required to be stored to stream */
+ bits_to_store = bits_in_stream - SKP_LSHIFT( psRC->bufferIx, 3 );
+ /* Round up to required resolution */
+ base_Q24 += SKP_RSHIFT_uint( 0x00800000, bits_to_store - 1 );
+ base_Q24 &= SKP_LSHIFT_ovflw( 0xFFFFFFFF, 24 - bits_to_store );
+
+ /* Check for carry */
+ if( base_Q24 & 0x01000000 ) {
+ /* Propagate carry in buffer */
+ bufferIx_tmp = psRC->bufferIx;
+ while( ( ++( psRC->buffer[ --bufferIx_tmp ] ) ) == 0 );
+ }
+
+ /* Store to stream, making sure not to write beyond buffer */
+ if( psRC->bufferIx < psRC->bufferLength ) {
+ psRC->buffer[ psRC->bufferIx++ ] = (SKP_uint8)SKP_RSHIFT_uint( base_Q24, 16 );
+ if( bits_to_store > 8 ) {
+ if( psRC->bufferIx < psRC->bufferLength ) {
+ psRC->buffer[ psRC->bufferIx++ ] = (SKP_uint8)SKP_RSHIFT_uint( base_Q24, 8 );
+ }
+ }
+ }
+
+ /* Fill up any remaining bits in the last byte with 1s */
+ if( bits_in_stream & 7 ) {
+ mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );
+ if( nBytes - 1 < psRC->bufferLength ) {
+ psRC->buffer[ nBytes - 1 ] |= mask;
+ }
+ }
+}
+
+/* Check that any remaining bits in the last byte are set to 1 */
+void SKP_Silk_range_coder_check_after_decoding(
+ SKP_Silk_range_coder_state *psRC /* I/O compressed data structure */
+)
+{
+ SKP_int bits_in_stream, nBytes, mask;
+
+ bits_in_stream = SKP_Silk_range_coder_get_length( psRC, &nBytes );
+
+ /* Make sure not to read beyond buffer */
+ if( nBytes - 1 >= psRC->bufferLength ) {
+ psRC->error = RANGE_CODER_DECODER_CHECK_FAILED;
+ return;
+ }
+
+ /* Test any remaining bits in last byte */
+ if( bits_in_stream & 7 ) {
+ mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );
+ if( ( psRC->buffer[ nBytes - 1 ] & mask ) != mask ) {
+ psRC->error = RANGE_CODER_DECODER_CHECK_FAILED;
+ return;
+ }
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_regularize_correlations_FIX.c b/pkg/silk/csilk/SKP_Silk_regularize_correlations_FIX.c
new file mode 100644
index 0000000..e2700ac
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_regularize_correlations_FIX.c
@@ -0,0 +1,43 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/* Add noise to matrix diagonal */
+void SKP_Silk_regularize_correlations_FIX(
+ SKP_int32 *XX, /* I/O Correlation matrices */
+ SKP_int32 *xx, /* I/O Correlation values */
+ SKP_int32 noise, /* I Noise to add */
+ SKP_int D /* I Dimension of XX */
+)
+{
+ SKP_int i;
+ for( i = 0; i < D; i++ ) {
+ matrix_ptr( &XX[ 0 ], i, i, D ) = SKP_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );
+ }
+ xx[ 0 ] += noise;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler.c b/pkg/silk/csilk/SKP_Silk_resampler.c
new file mode 100644
index 0000000..c3d25e5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler.c
@@ -0,0 +1,323 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resampler.c *
+ * *
+ * Description: Interface to collection of resamplers *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * All rights reserved. *
+ * */
+
+/* Matrix of resampling methods used:
+ * Fs_out (kHz)
+ * 8 12 16 24 32 44.1 48
+ *
+ * 8 C UF U UF UF UF UF
+ * 12 AF C UF U UF UF UF
+ * 16 D AF C UF U UF UF
+ * Fs_in (kHz) 24 AIF D AF C UF UF U
+ * 32 UF AF D AF C UF UF
+ * 44.1 AMI AMI AMI AMI AMI C UF
+ * 48 DAF DAF AF D AF UF C
+ *
+ * default method: UF
+ *
+ * C -> Copy (no resampling)
+ * D -> Allpass-based 2x downsampling
+ * U -> Allpass-based 2x upsampling
+ * DAF -> Allpass-based 2x downsampling followed by AR2 filter followed by FIR interpolation
+ * UF -> Allpass-based 2x upsampling followed by FIR interpolation
+ * AMI -> ARMA4 filter followed by FIR interpolation
+ * AF -> AR2 filter followed by FIR interpolation
+ *
+ * Input signals sampled above 48 kHz are first downsampled to at most 48 kHz.
+ * Output signals sampled above 48 kHz are upsampled from at most 48 kHz.
+ */
+
+#include "SKP_Silk_resampler_private.h"
+
+/* Greatest common divisor */
+static SKP_int32 gcd(
+ SKP_int32 a,
+ SKP_int32 b
+)
+{
+ SKP_int32 tmp;
+ while( b > 0 ) {
+ tmp = a - b * SKP_DIV32( a, b );
+ a = b;
+ b = tmp;
+ }
+ return a;
+}
+
+/* Initialize/reset the resampler state for a given pair of input/output sampling rates */
+SKP_int SKP_Silk_resampler_init(
+ SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
+ SKP_int32 Fs_Hz_in, /* I: Input sampling rate (Hz) */
+ SKP_int32 Fs_Hz_out /* I: Output sampling rate (Hz) */
+)
+{
+ SKP_int32 cycleLen, cyclesPerBatch, up2 = 0, down2 = 0;
+
+ /* Clear state */
+ SKP_memset( S, 0, sizeof( SKP_Silk_resampler_state_struct ) );
+
+ /* Input checking */
+#if RESAMPLER_SUPPORT_ABOVE_48KHZ
+ if( Fs_Hz_in < 8000 || Fs_Hz_in > 192000 || Fs_Hz_out < 8000 || Fs_Hz_out > 192000 ) {
+#else
+ if( Fs_Hz_in < 8000 || Fs_Hz_in > 48000 || Fs_Hz_out < 8000 || Fs_Hz_out > 48000 ) {
+#endif
+ SKP_assert( 0 );
+ return -1;
+ }
+
+#if RESAMPLER_SUPPORT_ABOVE_48KHZ
+ /* Determine pre downsampling and post upsampling */
+ if( Fs_Hz_in > 96000 ) {
+ S->nPreDownsamplers = 2;
+ S->down_pre_function = SKP_Silk_resampler_private_down4;
+ } else if( Fs_Hz_in > 48000 ) {
+ S->nPreDownsamplers = 1;
+ S->down_pre_function = SKP_Silk_resampler_down2;
+ } else {
+ S->nPreDownsamplers = 0;
+ S->down_pre_function = NULL;
+ }
+
+ if( Fs_Hz_out > 96000 ) {
+ S->nPostUpsamplers = 2;
+ S->up_post_function = SKP_Silk_resampler_private_up4;
+ } else if( Fs_Hz_out > 48000 ) {
+ S->nPostUpsamplers = 1;
+ S->up_post_function = SKP_Silk_resampler_up2;
+ } else {
+ S->nPostUpsamplers = 0;
+ S->up_post_function = NULL;
+ }
+
+ if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) {
+ /* Ratio of output/input samples */
+ S->ratio_Q16 = SKP_LSHIFT32( SKP_DIV32( SKP_LSHIFT32( Fs_Hz_out, 13 ), Fs_Hz_in ), 3 );
+ /* Make sure the ratio is rounded up */
+ while( SKP_SMULWW( S->ratio_Q16, Fs_Hz_in ) < Fs_Hz_out ) S->ratio_Q16++;
+
+ /* Batch size is 10 ms */
+ S->batchSizePrePost = SKP_DIV32_16( Fs_Hz_in, 100 );
+
+ /* Convert sampling rate to those after pre-downsampling and before post-upsampling */
+ Fs_Hz_in = SKP_RSHIFT( Fs_Hz_in, S->nPreDownsamplers );
+ Fs_Hz_out = SKP_RSHIFT( Fs_Hz_out, S->nPostUpsamplers );
+ }
+#endif
+
+ /* Number of samples processed per batch */
+ /* First, try 10 ms frames */
+ S->batchSize = SKP_DIV32_16( Fs_Hz_in, 100 );
+ if( ( SKP_MUL( S->batchSize, 100 ) != Fs_Hz_in ) || ( Fs_Hz_in % 100 != 0 ) ) {
+ /* No integer number of input or output samples with 10 ms frames, use greatest common divisor */
+ cycleLen = SKP_DIV32( Fs_Hz_in, gcd( Fs_Hz_in, Fs_Hz_out ) );
+ cyclesPerBatch = SKP_DIV32( RESAMPLER_MAX_BATCH_SIZE_IN, cycleLen );
+ if( cyclesPerBatch == 0 ) {
+ /* cycleLen too big, let's just use the maximum batch size. Some distortion will result. */
+ S->batchSize = RESAMPLER_MAX_BATCH_SIZE_IN;
+ SKP_assert( 0 );
+ } else {
+ S->batchSize = SKP_MUL( cyclesPerBatch, cycleLen );
+ }
+ }
+
+
+ /* Find resampler with the right sampling ratio */
+ if( Fs_Hz_out > Fs_Hz_in ) {
+ /* Upsample */
+ if( Fs_Hz_out == SKP_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */
+ /* Special case: directly use 2x upsampler */
+ S->resampler_function = SKP_Silk_resampler_private_up2_HQ_wrapper;
+ } else {
+ /* Default resampler */
+ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR;
+ up2 = 1;
+ if( Fs_Hz_in > 24000 ) {
+ /* Low-quality all-pass upsampler */
+ S->up2_function = SKP_Silk_resampler_up2;
+ } else {
+ /* High-quality all-pass upsampler */
+ S->up2_function = SKP_Silk_resampler_private_up2_HQ;
+ }
+ }
+ } else if ( Fs_Hz_out < Fs_Hz_in ) {
+ /* Downsample */
+ if( SKP_MUL( Fs_Hz_out, 4 ) == SKP_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */
+ S->FIR_Fracs = 3;
+ S->Coefs = SKP_Silk_Resampler_3_4_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_down_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 3 ) == SKP_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */
+ S->FIR_Fracs = 2;
+ S->Coefs = SKP_Silk_Resampler_2_3_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_down_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */
+ S->FIR_Fracs = 1;
+ S->Coefs = SKP_Silk_Resampler_1_2_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_down_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 8 ) == SKP_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 8 */
+ S->FIR_Fracs = 3;
+ S->Coefs = SKP_Silk_Resampler_3_8_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_down_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */
+ S->FIR_Fracs = 1;
+ S->Coefs = SKP_Silk_Resampler_1_3_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_down_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */
+ S->FIR_Fracs = 1;
+ down2 = 1;
+ S->Coefs = SKP_Silk_Resampler_1_2_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_down_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */
+ S->FIR_Fracs = 1;
+ down2 = 1;
+ S->Coefs = SKP_Silk_Resampler_1_3_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_down_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 80 ) ) { /* Fs_out : Fs_in = 80 : 441 */
+ S->Coefs = SKP_Silk_Resampler_80_441_ARMA4_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 120 ) ) { /* Fs_out : Fs_in = 120 : 441 */
+ S->Coefs = SKP_Silk_Resampler_120_441_ARMA4_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 160 ) ) { /* Fs_out : Fs_in = 160 : 441 */
+ S->Coefs = SKP_Silk_Resampler_160_441_ARMA4_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 240 ) ) { /* Fs_out : Fs_in = 240 : 441 */
+ S->Coefs = SKP_Silk_Resampler_240_441_ARMA4_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR;
+ } else if( SKP_MUL( Fs_Hz_out, 441 ) == SKP_MUL( Fs_Hz_in, 320 ) ) { /* Fs_out : Fs_in = 320 : 441 */
+ S->Coefs = SKP_Silk_Resampler_320_441_ARMA4_COEFS;
+ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR;
+ } else {
+ /* Default resampler */
+ S->resampler_function = SKP_Silk_resampler_private_IIR_FIR;
+ up2 = 1;
+ if( Fs_Hz_in > 24000 ) {
+ /* Low-quality all-pass upsampler */
+ S->up2_function = SKP_Silk_resampler_up2;
+ } else {
+ /* High-quality all-pass upsampler */
+ S->up2_function = SKP_Silk_resampler_private_up2_HQ;
+ }
+ }
+ } else {
+ /* Input and output sampling rates are equal: copy */
+ S->resampler_function = SKP_Silk_resampler_private_copy;
+ }
+
+ S->input2x = up2 | down2;
+
+ /* Ratio of input/output samples */
+ S->invRatio_Q16 = SKP_LSHIFT32( SKP_DIV32( SKP_LSHIFT32( Fs_Hz_in, 14 + up2 - down2 ), Fs_Hz_out ), 2 );
+ /* Make sure the ratio is rounded up */
+ while( SKP_SMULWW( S->invRatio_Q16, SKP_LSHIFT32( Fs_Hz_out, down2 ) ) < SKP_LSHIFT32( Fs_Hz_in, up2 ) ) {
+ S->invRatio_Q16++;
+ }
+
+ S->magic_number = 123456789;
+
+ return 0;
+}
+
+/* Clear the states of all resampling filters, without resetting sampling rate ratio */
+SKP_int SKP_Silk_resampler_clear(
+ SKP_Silk_resampler_state_struct *S /* I/O: Resampler state */
+)
+{
+ /* Clear state */
+ SKP_memset( S->sDown2, 0, sizeof( S->sDown2 ) );
+ SKP_memset( S->sIIR, 0, sizeof( S->sIIR ) );
+ SKP_memset( S->sFIR, 0, sizeof( S->sFIR ) );
+#if RESAMPLER_SUPPORT_ABOVE_48KHZ
+ SKP_memset( S->sDownPre, 0, sizeof( S->sDownPre ) );
+ SKP_memset( S->sUpPost, 0, sizeof( S->sUpPost ) );
+#endif
+ return 0;
+}
+
+/* Resampler: convert from one sampling rate to another */
+SKP_int SKP_Silk_resampler(
+ SKP_Silk_resampler_state_struct *S, /* I/O: Resampler state */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ /* Verify that state was initialized and has not been corrupted */
+ if( S->magic_number != 123456789 ) {
+ SKP_assert( 0 );
+ return -1;
+ }
+
+#if RESAMPLER_SUPPORT_ABOVE_48KHZ
+ if( S->nPreDownsamplers + S->nPostUpsamplers > 0 ) {
+ /* The input and/or output sampling rate is above 48000 Hz */
+ SKP_int32 nSamplesIn, nSamplesOut;
+ SKP_int16 in_buf[ 480 ], out_buf[ 480 ];
+
+ while( inLen > 0 ) {
+ /* Number of input and output samples to process */
+ nSamplesIn = SKP_min( inLen, S->batchSizePrePost );
+ nSamplesOut = SKP_SMULWB( S->ratio_Q16, nSamplesIn );
+
+ SKP_assert( SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) <= 480 );
+ SKP_assert( SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) <= 480 );
+
+ if( S->nPreDownsamplers > 0 ) {
+ S->down_pre_function( S->sDownPre, in_buf, in, nSamplesIn );
+ if( S->nPostUpsamplers > 0 ) {
+ S->resampler_function( S, out_buf, in_buf, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) );
+ S->up_post_function( S->sUpPost, out, out_buf, SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) );
+ } else {
+ S->resampler_function( S, out, in_buf, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) );
+ }
+ } else {
+ S->resampler_function( S, out_buf, in, SKP_RSHIFT32( nSamplesIn, S->nPreDownsamplers ) );
+ S->up_post_function( S->sUpPost, out, out_buf, SKP_RSHIFT32( nSamplesOut, S->nPostUpsamplers ) );
+ }
+
+ in += nSamplesIn;
+ out += nSamplesOut;
+ inLen -= nSamplesIn;
+ }
+ } else
+#endif
+ {
+ /* Input and output sampling rate are at most 48000 Hz */
+ S->resampler_function( S, out, in, inLen );
+ }
+
+ return 0;
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_down2.c b/pkg/silk/csilk/SKP_Silk_resampler_down2.c
new file mode 100644
index 0000000..fedba1f
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_down2.c
@@ -0,0 +1,79 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_down2.c *
+ * *
+ * Downsample by a factor 2, mediocre quality *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_rom.h"
+
+#if (EMBEDDED_ARM<5)
+/* Downsample by a factor 2, mediocre quality */
+void SKP_Silk_resampler_down2(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ len ] */
+ const SKP_int16 *in, /* I: Input signal [ floor(len/2) ] */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ SKP_int32 k, len2 = SKP_RSHIFT32( inLen, 1 );
+ SKP_int32 in32, out32, Y, X;
+
+ SKP_assert( SKP_Silk_resampler_down2_0 > 0 );
+ SKP_assert( SKP_Silk_resampler_down2_1 < 0 );
+
+ /* Internal variables and state are in Q10 format */
+ for( k = 0; k < len2; k++ ) {
+ /* Convert to Q10 */
+ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k ], 10 );
+
+ /* All-pass section for even input sample */
+ Y = SKP_SUB32( in32, S[ 0 ] );
+ X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_down2_1 );
+ out32 = SKP_ADD32( S[ 0 ], X );
+ S[ 0 ] = SKP_ADD32( in32, X );
+
+ /* Convert to Q10 */
+ in32 = SKP_LSHIFT( (SKP_int32)in[ 2 * k + 1 ], 10 );
+
+ /* All-pass section for odd input sample, and add to output of previous section */
+ Y = SKP_SUB32( in32, S[ 1 ] );
+ X = SKP_SMULWB( Y, SKP_Silk_resampler_down2_0 );
+ out32 = SKP_ADD32( out32, S[ 1 ] );
+ out32 = SKP_ADD32( out32, X );
+ S[ 1 ] = SKP_ADD32( in32, X );
+
+ /* Add, convert back to int16 and store to output */
+ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 11 ) );
+ }
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_down2_3.c b/pkg/silk/csilk/SKP_Silk_resampler_down2_3.c
new file mode 100644
index 0000000..59ecc7c
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_down2_3.c
@@ -0,0 +1,103 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_down2_3.c *
+ * *
+ * Downsample by a factor 2/3, low quality *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+#undef ORDER_FIR
+#define ORDER_FIR 4
+
+/* Downsample by a factor 2/3, low quality */
+void SKP_Silk_resampler_down2_3(
+ SKP_int32 *S, /* I/O: State vector [ 6 ] */
+ SKP_int16 *out, /* O: Output signal [ floor(2*inLen/3) ] */
+ const SKP_int16 *in, /* I: Input signal [ inLen ] */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ SKP_int32 nSamplesIn, counter, res_Q6;
+ SKP_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ];
+ SKP_int32 *buf_ptr;
+
+ /* Copy buffered samples to start of buffer */
+ SKP_memcpy( buf, S, ORDER_FIR * sizeof( SKP_int32 ) );
+
+ /* Iterate over blocks of frameSizeIn input samples */
+ while( 1 ) {
+ nSamplesIn = SKP_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN );
+
+ /* Second-order AR filter (output in Q8) */
+ SKP_Silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in,
+ SKP_Silk_Resampler_2_3_COEFS_LQ, nSamplesIn );
+
+ /* Interpolate filtered signal */
+ buf_ptr = buf;
+ counter = nSamplesIn;
+ while( counter > 2 ) {
+ /* Inner product */
+ res_Q6 = SKP_SMULWB( buf_ptr[ 0 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 1 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] );
+
+ /* Scale down, saturate and store in output array */
+ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) );
+
+ res_Q6 = SKP_SMULWB( buf_ptr[ 1 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 4 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 5 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 3 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 4 ], SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 ] );
+
+ /* Scale down, saturate and store in output array */
+ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) );
+
+ buf_ptr += 3;
+ counter -= 3;
+ }
+
+ in += nSamplesIn;
+ inLen -= nSamplesIn;
+
+ if( inLen > 0 ) {
+ /* More iterations to do; copy last part of filtered signal to beginning of buffer */
+ SKP_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) );
+ } else {
+ break;
+ }
+ }
+
+ /* Copy last part of filtered signal to the state for the next call */
+ SKP_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_down3.c b/pkg/silk/csilk/SKP_Silk_resampler_down3.c
new file mode 100644
index 0000000..2cc601e
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_down3.c
@@ -0,0 +1,94 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_down3.c *
+ * *
+ * Downsample by a factor 3, low quality *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+#undef ORDER_FIR
+#define ORDER_FIR 6
+
+/* Downsample by a factor 3, low quality */
+void SKP_Silk_resampler_down3(
+ SKP_int32 *S, /* I/O: State vector [ 8 ] */
+ SKP_int16 *out, /* O: Output signal [ floor(inLen/3) ] */
+ const SKP_int16 *in, /* I: Input signal [ inLen ] */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ SKP_int32 nSamplesIn, counter, res_Q6;
+ SKP_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ];
+ SKP_int32 *buf_ptr;
+
+ /* Copy buffered samples to start of buffer */
+ SKP_memcpy( buf, S, ORDER_FIR * sizeof( SKP_int32 ) );
+
+ /* Iterate over blocks of frameSizeIn input samples */
+ while( 1 ) {
+ nSamplesIn = SKP_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN );
+
+ /* Second-order AR filter (output in Q8) */
+ SKP_Silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in,
+ SKP_Silk_Resampler_1_3_COEFS_LQ, nSamplesIn );
+
+ /* Interpolate filtered signal */
+ buf_ptr = buf;
+ counter = nSamplesIn;
+ while( counter > 2 ) {
+ /* Inner product */
+ res_Q6 = SKP_SMULWB( SKP_ADD32( buf_ptr[ 0 ], buf_ptr[ 5 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 1 ], buf_ptr[ 4 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 3 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 2 ], buf_ptr[ 3 ] ), SKP_Silk_Resampler_1_3_COEFS_LQ[ 4 ] );
+
+ /* Scale down, saturate and store in output array */
+ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) );
+
+ buf_ptr += 3;
+ counter -= 3;
+ }
+
+ in += nSamplesIn;
+ inLen -= nSamplesIn;
+
+ if( inLen > 0 ) {
+ /* More iterations to do; copy last part of filtered signal to beginning of buffer */
+ SKP_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) );
+ } else {
+ break;
+ }
+ }
+
+ /* Copy last part of filtered signal to the state for the next call */
+ SKP_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( SKP_int32 ) );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private.h b/pkg/silk/csilk/SKP_Silk_resampler_private.h
new file mode 100644
index 0000000..04563fa
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private.h
@@ -0,0 +1,131 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resampler_structs.h *
+ * *
+ * Description: Structs for IIR/FIR resamplers *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * All rights reserved. *
+ * *
+ * */
+
+#ifndef SKP_Silk_RESAMPLER_H
+#define SKP_Silk_RESAMPLER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_structs.h"
+#include "SKP_Silk_resampler_rom.h"
+
+/* Number of input samples to process in the inner loop */
+#define RESAMPLER_MAX_BATCH_SIZE_IN 480
+
+/* Description: Hybrid IIR/FIR polyphase implementation of resampling */
+void SKP_Silk_resampler_private_IIR_FIR(
+ void *SS, /* I/O: Resampler state */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+/* Description: Hybrid IIR/FIR polyphase implementation of resampling */
+void SKP_Silk_resampler_private_down_FIR(
+ void *SS, /* I/O: Resampler state */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+/* Copy */
+void SKP_Silk_resampler_private_copy(
+ void *SS, /* I/O: Resampler state (unused) */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+/* Upsample by a factor 2, high quality */
+void SKP_Silk_resampler_private_up2_HQ_wrapper(
+ void *SS, /* I/O: Resampler state (unused) */
+ SKP_int16 *out, /* O: Output signal [ 2 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of input samples */
+);
+
+/* Upsample by a factor 2, high quality */
+void SKP_Silk_resampler_private_up2_HQ(
+ SKP_int32 *S, /* I/O: Resampler state [ 6 ] */
+ SKP_int16 *out, /* O: Output signal [ 2 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of input samples */
+);
+
+/* Upsample 4x, low quality */
+void SKP_Silk_resampler_private_up4(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ 4 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of input samples */
+);
+
+/* Downsample 4x, low quality */
+void SKP_Silk_resampler_private_down4(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ floor(len/2) ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 inLen /* I: Number of input samples */
+);
+
+/* Second order AR filter */
+void SKP_Silk_resampler_private_AR2(
+ SKP_int32 S[], /* I/O: State vector [ 2 ] */
+ SKP_int32 out_Q8[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ const SKP_int16 A_Q14[], /* I: AR coefficients, Q14 */
+ SKP_int32 len /* I: Signal length */
+);
+
+/* Fourth order ARMA filter */
+void SKP_Silk_resampler_private_ARMA4(
+ SKP_int32 S[], /* I/O: State vector [ 4 ] */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ const SKP_int16 Coef[], /* I: ARMA coefficients [ 7 ] */
+ SKP_int32 len /* I: Signal length */
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif // SKP_Silk_RESAMPLER_H
+
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_AR2.c b/pkg/silk/csilk/SKP_Silk_resampler_private_AR2.c
new file mode 100644
index 0000000..5d581a4
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_AR2.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_private_AR2. c *
+ * *
+ * Second order AR filter with single delay elements *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+#if (EMBEDDED_ARM<5)
+/* Second order AR filter with single delay elements */
+void SKP_Silk_resampler_private_AR2(
+ SKP_int32 S[], /* I/O: State vector [ 2 ] */
+ SKP_int32 out_Q8[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ const SKP_int16 A_Q14[], /* I: AR coefficients, Q14 */
+ SKP_int32 len /* I: Signal length */
+)
+{
+ SKP_int32 k;
+ SKP_int32 out32;
+
+ for( k = 0; k < len; k++ ) {
+ out32 = SKP_ADD_LSHIFT32( S[ 0 ], (SKP_int32)in[ k ], 8 );
+ out_Q8[ k ] = out32;
+ out32 = SKP_LSHIFT( out32, 2 );
+ S[ 0 ] = SKP_SMLAWB( S[ 1 ], out32, A_Q14[ 0 ] );
+ S[ 1 ] = SKP_SMULWB( out32, A_Q14[ 1 ] );
+ }
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_ARMA4.c b/pkg/silk/csilk/SKP_Silk_resampler_private_ARMA4.c
new file mode 100644
index 0000000..4351592
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_ARMA4.c
@@ -0,0 +1,79 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_private_ARMA4.c *
+ * *
+ * Fourth order ARMA filter, applies 64x gain *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+/* Fourth order ARMA filter */
+/* Internally operates as two biquad filters in sequence. */
+
+/* Coeffients are stored in a packed format: */
+/* { B1_Q14[1], B2_Q14[1], -A1_Q14[1], -A1_Q14[2], -A2_Q14[1], -A2_Q14[2], gain_Q16 } */
+/* where it is assumed that B*_Q14[0], B*_Q14[2], A*_Q14[0] are all 16384 */
+#if (EMBEDDED_ARM<5)
+void SKP_Silk_resampler_private_ARMA4(
+ SKP_int32 S[], /* I/O: State vector [ 4 ] */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ const SKP_int16 Coef[], /* I: ARMA coefficients [ 7 ] */
+ SKP_int32 len /* I: Signal length */
+)
+{
+ SKP_int32 k;
+ SKP_int32 in_Q8, out1_Q8, out2_Q8, X;
+
+ for( k = 0; k < len; k++ ) {
+ in_Q8 = SKP_LSHIFT32( (SKP_int32)in[ k ], 8 );
+
+ /* Outputs of first and second biquad */
+ out1_Q8 = SKP_ADD_LSHIFT32( in_Q8, S[ 0 ], 2 );
+ out2_Q8 = SKP_ADD_LSHIFT32( out1_Q8, S[ 2 ], 2 );
+
+ /* Update states, which are stored in Q6. Coefficients are in Q14 here */
+ X = SKP_SMLAWB( S[ 1 ], in_Q8, Coef[ 0 ] );
+ S[ 0 ] = SKP_SMLAWB( X, out1_Q8, Coef[ 2 ] );
+
+ X = SKP_SMLAWB( S[ 3 ], out1_Q8, Coef[ 1 ] );
+ S[ 2 ] = SKP_SMLAWB( X, out2_Q8, Coef[ 4 ] );
+
+ S[ 1 ] = SKP_SMLAWB( SKP_RSHIFT32( in_Q8, 2 ), out1_Q8, Coef[ 3 ] );
+ S[ 3 ] = SKP_SMLAWB( SKP_RSHIFT32( out1_Q8, 2 ), out2_Q8, Coef[ 5 ] );
+
+ /* Apply gain and store to output. The coefficient is in Q16 */
+ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32( SKP_SMLAWB( 128, out2_Q8, Coef[ 6 ] ), 8 ) );
+ }
+}
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_IIR_FIR.c b/pkg/silk/csilk/SKP_Silk_resampler_private_IIR_FIR.c
new file mode 100644
index 0000000..0976451
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_IIR_FIR.c
@@ -0,0 +1,110 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resampler_private_IIR_FIR.c *
+ * *
+ * Description: Hybrid IIR/FIR polyphase implementation of resampling *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * All rights reserved. *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+#if EMBEDDED_ARM<5
+SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_IIR_FIR_INTERPOL(
+ SKP_int16 * out, SKP_int16 * buf, SKP_int32 max_index_Q16 , SKP_int32 index_increment_Q16 ){
+ SKP_int32 index_Q16, res_Q15;
+ SKP_int16 *buf_ptr;
+ SKP_int32 table_index;
+ /* Interpolate upsampled signal and store in output array */
+ for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
+ table_index = SKP_SMULWB( index_Q16 & 0xFFFF, 144 );
+ buf_ptr = &buf[ index_Q16 >> 16 ];
+
+ res_Q15 = SKP_SMULBB( buf_ptr[ 0 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 0 ] );
+ res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 1 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 1 ] );
+ res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 2 ], SKP_Silk_resampler_frac_FIR_144[ table_index ][ 2 ] );
+ res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 3 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 2 ] );
+ res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 4 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 1 ] );
+ res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 5 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 0 ] );
+ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q15, 15 ) );
+ }
+ return out;
+}
+#else
+extern SKP_int16 *SKP_Silk_resampler_private_IIR_FIR_INTERPOL(
+ SKP_int16 * out, SKP_int16 * buf, SKP_int32 max_index_Q16 , SKP_int32 index_increment_Q16 );
+#endif
+/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */
+void SKP_Silk_resampler_private_IIR_FIR(
+ void *SS, /* I/O: Resampler state */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS;
+ SKP_int32 nSamplesIn;
+ SKP_int32 max_index_Q16, index_increment_Q16;
+ SKP_int16 buf[ 2 * RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_144 ];
+
+
+ /* Copy buffered samples to start of buffer */
+ SKP_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) );
+
+ /* Iterate over blocks of frameSizeIn input samples */
+ index_increment_Q16 = S->invRatio_Q16;
+ while( 1 ) {
+ nSamplesIn = SKP_min( inLen, S->batchSize );
+
+ if( S->input2x == 1 ) {
+ /* Upsample 2x */
+ S->up2_function( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, nSamplesIn );
+ } else {
+ /* Fourth-order ARMA filter */
+ SKP_Silk_resampler_private_ARMA4( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, S->Coefs, nSamplesIn );
+ }
+
+ max_index_Q16 = SKP_LSHIFT32( nSamplesIn, 16 + S->input2x ); /* +1 if 2x upsampling */
+ out = SKP_Silk_resampler_private_IIR_FIR_INTERPOL(out, buf, max_index_Q16, index_increment_Q16);
+ in += nSamplesIn;
+ inLen -= nSamplesIn;
+
+ if( inLen > 0 ) {
+ /* More iterations to do; copy last part of filtered signal to beginning of buffer */
+ SKP_memcpy( buf, &buf[ nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) );
+ } else {
+ break;
+ }
+ }
+
+ /* Copy last part of filtered signal to the state for the next call */
+ SKP_memcpy( S->sFIR, &buf[nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) );
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_copy.c b/pkg/silk/csilk/SKP_Silk_resampler_private_copy.c
new file mode 100644
index 0000000..71df033
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_copy.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resampler_private_copy.c *
+ * *
+ * Description: Copy. *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * All rights reserved. *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+/* Copy */
+void SKP_Silk_resampler_private_copy(
+ void *SS, /* I/O: Resampler state (unused) */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ SKP_memcpy( out, in, inLen * sizeof( SKP_int16 ) );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_down4.c b/pkg/silk/csilk/SKP_Silk_resampler_private_down4.c
new file mode 100644
index 0000000..3d65ad7
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_down4.c
@@ -0,0 +1,77 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_private_down4.c *
+ * *
+ * Downsample by a factor 4 *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+/* Downsample by a factor 4. Note: very low quality, only use with input sampling rates above 96 kHz. */
+void SKP_Silk_resampler_private_down4(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ floor(len/2) ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ SKP_int32 k, len4 = SKP_RSHIFT32( inLen, 2 );
+ SKP_int32 in32, out32, Y, X;
+
+ SKP_assert( SKP_Silk_resampler_down2_0 > 0 );
+ SKP_assert( SKP_Silk_resampler_down2_1 < 0 );
+
+ /* Internal variables and state are in Q10 format */
+ for( k = 0; k < len4; k++ ) {
+ /* Add two input samples and convert to Q10 */
+ in32 = SKP_LSHIFT( SKP_ADD32( (SKP_int32)in[ 4 * k ], (SKP_int32)in[ 4 * k + 1 ] ), 9 );
+
+ /* All-pass section for even input sample */
+ Y = SKP_SUB32( in32, S[ 0 ] );
+ X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_down2_1 );
+ out32 = SKP_ADD32( S[ 0 ], X );
+ S[ 0 ] = SKP_ADD32( in32, X );
+
+ /* Add two input samples and convert to Q10 */
+ in32 = SKP_LSHIFT( SKP_ADD32( (SKP_int32)in[ 4 * k + 2 ], (SKP_int32)in[ 4 * k + 3 ] ), 9 );
+
+ /* All-pass section for odd input sample */
+ Y = SKP_SUB32( in32, S[ 1 ] );
+ X = SKP_SMULWB( Y, SKP_Silk_resampler_down2_0 );
+ out32 = SKP_ADD32( out32, S[ 1 ] );
+ out32 = SKP_ADD32( out32, X );
+ S[ 1 ] = SKP_ADD32( in32, X );
+
+ /* Add, convert back to int16 and store to output */
+ out[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 11 ) );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_down_FIR.c b/pkg/silk/csilk/SKP_Silk_resampler_private_down_FIR.c
new file mode 100644
index 0000000..4a441b1
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_down_FIR.c
@@ -0,0 +1,167 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resampler_private_down_FIR.c *
+ * *
+ * Description: Hybrid IIR/FIR polyphase implementation of resampling *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * All rights reserved. *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+#if EMBEDDED_ARM<5
+SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL0(
+ SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16){
+
+ SKP_int32 index_Q16, res_Q6;
+ SKP_int32 *buf_ptr;
+ for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
+ /* Integer part gives pointer to buffered input */
+ buf_ptr = buf2 + SKP_RSHIFT( index_Q16, 16 );
+
+ /* Inner product */
+ res_Q6 = SKP_SMULWB( SKP_ADD32( buf_ptr[ 0 ], buf_ptr[ 11 ] ), FIR_Coefs[ 0 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 1 ], buf_ptr[ 10 ] ), FIR_Coefs[ 1 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 2 ], buf_ptr[ 9 ] ), FIR_Coefs[ 2 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 3 ], buf_ptr[ 8 ] ), FIR_Coefs[ 3 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 4 ], buf_ptr[ 7 ] ), FIR_Coefs[ 4 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, SKP_ADD32( buf_ptr[ 5 ], buf_ptr[ 6 ] ), FIR_Coefs[ 5 ] );
+
+ /* Scale down, saturate and store in output array */
+ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) );
+ }
+ return out;
+}
+
+SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL1(
+ SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16, SKP_int32 FIR_Fracs){
+
+ SKP_int32 index_Q16, res_Q6;
+ SKP_int32 *buf_ptr;
+ SKP_int32 interpol_ind;
+ const SKP_int16 *interpol_ptr;
+ for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
+ /* Integer part gives pointer to buffered input */
+ buf_ptr = buf2 + SKP_RSHIFT( index_Q16, 16 );
+
+ /* Fractional part gives interpolation coefficients */
+ interpol_ind = SKP_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs );
+
+ /* Inner product */
+ interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * interpol_ind ];
+ res_Q6 = SKP_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] );
+ interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR / 2 * ( FIR_Fracs - 1 - interpol_ind ) ];
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 0 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 1 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 2 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 3 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 4 ] );
+ res_Q6 = SKP_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 5 ] );
+
+ /* Scale down, saturate and store in output array */
+ *out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q6, 6 ) );
+ }
+ return out;
+}
+
+#else
+extern SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL0(
+ SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16);
+extern SKP_int16 *SKP_Silk_resampler_private_down_FIR_INTERPOL1(
+ SKP_int16 *out, SKP_int32 *buf2, const SKP_int16 *FIR_Coefs, SKP_int32 max_index_Q16, SKP_int32 index_increment_Q16, SKP_int32 FIR_Fracs);
+#endif
+
+/* Resample with a 2x downsampler (optional), a 2nd order AR filter followed by FIR interpolation */
+void SKP_Silk_resampler_private_down_FIR(
+ void *SS, /* I/O: Resampler state */
+ SKP_int16 out[], /* O: Output signal */
+ const SKP_int16 in[], /* I: Input signal */
+ SKP_int32 inLen /* I: Number of input samples */
+)
+{
+ SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS;
+ SKP_int32 nSamplesIn;
+ SKP_int32 max_index_Q16, index_increment_Q16;
+ SKP_int16 buf1[ RESAMPLER_MAX_BATCH_SIZE_IN / 2 ];
+ SKP_int32 buf2[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_DOWN_ORDER_FIR ];
+ const SKP_int16 *FIR_Coefs;
+
+ /* Copy buffered samples to start of buffer */
+ SKP_memcpy( buf2, S->sFIR, RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) );
+
+ FIR_Coefs = &S->Coefs[ 2 ];
+
+ /* Iterate over blocks of frameSizeIn input samples */
+ index_increment_Q16 = S->invRatio_Q16;
+ while( 1 ) {
+ nSamplesIn = SKP_min( inLen, S->batchSize );
+
+ if( S->input2x == 1 ) {
+ /* Downsample 2x */
+ SKP_Silk_resampler_down2( S->sDown2, buf1, in, nSamplesIn );
+
+ nSamplesIn = SKP_RSHIFT32( nSamplesIn, 1 );
+
+ /* Second-order AR filter (output in Q8) */
+ SKP_Silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], buf1, S->Coefs, nSamplesIn );
+ } else {
+ /* Second-order AR filter (output in Q8) */
+ SKP_Silk_resampler_private_AR2( S->sIIR, &buf2[ RESAMPLER_DOWN_ORDER_FIR ], in, S->Coefs, nSamplesIn );
+ }
+
+ max_index_Q16 = SKP_LSHIFT32( nSamplesIn, 16 );
+
+ /* Interpolate filtered signal */
+ if( S->FIR_Fracs == 1 ) {
+ out = SKP_Silk_resampler_private_down_FIR_INTERPOL0(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16);
+ } else {
+ out = SKP_Silk_resampler_private_down_FIR_INTERPOL1(out, buf2, FIR_Coefs, max_index_Q16, index_increment_Q16, S->FIR_Fracs);
+ }
+
+ in += nSamplesIn << S->input2x;
+ inLen -= nSamplesIn << S->input2x;
+
+ if( inLen > S->input2x ) {
+ /* More iterations to do; copy last part of filtered signal to beginning of buffer */
+ SKP_memcpy( buf2, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) );
+ } else {
+ break;
+ }
+ }
+
+ /* Copy last part of filtered signal to the state for the next call */
+ SKP_memcpy( S->sFIR, &buf2[ nSamplesIn ], RESAMPLER_DOWN_ORDER_FIR * sizeof( SKP_int32 ) );
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_up2_HQ.c b/pkg/silk/csilk/SKP_Silk_resampler_private_up2_HQ.c
new file mode 100644
index 0000000..a95082e
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_up2_HQ.c
@@ -0,0 +1,120 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_private_up2_HQ.c *
+ * *
+ * Upsample by a factor 2, high quality *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+/* Upsample by a factor 2, high quality */
+/* Uses 2nd order allpass filters for the 2x upsampling, followed by a */
+/* notch filter just above Nyquist. */
+#if (EMBEDDED_ARM<5)
+void SKP_Silk_resampler_private_up2_HQ(
+ SKP_int32 *S, /* I/O: Resampler state [ 6 ] */
+ SKP_int16 *out, /* O: Output signal [ 2 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of INPUT samples */
+)
+{
+ SKP_int32 k;
+ SKP_int32 in32, out32_1, out32_2, Y, X;
+
+ SKP_assert( SKP_Silk_resampler_up2_hq_0[ 0 ] > 0 );
+ SKP_assert( SKP_Silk_resampler_up2_hq_0[ 1 ] < 0 );
+ SKP_assert( SKP_Silk_resampler_up2_hq_1[ 0 ] > 0 );
+ SKP_assert( SKP_Silk_resampler_up2_hq_1[ 1 ] < 0 );
+
+ /* Internal variables and state are in Q10 format */
+ for( k = 0; k < len; k++ ) {
+ /* Convert to Q10 */
+ in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 );
+
+ /* First all-pass section for even output sample */
+ Y = SKP_SUB32( in32, S[ 0 ] );
+ X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_hq_0[ 0 ] );
+ out32_1 = SKP_ADD32( S[ 0 ], X );
+ S[ 0 ] = SKP_ADD32( in32, X );
+
+ /* Second all-pass section for even output sample */
+ Y = SKP_SUB32( out32_1, S[ 1 ] );
+ X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_hq_0[ 1 ] );
+ out32_2 = SKP_ADD32( S[ 1 ], X );
+ S[ 1 ] = SKP_ADD32( out32_1, X );
+
+ /* Biquad notch filter */
+ out32_2 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 2 ] );
+ out32_2 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 1 ] );
+ out32_1 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 0 ] );
+ S[ 5 ] = SKP_SUB32( out32_2, S[ 5 ] );
+
+ /* Apply gain in Q15, convert back to int16 and store to output */
+ out[ 2 * k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32(
+ SKP_SMLAWB( 256, out32_1, SKP_Silk_resampler_up2_hq_notch[ 3 ] ), 9 ) );
+
+ /* First all-pass section for odd output sample */
+ Y = SKP_SUB32( in32, S[ 2 ] );
+ X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_hq_1[ 0 ] );
+ out32_1 = SKP_ADD32( S[ 2 ], X );
+ S[ 2 ] = SKP_ADD32( in32, X );
+
+ /* Second all-pass section for odd output sample */
+ Y = SKP_SUB32( out32_1, S[ 3 ] );
+ X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_hq_1[ 1 ] );
+ out32_2 = SKP_ADD32( S[ 3 ], X );
+ S[ 3 ] = SKP_ADD32( out32_1, X );
+
+ /* Biquad notch filter */
+ out32_2 = SKP_SMLAWB( out32_2, S[ 4 ], SKP_Silk_resampler_up2_hq_notch[ 2 ] );
+ out32_2 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 1 ] );
+ out32_1 = SKP_SMLAWB( out32_2, S[ 5 ], SKP_Silk_resampler_up2_hq_notch[ 0 ] );
+ S[ 4 ] = SKP_SUB32( out32_2, S[ 4 ] );
+
+ /* Apply gain in Q15, convert back to int16 and store to output */
+ out[ 2 * k + 1 ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT32(
+ SKP_SMLAWB( 256, out32_1, SKP_Silk_resampler_up2_hq_notch[ 3 ] ), 9 ) );
+ }
+}
+#endif
+
+
+void SKP_Silk_resampler_private_up2_HQ_wrapper(
+ void *SS, /* I/O: Resampler state (unused) */
+ SKP_int16 *out, /* O: Output signal [ 2 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of input samples */
+)
+{
+ SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS;
+ SKP_Silk_resampler_private_up2_HQ( S->sIIR, out, in, len );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_private_up4.c b/pkg/silk/csilk/SKP_Silk_resampler_private_up4.c
new file mode 100644
index 0000000..f1cff61
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_private_up4.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_private_up4.c *
+ * *
+ * Upsample by a factor 4, low quality *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_private.h"
+
+/* Upsample by a factor 4, Note: very low quality, only use with output sampling rates above 96 kHz. */
+void SKP_Silk_resampler_private_up4(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ 4 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of INPUT samples */
+)
+{
+ SKP_int32 k;
+ SKP_int32 in32, out32, Y, X;
+ SKP_int16 out16;
+
+ SKP_assert( SKP_Silk_resampler_up2_lq_0 > 0 );
+ SKP_assert( SKP_Silk_resampler_up2_lq_1 < 0 );
+
+ /* Internal variables and state are in Q10 format */
+ for( k = 0; k < len; k++ ) {
+ /* Convert to Q10 */
+ in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 );
+
+ /* All-pass section for even output sample */
+ Y = SKP_SUB32( in32, S[ 0 ] );
+ X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_lq_0 );
+ out32 = SKP_ADD32( S[ 0 ], X );
+ S[ 0 ] = SKP_ADD32( in32, X );
+
+ /* Convert back to int16 and store to output */
+ out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) );
+ out[ 4 * k ] = out16;
+ out[ 4 * k + 1 ] = out16;
+
+ /* All-pass section for odd output sample */
+ Y = SKP_SUB32( in32, S[ 1 ] );
+ X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_lq_1 );
+ out32 = SKP_ADD32( S[ 1 ], X );
+ S[ 1 ] = SKP_ADD32( in32, X );
+
+ /* Convert back to int16 and store to output */
+ out16 = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) );
+ out[ 4 * k + 2 ] = out16;
+ out[ 4 * k + 3 ] = out16;
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_rom.c b/pkg/silk/csilk/SKP_Silk_resampler_rom.c
new file mode 100644
index 0000000..b8e8ef8
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_rom.c
@@ -0,0 +1,269 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resampler_rom.c *
+ * *
+ * Description: Filter coefficients for IIR/FIR polyphase resampling *
+ * Total size: 550 Words (1.1 kB) *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * All rights reserved. *
+ * */
+
+#include "SKP_Silk_resampler_private.h"
+
+/* Tables for 2x downsampler */
+const SKP_int16 SKP_Silk_resampler_down2_0 = 9872;
+const SKP_int16 SKP_Silk_resampler_down2_1 = 39809 - 65536;
+
+/* Tables for 2x upsampler, low quality */
+const SKP_int16 SKP_Silk_resampler_up2_lq_0 = 8102;
+const SKP_int16 SKP_Silk_resampler_up2_lq_1 = 36783 - 65536;
+
+/* Tables for 2x upsampler, high quality */
+const SKP_int16 SKP_Silk_resampler_up2_hq_0[ 2 ] = { 4280, 33727 - 65536 };
+const SKP_int16 SKP_Silk_resampler_up2_hq_1[ 2 ] = { 16295, 54015 - 65536 };
+/* Matlab code for the notch filter coefficients: */
+/* B = [1, 0.12, 1]; A = [1, 0.055, 0.8]; G = 0.87; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]); */
+/* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */
+const SKP_int16 SKP_Silk_resampler_up2_hq_notch[ 4 ] = { 7864, -3604, 13107, 28508 };
+
+
+/* Tables with IIR and FIR coefficients for fractional downsamplers (70 Words) */
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
+ -18249, -12532,
+ -97, 284, -495, 309, 10268, 20317,
+ -94, 156, -48, -720, 5984, 18278,
+ -45, -4, 237, -847, 2540, 14662,
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
+ -11891, -12486,
+ 20, 211, -657, 688, 8423, 15911,
+ -44, 197, -152, -653, 3855, 13015,
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
+ 2415, -13101,
+ 158, -295, -400, 1265, 4832, 7968,
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_3_8_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
+ 13270, -13738,
+ -294, -123, 747, 2043, 3339, 3995,
+ -151, -311, 414, 1583, 2947, 3877,
+ -33, -389, 143, 1141, 2503, 3653,
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ] = {
+ 16643, -14000,
+ -331, 19, 581, 1421, 2290, 2845,
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
+ -2797, -6507,
+ 4697, 10739,
+ 1567, 8276,
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 + 3 ] = {
+ 16777, -9792,
+ 890, 1614, 2148,
+};
+
+
+/* Tables with coefficients for 4th order ARMA filter (35 Words), in a packed format: */
+/* { B1_Q14[1], B2_Q14[1], -A1_Q14[1], -A1_Q14[2], -A2_Q14[1], -A2_Q14[2], gain_Q16 } */
+/* where it is assumed that B*_Q14[0], B*_Q14[2], A*_Q14[0] are all 16384 */
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_320_441_ARMA4_COEFS[ 7 ] = {
+ 31454, 24746, -9706, -3386, -17911, -13243, 24797
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_240_441_ARMA4_COEFS[ 7 ] = {
+ 28721, 11254, 3189, -2546, -1495, -12618, 11562
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_160_441_ARMA4_COEFS[ 7 ] = {
+ 23492, -6457, 14358, -4856, 14654, -13008, 4456
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_120_441_ARMA4_COEFS[ 7 ] = {
+ 19311, -15569, 19489, -6950, 21441, -13559, 2370
+};
+
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_Resampler_80_441_ARMA4_COEFS[ 7 ] = {
+ 13248, -23849, 24126, -9486, 26806, -14286, 1065
+};
+
+/* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */
+SKP_DWORD_ALIGN const SKP_int16 SKP_Silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ] = {
+ { -647, 1884, 30078},
+ { -625, 1736, 30044},
+ { -603, 1591, 30005},
+ { -581, 1448, 29963},
+ { -559, 1308, 29917},
+ { -537, 1169, 29867},
+ { -515, 1032, 29813},
+ { -494, 898, 29755},
+ { -473, 766, 29693},
+ { -452, 636, 29627},
+ { -431, 508, 29558},
+ { -410, 383, 29484},
+ { -390, 260, 29407},
+ { -369, 139, 29327},
+ { -349, 20, 29242},
+ { -330, -97, 29154},
+ { -310, -211, 29062},
+ { -291, -324, 28967},
+ { -271, -434, 28868},
+ { -253, -542, 28765},
+ { -234, -647, 28659},
+ { -215, -751, 28550},
+ { -197, -852, 28436},
+ { -179, -951, 28320},
+ { -162, -1048, 28200},
+ { -144, -1143, 28077},
+ { -127, -1235, 27950},
+ { -110, -1326, 27820},
+ { -94, -1414, 27687},
+ { -77, -1500, 27550},
+ { -61, -1584, 27410},
+ { -45, -1665, 27268},
+ { -30, -1745, 27122},
+ { -15, -1822, 26972},
+ { 0, -1897, 26820},
+ { 15, -1970, 26665},
+ { 29, -2041, 26507},
+ { 44, -2110, 26346},
+ { 57, -2177, 26182},
+ { 71, -2242, 26015},
+ { 84, -2305, 25845},
+ { 97, -2365, 25673},
+ { 110, -2424, 25498},
+ { 122, -2480, 25320},
+ { 134, -2534, 25140},
+ { 146, -2587, 24956},
+ { 157, -2637, 24771},
+ { 168, -2685, 24583},
+ { 179, -2732, 24392},
+ { 190, -2776, 24199},
+ { 200, -2819, 24003},
+ { 210, -2859, 23805},
+ { 220, -2898, 23605},
+ { 229, -2934, 23403},
+ { 238, -2969, 23198},
+ { 247, -3002, 22992},
+ { 255, -3033, 22783},
+ { 263, -3062, 22572},
+ { 271, -3089, 22359},
+ { 279, -3114, 22144},
+ { 286, -3138, 21927},
+ { 293, -3160, 21709},
+ { 300, -3180, 21488},
+ { 306, -3198, 21266},
+ { 312, -3215, 21042},
+ { 318, -3229, 20816},
+ { 323, -3242, 20589},
+ { 328, -3254, 20360},
+ { 333, -3263, 20130},
+ { 338, -3272, 19898},
+ { 342, -3278, 19665},
+ { 346, -3283, 19430},
+ { 350, -3286, 19194},
+ { 353, -3288, 18957},
+ { 356, -3288, 18718},
+ { 359, -3286, 18478},
+ { 362, -3283, 18238},
+ { 364, -3279, 17996},
+ { 366, -3273, 17753},
+ { 368, -3266, 17509},
+ { 369, -3257, 17264},
+ { 371, -3247, 17018},
+ { 372, -3235, 16772},
+ { 372, -3222, 16525},
+ { 373, -3208, 16277},
+ { 373, -3192, 16028},
+ { 373, -3175, 15779},
+ { 373, -3157, 15529},
+ { 372, -3138, 15279},
+ { 371, -3117, 15028},
+ { 370, -3095, 14777},
+ { 369, -3072, 14526},
+ { 368, -3048, 14274},
+ { 366, -3022, 14022},
+ { 364, -2996, 13770},
+ { 362, -2968, 13517},
+ { 359, -2940, 13265},
+ { 357, -2910, 13012},
+ { 354, -2880, 12760},
+ { 351, -2848, 12508},
+ { 348, -2815, 12255},
+ { 344, -2782, 12003},
+ { 341, -2747, 11751},
+ { 337, -2712, 11500},
+ { 333, -2676, 11248},
+ { 328, -2639, 10997},
+ { 324, -2601, 10747},
+ { 320, -2562, 10497},
+ { 315, -2523, 10247},
+ { 310, -2482, 9998},
+ { 305, -2442, 9750},
+ { 300, -2400, 9502},
+ { 294, -2358, 9255},
+ { 289, -2315, 9009},
+ { 283, -2271, 8763},
+ { 277, -2227, 8519},
+ { 271, -2182, 8275},
+ { 265, -2137, 8032},
+ { 259, -2091, 7791},
+ { 252, -2045, 7550},
+ { 246, -1998, 7311},
+ { 239, -1951, 7072},
+ { 232, -1904, 6835},
+ { 226, -1856, 6599},
+ { 219, -1807, 6364},
+ { 212, -1758, 6131},
+ { 204, -1709, 5899},
+ { 197, -1660, 5668},
+ { 190, -1611, 5439},
+ { 183, -1561, 5212},
+ { 175, -1511, 4986},
+ { 168, -1460, 4761},
+ { 160, -1410, 4538},
+ { 152, -1359, 4317},
+ { 145, -1309, 4098},
+ { 137, -1258, 3880},
+ { 129, -1207, 3664},
+ { 121, -1156, 3450},
+ { 113, -1105, 3238},
+ { 105, -1054, 3028},
+ { 97, -1003, 2820},
+ { 89, -952, 2614},
+ { 81, -901, 2409},
+ { 73, -851, 2207},
+};
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_rom.h b/pkg/silk/csilk/SKP_Silk_resampler_rom.h
new file mode 100644
index 0000000..8c12f67
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_rom.h
@@ -0,0 +1,91 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resample_rom.h *
+ * *
+ * Description: Header file for FIR resampling of *
+ * 32 and 44 kHz input *
+ * *
+ * Copyright 2007 (c), Skype Limited *
+ * All rights reserved. *
+ * *
+ * Date: 070807 *
+ * */
+
+#ifndef _SKP_SILK_FIX_RESAMPLER_ROM_H_
+#define _SKP_SILK_FIX_RESAMPLER_ROM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "SKP_Silk_typedef.h"
+#include "SKP_Silk_resampler_structs.h"
+
+#define RESAMPLER_DOWN_ORDER_FIR 12
+#define RESAMPLER_ORDER_FIR_144 6
+
+
+/* Tables for 2x downsampler. Values above 32767 intentionally wrap to a negative value. */
+extern const SKP_int16 SKP_Silk_resampler_down2_0;
+extern const SKP_int16 SKP_Silk_resampler_down2_1;
+
+/* Tables for 2x upsampler, low quality. Values above 32767 intentionally wrap to a negative value. */
+extern const SKP_int16 SKP_Silk_resampler_up2_lq_0;
+extern const SKP_int16 SKP_Silk_resampler_up2_lq_1;
+
+/* Tables for 2x upsampler, high quality. Values above 32767 intentionally wrap to a negative value. */
+extern const SKP_int16 SKP_Silk_resampler_up2_hq_0[ 2 ];
+extern const SKP_int16 SKP_Silk_resampler_up2_hq_1[ 2 ];
+extern const SKP_int16 SKP_Silk_resampler_up2_hq_notch[ 4 ];
+
+/* Tables with IIR and FIR coefficients for fractional downsamplers */
+extern const SKP_int16 SKP_Silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ];
+extern const SKP_int16 SKP_Silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR / 2 ];
+extern const SKP_int16 SKP_Silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ];
+extern const SKP_int16 SKP_Silk_Resampler_3_8_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR / 2 ];
+extern const SKP_int16 SKP_Silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR / 2 ];
+extern const SKP_int16 SKP_Silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ];
+extern const SKP_int16 SKP_Silk_Resampler_1_3_COEFS_LQ[ 2 + 3 ];
+
+/* Tables with coefficients for 4th order ARMA filter */
+extern const SKP_int16 SKP_Silk_Resampler_320_441_ARMA4_COEFS[ 7 ];
+extern const SKP_int16 SKP_Silk_Resampler_240_441_ARMA4_COEFS[ 7 ];
+extern const SKP_int16 SKP_Silk_Resampler_160_441_ARMA4_COEFS[ 7 ];
+extern const SKP_int16 SKP_Silk_Resampler_120_441_ARMA4_COEFS[ 7 ];
+extern const SKP_int16 SKP_Silk_Resampler_80_441_ARMA4_COEFS[ 7 ];
+
+/* Table with interplation fractions of 1/288 : 2/288 : 287/288 (432 Words) */
+extern const SKP_int16 SKP_Silk_resampler_frac_FIR_144[ 144 ][ RESAMPLER_ORDER_FIR_144 / 2 ];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SKP_SILK_FIX_RESAMPLER_ROM_H_
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_structs.h b/pkg/silk/csilk/SKP_Silk_resampler_structs.h
new file mode 100644
index 0000000..743c992
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_structs.h
@@ -0,0 +1,80 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * File Name: SKP_Silk_resampler_structs.h *
+ * *
+ * Description: Structs for IIR/FIR resamplers *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * All rights reserved. *
+ * *
+ * */
+
+#ifndef SKP_Silk_RESAMPLER_STRUCTS_H
+#define SKP_Silk_RESAMPLER_STRUCTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Flag to enable support for input/output sampling rates above 48 kHz. Turn off for embedded devices */
+#define RESAMPLER_SUPPORT_ABOVE_48KHZ 1
+
+#define SKP_Silk_RESAMPLER_MAX_FIR_ORDER 16
+#define SKP_Silk_RESAMPLER_MAX_IIR_ORDER 6
+
+
+typedef struct _SKP_Silk_resampler_state_struct{
+ SKP_int32 sIIR[ SKP_Silk_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */
+ SKP_int32 sFIR[ SKP_Silk_RESAMPLER_MAX_FIR_ORDER ];
+ SKP_int32 sDown2[ 2 ];
+ void (*resampler_function)( void *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+ void (*up2_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+ SKP_int32 batchSize;
+ SKP_int32 invRatio_Q16;
+ SKP_int32 FIR_Fracs;
+ SKP_int32 input2x;
+ const SKP_int16 *Coefs;
+#if RESAMPLER_SUPPORT_ABOVE_48KHZ
+ SKP_int32 sDownPre[ 2 ];
+ SKP_int32 sUpPost[ 2 ];
+ void (*down_pre_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+ void (*up_post_function)( SKP_int32 *, SKP_int16 *, const SKP_int16 *, SKP_int32 );
+ SKP_int32 batchSizePrePost;
+ SKP_int32 ratio_Q16;
+ SKP_int32 nPreDownsamplers;
+ SKP_int32 nPostUpsamplers;
+#endif
+ SKP_int32 magic_number;
+} SKP_Silk_resampler_state_struct;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* SKP_Silk_RESAMPLER_STRUCTS_H */
+
diff --git a/pkg/silk/csilk/SKP_Silk_resampler_up2.c b/pkg/silk/csilk/SKP_Silk_resampler_up2.c
new file mode 100644
index 0000000..9ede6a9
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_resampler_up2.c
@@ -0,0 +1,77 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_resampler_up2.c *
+ * *
+ * Upsample by a factor 2, low quality *
+ * *
+ * Copyright 2010 (c), Skype Limited *
+ * */
+
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_resampler_rom.h"
+
+/* Upsample by a factor 2, low quality */
+#if EMBEDDED_ARM<5
+void SKP_Silk_resampler_up2(
+ SKP_int32 *S, /* I/O: State vector [ 2 ] */
+ SKP_int16 *out, /* O: Output signal [ 2 * len ] */
+ const SKP_int16 *in, /* I: Input signal [ len ] */
+ SKP_int32 len /* I: Number of input samples */
+)
+{
+ SKP_int32 k;
+ SKP_int32 in32, out32, Y, X;
+
+ SKP_assert( SKP_Silk_resampler_up2_lq_0 > 0 );
+ SKP_assert( SKP_Silk_resampler_up2_lq_1 < 0 );
+ /* Internal variables and state are in Q10 format */
+ for( k = 0; k < len; k++ ) {
+ /* Convert to Q10 */
+ in32 = SKP_LSHIFT( (SKP_int32)in[ k ], 10 );
+
+ /* All-pass section for even output sample */
+ Y = SKP_SUB32( in32, S[ 0 ] );
+ X = SKP_SMULWB( Y, SKP_Silk_resampler_up2_lq_0 );
+ out32 = SKP_ADD32( S[ 0 ], X );
+ S[ 0 ] = SKP_ADD32( in32, X );
+
+ /* Convert back to int16 and store to output */
+ out[ 2 * k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) );
+
+ /* All-pass section for odd output sample */
+ Y = SKP_SUB32( in32, S[ 1 ] );
+ X = SKP_SMLAWB( Y, Y, SKP_Silk_resampler_up2_lq_1 );
+ out32 = SKP_ADD32( S[ 1 ], X );
+ S[ 1 ] = SKP_ADD32( in32, X );
+
+ /* Convert back to int16 and store to output */
+ out[ 2 * k + 1 ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( out32, 10 ) );
+ }
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_residual_energy16_FIX.c b/pkg/silk/csilk/SKP_Silk_residual_energy16_FIX.c
new file mode 100644
index 0000000..60ee2a5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_residual_energy16_FIX.c
@@ -0,0 +1,99 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
+SKP_int32 SKP_Silk_residual_energy16_covar_FIX(
+ const SKP_int16 *c, /* I Prediction vector */
+ const SKP_int32 *wXX, /* I Correlation matrix */
+ const SKP_int32 *wXx, /* I Correlation vector */
+ SKP_int32 wxx, /* I Signal energy */
+ SKP_int D, /* I Dimension */
+ SKP_int cQ /* I Q value for c vector 0 - 15 */
+)
+{
+ SKP_int i, j, lshifts, Qxtra;
+ SKP_int32 c_max, w_max, tmp, tmp2, nrg;
+ SKP_int cn[ MAX_MATRIX_SIZE ];
+ const SKP_int32 *pRow;
+
+ /* Safety checks */
+ SKP_assert( D >= 0 );
+ SKP_assert( D <= 16 );
+ SKP_assert( cQ > 0 );
+ SKP_assert( cQ < 16 );
+
+ lshifts = 16 - cQ;
+ Qxtra = lshifts;
+
+ c_max = 0;
+ for( i = 0; i < D; i++ ) {
+ c_max = SKP_max_32( c_max, SKP_abs( ( SKP_int32 )c[ i ] ) );
+ }
+ Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( c_max ) - 17 );
+
+ w_max = SKP_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );
+ Qxtra = SKP_min_int( Qxtra, SKP_Silk_CLZ32( SKP_MUL( D, SKP_RSHIFT( SKP_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );
+ Qxtra = SKP_max_int( Qxtra, 0 );
+ for( i = 0; i < D; i++ ) {
+ cn[ i ] = SKP_LSHIFT( ( SKP_int )c[ i ], Qxtra );
+ SKP_assert( SKP_abs(cn[i]) <= ( SKP_int16_MAX + 1 ) ); /* Check that SKP_SMLAWB can be used */
+ }
+ lshifts -= Qxtra;
+
+ /* Compute wxx - 2 * wXx * c */
+ tmp = 0;
+ for( i = 0; i < D; i++ ) {
+ tmp = SKP_SMLAWB( tmp, wXx[ i ], cn[ i ] );
+ }
+ nrg = SKP_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */
+
+ /* Add c' * wXX * c, assuming wXX is symmetric */
+ tmp2 = 0;
+ for( i = 0; i < D; i++ ) {
+ tmp = 0;
+ pRow = &wXX[ i * D ];
+ for( j = i + 1; j < D; j++ ) {
+ tmp = SKP_SMLAWB( tmp, pRow[ j ], cn[ j ] );
+ }
+ tmp = SKP_SMLAWB( tmp, SKP_RSHIFT( pRow[ i ], 1 ), cn[ i ] );
+ tmp2 = SKP_SMLAWB( tmp2, tmp, cn[ i ] );
+ }
+ nrg = SKP_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */
+
+ /* Keep one bit free always, because we add them for LSF interpolation */
+ if( nrg < 1 ) {
+ nrg = 1;
+ } else if( nrg > SKP_RSHIFT( SKP_int32_MAX, lshifts + 2 ) ) {
+ nrg = SKP_int32_MAX >> 1;
+ } else {
+ nrg = SKP_LSHIFT( nrg, lshifts + 1 ); /* Q0 */
+ }
+ return nrg;
+
+}
diff --git a/pkg/silk/csilk/SKP_Silk_residual_energy_FIX.c b/pkg/silk/csilk/SKP_Silk_residual_energy_FIX.c
new file mode 100644
index 0000000..f422e55
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_residual_energy_FIX.c
@@ -0,0 +1,88 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+/* Calculates residual energies of input subframes where all subframes have LPC_order */
+/* of preceeding samples */
+void SKP_Silk_residual_energy_FIX(
+ SKP_int32 nrgs[ NB_SUBFR ], /* O Residual energy per subframe */
+ SKP_int nrgsQ[ NB_SUBFR ], /* O Q value per subframe */
+ const SKP_int16 x[], /* I Input signal */
+ SKP_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ],/* I AR coefs for each frame half */
+ const SKP_int32 gains[ NB_SUBFR ], /* I Quantization gains */
+ const SKP_int subfr_length, /* I Subframe length */
+ const SKP_int LPC_order /* I LPC order */
+)
+{
+ SKP_int offset, i, j, rshift, lz1, lz2;
+ SKP_int16 *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
+ const SKP_int16 *x_ptr;
+ SKP_int16 S[ MAX_LPC_ORDER ];
+ SKP_int32 tmp32;
+
+ x_ptr = x;
+ offset = LPC_order + subfr_length;
+
+ /* Filter input to create the LPC residual for each frame half, and measure subframe energies */
+ for( i = 0; i < 2; i++ ) {
+ /* Calculate half frame LPC residual signal including preceeding samples */
+ SKP_memset( S, 0, LPC_order * sizeof( SKP_int16 ) );
+ SKP_Silk_LPC_analysis_filter( x_ptr, a_Q12[ i ], S, LPC_res, ( NB_SUBFR >> 1 ) * offset, LPC_order );
+
+ /* Point to first subframe of the just calculated LPC residual signal */
+ LPC_res_ptr = LPC_res + LPC_order;
+ for( j = 0; j < ( NB_SUBFR >> 1 ); j++ ) {
+ /* Measure subframe energy */
+ SKP_Silk_sum_sqr_shift( &nrgs[ i * ( NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length );
+
+ /* Set Q values for the measured energy */
+ nrgsQ[ i * ( NB_SUBFR >> 1 ) + j ] = -rshift;
+
+ /* Move to next subframe */
+ LPC_res_ptr += offset;
+ }
+ /* Move to next frame half */
+ x_ptr += ( NB_SUBFR >> 1 ) * offset;
+ }
+
+ /* Apply the squared subframe gains */
+ for( i = 0; i < NB_SUBFR; i++ ) {
+ /* Fully upscale gains and energies */
+ lz1 = SKP_Silk_CLZ32( nrgs[ i ] ) - 1;
+ lz2 = SKP_Silk_CLZ32( gains[ i ] ) - 1;
+
+ tmp32 = SKP_LSHIFT32( gains[ i ], lz2 );
+
+ /* Find squared gains */
+ tmp32 = SKP_SMMUL( tmp32, tmp32 ); // Q( 2 * lz2 - 32 )
+
+ /* Scale energies */
+ nrgs[ i ] = SKP_SMMUL( tmp32, SKP_LSHIFT32( nrgs[ i ], lz1 ) ); // Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )
+ nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_scale_copy_vector16.c b/pkg/silk/csilk/SKP_Silk_scale_copy_vector16.c
new file mode 100644
index 0000000..9d6f8c3
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_scale_copy_vector16.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SigProc_FIX.h"
+
+/* Copy and multiply a vector by a constant */
+void SKP_Silk_scale_copy_vector16(
+ SKP_int16 *data_out,
+ const SKP_int16 *data_in,
+ SKP_int32 gain_Q16, /* (I): gain in Q16 */
+ const SKP_int dataSize /* (I): length */
+)
+{
+ SKP_int i;
+ SKP_int32 tmp32;
+
+ for( i = 0; i < dataSize; i++ ) {
+ tmp32 = SKP_SMULWB( gain_Q16, data_in[ i ] );
+ data_out[ i ] = (SKP_int16)SKP_CHECK_FIT16( tmp32 );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_scale_vector.c b/pkg/silk/csilk/SKP_Silk_scale_vector.c
new file mode 100644
index 0000000..320e94a
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_scale_vector.c
@@ -0,0 +1,43 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_SigProc_FIX.h"
+
+/* Multiply a vector by a constant */
+void SKP_Silk_scale_vector32_Q26_lshift_18(
+ SKP_int32 *data1, /* (I/O): Q0/Q18 */
+ SKP_int32 gain_Q26, /* (I): Q26 */
+ SKP_int dataSize /* (I): length */
+)
+{
+ SKP_int i;
+
+ for( i = 0; i < dataSize; i++ ) {
+ data1[ i ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( SKP_SMULL( data1[ i ], gain_Q26 ), 8 ) );// OUTPUT: Q18
+ }
+}
+
diff --git a/pkg/silk/csilk/SKP_Silk_schur.c b/pkg/silk/csilk/SKP_Silk_schur.c
new file mode 100644
index 0000000..b631851
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_schur.c
@@ -0,0 +1,94 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_schur.c *
+ * *
+ * Calculates the reflection coefficients from the correlation sequence *
+ * *
+ * Copyright 2008 (c), Skype Limited *
+ * Date: 080103 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Faster than schur64(), but much less accurate. */
+/* uses SMLAWB(), requiring armv5E and higher. */
+SKP_int32 SKP_Silk_schur( /* O: Returns residual energy */
+ SKP_int16 *rc_Q15, /* O: reflection coefficients [order] Q15 */
+ const SKP_int32 *c, /* I: correlations [order+1] */
+ const SKP_int32 order /* I: prediction order */
+)
+{
+ SKP_int k, n, lz;
+ SKP_int32 C[ SKP_Silk_MAX_ORDER_LPC + 1 ][ 2 ];
+ SKP_int32 Ctmp1, Ctmp2, rc_tmp_Q15;
+
+ /* Get number of leading zeros */
+ lz = SKP_Silk_CLZ32( c[ 0 ] );
+
+ /* Copy correlations and adjust level to Q30 */
+ if( lz < 2 ) {
+ /* lz must be 1, so shift one to the right */
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = SKP_RSHIFT( c[ k ], 1 );
+ }
+ } else if( lz > 2 ) {
+ /* Shift to the left */
+ lz -= 2;
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = SKP_LSHIFT( c[k], lz );
+ }
+ } else {
+ /* No need to shift */
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
+ }
+ }
+
+ for( k = 0; k < order; k++ ) {
+
+ /* Get reflection coefficient */
+ rc_tmp_Q15 = -SKP_DIV32_16( C[ k + 1 ][ 0 ], SKP_max_32( SKP_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );
+
+ /* Clip (shouldn't happen for properly conditioned inputs) */
+ rc_tmp_Q15 = SKP_SAT16( rc_tmp_Q15 );
+
+ /* Store */
+ rc_Q15[ k ] = (SKP_int16)rc_tmp_Q15;
+
+ /* Update correlations */
+ for( n = 0; n < order - k; n++ ) {
+ Ctmp1 = C[ n + k + 1 ][ 0 ];
+ Ctmp2 = C[ n ][ 1 ];
+ C[ n + k + 1 ][ 0 ] = SKP_SMLAWB( Ctmp1, SKP_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );
+ C[ n ][ 1 ] = SKP_SMLAWB( Ctmp2, SKP_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );
+ }
+ }
+
+ /* return residual energy */
+ return C[0][1];
+}
diff --git a/pkg/silk/csilk/SKP_Silk_schur64.c b/pkg/silk/csilk/SKP_Silk_schur64.c
new file mode 100644
index 0000000..c4e824c
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_schur64.c
@@ -0,0 +1,82 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_schur64.c *
+ * *
+ * Calculates the reflection coefficients from the correlation sequence *
+ * using extra precision *
+ * *
+ * Copyright 2008 (c), Skype Limited *
+ * Date: 080103 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+
+/* Slower than schur(), but more accurate. */
+/* Uses SMULL(), available on armv4 */
+#if EMBEDDED_ARM<6
+SKP_int32 SKP_Silk_schur64( /* O: Returns residual energy */
+ SKP_int32 rc_Q16[], /* O: Reflection coefficients [order] Q16 */
+ const SKP_int32 c[], /* I: Correlations [order+1] */
+ SKP_int32 order /* I: Prediction order */
+)
+{
+ SKP_int k, n;
+ SKP_int32 C[ SKP_Silk_MAX_ORDER_LPC + 1 ][ 2 ];
+ SKP_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
+
+ /* Check for invalid input */
+ if( c[ 0 ] <= 0 ) {
+ SKP_memset( rc_Q16, 0, order * sizeof( SKP_int32 ) );
+ return 0;
+ }
+
+ for( k = 0; k < order + 1; k++ ) {
+ C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
+ }
+
+ for( k = 0; k < order; k++ ) {
+ /* Get reflection coefficient: divide two Q30 values and get result in Q31 */
+ rc_tmp_Q31 = SKP_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );
+
+ /* Save the output */
+ rc_Q16[ k ] = SKP_RSHIFT_ROUND( rc_tmp_Q31, 15 );
+
+ /* Update correlations */
+ for( n = 0; n < order - k; n++ ) {
+ Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];
+ Ctmp2_Q30 = C[ n ][ 1 ];
+
+ /* Multiply and add the highest int32 */
+ C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + SKP_SMMUL( SKP_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );
+ C[ n ][ 1 ] = Ctmp2_Q30 + SKP_SMMUL( SKP_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );
+ }
+ }
+
+ return C[ 0 ][ 1 ];
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_setup_complexity.h b/pkg/silk/csilk/SKP_Silk_setup_complexity.h
new file mode 100644
index 0000000..f00ab55
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_setup_complexity.h
@@ -0,0 +1,99 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+SKP_INLINE SKP_int SKP_Silk_setup_complexity(
+ SKP_Silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
+ SKP_int Complexity /* I Complexity (0->low; 1->medium; 2->high) */
+)
+{
+ SKP_int ret = SKP_SILK_NO_ERROR;
+
+ /* Check that settings are valid */
+ if( LOW_COMPLEXITY_ONLY && Complexity != 0 ) {
+ ret = SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING;
+ }
+
+ /* Set encoding complexity */
+ if( Complexity == 0 || LOW_COMPLEXITY_ONLY ) {
+ /* Low complexity */
+ psEncC->Complexity = 0;
+ psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_LC_MODE;
+ psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE, 16 );
+ psEncC->pitchEstimationLPCOrder = 6;
+ psEncC->shapingLPCOrder = 8;
+ psEncC->la_shape = 3 * psEncC->fs_kHz;
+ psEncC->nStatesDelayedDecision = 1;
+ psEncC->useInterpolatedNLSFs = 0;
+ psEncC->LTPQuantLowComplexity = 1;
+ psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_LC_MODE;
+ psEncC->warping_Q16 = 0;
+ } else if( Complexity == 1 ) {
+ /* Medium complexity */
+ psEncC->Complexity = 1;
+ psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_MC_MODE;
+ psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE, 16 );
+ psEncC->pitchEstimationLPCOrder = 12;
+ psEncC->shapingLPCOrder = 12;
+ psEncC->la_shape = 5 * psEncC->fs_kHz;
+ psEncC->nStatesDelayedDecision = 2;
+ psEncC->useInterpolatedNLSFs = 0;
+ psEncC->LTPQuantLowComplexity = 0;
+ psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS_MC_MODE;
+ psEncC->warping_Q16 = psEncC->fs_kHz * SKP_FIX_CONST( WARPING_MULTIPLIER, 16 );
+ } else if( Complexity == 2 ) {
+ /* High complexity */
+ psEncC->Complexity = 2;
+ psEncC->pitchEstimationComplexity = PITCH_EST_COMPLEXITY_HC_MODE;
+ psEncC->pitchEstimationThreshold_Q16 = SKP_FIX_CONST( FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE, 16 );
+ psEncC->pitchEstimationLPCOrder = 16;
+ psEncC->shapingLPCOrder = 16;
+ psEncC->la_shape = 5 * psEncC->fs_kHz;
+ psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
+ psEncC->useInterpolatedNLSFs = 1;
+ psEncC->LTPQuantLowComplexity = 0;
+ psEncC->NLSF_MSVQ_Survivors = MAX_NLSF_MSVQ_SURVIVORS;
+ psEncC->warping_Q16 = psEncC->fs_kHz * SKP_FIX_CONST( WARPING_MULTIPLIER, 16 );
+ } else {
+ ret = SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING;
+ }
+
+ /* Do not allow higher pitch estimation LPC order than predict LPC order */
+ psEncC->pitchEstimationLPCOrder = SKP_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder );
+ psEncC->shapeWinLength = 5 * psEncC->fs_kHz + 2 * psEncC->la_shape;
+
+ SKP_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
+ SKP_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER );
+ SKP_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES );
+ SKP_assert( psEncC->warping_Q16 <= 32767 );
+ SKP_assert( psEncC->la_shape <= LA_SHAPE_MAX );
+ SKP_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX );
+
+ return( ret );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_shell_coder.c b/pkg/silk/csilk/SKP_Silk_shell_coder.c
new file mode 100644
index 0000000..0163ab4
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_shell_coder.c
@@ -0,0 +1,155 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main.h"
+
+/* shell coder; pulse-subframe length is hardcoded */
+
+SKP_INLINE void combine_pulses(
+ SKP_int *out, /* O: combined pulses vector [len] */
+ const SKP_int *in, /* I: input vector [2 * len] */
+ const SKP_int len /* I: number of OUTPUT samples */
+)
+{
+ SKP_int k;
+ for( k = 0; k < len; k++ ) {
+ out[ k ] = in[ 2 * k ] + in[ 2 * k + 1 ];
+ }
+}
+
+SKP_INLINE void encode_split(
+ SKP_Silk_range_coder_state *sRC, /* I/O: compressor data structure */
+ const SKP_int p_child1, /* I: pulse amplitude of first child subframe */
+ const SKP_int p, /* I: pulse amplitude of current subframe */
+ const SKP_uint16 *shell_table /* I: table of shell cdfs */
+)
+{
+ const SKP_uint16 *cdf;
+
+ if( p > 0 ) {
+ cdf = &shell_table[ SKP_Silk_shell_code_table_offsets[ p ] ];
+ SKP_Silk_range_encoder( sRC, p_child1, cdf );
+ }
+}
+
+SKP_INLINE void decode_split(
+ SKP_int *p_child1, /* O: pulse amplitude of first child subframe */
+ SKP_int *p_child2, /* O: pulse amplitude of second child subframe */
+ SKP_Silk_range_coder_state *sRC, /* I/O: compressor data structure */
+ const SKP_int p, /* I: pulse amplitude of current subframe */
+ const SKP_uint16 *shell_table /* I: table of shell cdfs */
+)
+{
+ SKP_int cdf_middle;
+ const SKP_uint16 *cdf;
+
+ if( p > 0 ) {
+ cdf_middle = SKP_RSHIFT( p, 1 );
+ cdf = &shell_table[ SKP_Silk_shell_code_table_offsets[ p ] ];
+ SKP_Silk_range_decoder( p_child1, sRC, cdf, cdf_middle );
+ p_child2[ 0 ] = p - p_child1[ 0 ];
+ } else {
+ p_child1[ 0 ] = 0;
+ p_child2[ 0 ] = 0;
+ }
+}
+
+/* Shell encoder, operates on one shell code frame of 16 pulses */
+void SKP_Silk_shell_encoder(
+ SKP_Silk_range_coder_state *sRC, /* I/O compressor data structure */
+ const SKP_int *pulses0 /* I data: nonnegative pulse amplitudes */
+)
+{
+ SKP_int pulses1[ 8 ], pulses2[ 4 ], pulses3[ 2 ], pulses4[ 1 ];
+
+ /* this function operates on one shell code frame of 16 pulses */
+ SKP_assert( SHELL_CODEC_FRAME_LENGTH == 16 );
+
+ /* tree representation per pulse-subframe */
+ combine_pulses( pulses1, pulses0, 8 );
+ combine_pulses( pulses2, pulses1, 4 );
+ combine_pulses( pulses3, pulses2, 2 );
+ combine_pulses( pulses4, pulses3, 1 );
+
+ encode_split( sRC, pulses3[ 0 ], pulses4[ 0 ], SKP_Silk_shell_code_table3 );
+
+ encode_split( sRC, pulses2[ 0 ], pulses3[ 0 ], SKP_Silk_shell_code_table2 );
+
+ encode_split( sRC, pulses1[ 0 ], pulses2[ 0 ], SKP_Silk_shell_code_table1 );
+ encode_split( sRC, pulses0[ 0 ], pulses1[ 0 ], SKP_Silk_shell_code_table0 );
+ encode_split( sRC, pulses0[ 2 ], pulses1[ 1 ], SKP_Silk_shell_code_table0 );
+
+ encode_split( sRC, pulses1[ 2 ], pulses2[ 1 ], SKP_Silk_shell_code_table1 );
+ encode_split( sRC, pulses0[ 4 ], pulses1[ 2 ], SKP_Silk_shell_code_table0 );
+ encode_split( sRC, pulses0[ 6 ], pulses1[ 3 ], SKP_Silk_shell_code_table0 );
+
+ encode_split( sRC, pulses2[ 2 ], pulses3[ 1 ], SKP_Silk_shell_code_table2 );
+
+ encode_split( sRC, pulses1[ 4 ], pulses2[ 2 ], SKP_Silk_shell_code_table1 );
+ encode_split( sRC, pulses0[ 8 ], pulses1[ 4 ], SKP_Silk_shell_code_table0 );
+ encode_split( sRC, pulses0[ 10 ], pulses1[ 5 ], SKP_Silk_shell_code_table0 );
+
+ encode_split( sRC, pulses1[ 6 ], pulses2[ 3 ], SKP_Silk_shell_code_table1 );
+ encode_split( sRC, pulses0[ 12 ], pulses1[ 6 ], SKP_Silk_shell_code_table0 );
+ encode_split( sRC, pulses0[ 14 ], pulses1[ 7 ], SKP_Silk_shell_code_table0 );
+}
+
+
+/* Shell decoder, operates on one shell code frame of 16 pulses */
+void SKP_Silk_shell_decoder(
+ SKP_int *pulses0, /* O data: nonnegative pulse amplitudes */
+ SKP_Silk_range_coder_state *sRC, /* I/O compressor data structure */
+ const SKP_int pulses4 /* I number of pulses per pulse-subframe */
+)
+{
+ SKP_int pulses3[ 2 ], pulses2[ 4 ], pulses1[ 8 ];
+
+ /* this function operates on one shell code frame of 16 pulses */
+ SKP_assert( SHELL_CODEC_FRAME_LENGTH == 16 );
+
+ decode_split( &pulses3[ 0 ], &pulses3[ 1 ], sRC, pulses4, SKP_Silk_shell_code_table3 );
+
+ decode_split( &pulses2[ 0 ], &pulses2[ 1 ], sRC, pulses3[ 0 ], SKP_Silk_shell_code_table2 );
+
+ decode_split( &pulses1[ 0 ], &pulses1[ 1 ], sRC, pulses2[ 0 ], SKP_Silk_shell_code_table1 );
+ decode_split( &pulses0[ 0 ], &pulses0[ 1 ], sRC, pulses1[ 0 ], SKP_Silk_shell_code_table0 );
+ decode_split( &pulses0[ 2 ], &pulses0[ 3 ], sRC, pulses1[ 1 ], SKP_Silk_shell_code_table0 );
+
+ decode_split( &pulses1[ 2 ], &pulses1[ 3 ], sRC, pulses2[ 1 ], SKP_Silk_shell_code_table1 );
+ decode_split( &pulses0[ 4 ], &pulses0[ 5 ], sRC, pulses1[ 2 ], SKP_Silk_shell_code_table0 );
+ decode_split( &pulses0[ 6 ], &pulses0[ 7 ], sRC, pulses1[ 3 ], SKP_Silk_shell_code_table0 );
+
+ decode_split( &pulses2[ 2 ], &pulses2[ 3 ], sRC, pulses3[ 1 ], SKP_Silk_shell_code_table2 );
+
+ decode_split( &pulses1[ 4 ], &pulses1[ 5 ], sRC, pulses2[ 2 ], SKP_Silk_shell_code_table1 );
+ decode_split( &pulses0[ 8 ], &pulses0[ 9 ], sRC, pulses1[ 4 ], SKP_Silk_shell_code_table0 );
+ decode_split( &pulses0[ 10 ], &pulses0[ 11 ], sRC, pulses1[ 5 ], SKP_Silk_shell_code_table0 );
+
+ decode_split( &pulses1[ 6 ], &pulses1[ 7 ], sRC, pulses2[ 3 ], SKP_Silk_shell_code_table1 );
+ decode_split( &pulses0[ 12 ], &pulses0[ 13 ], sRC, pulses1[ 6 ], SKP_Silk_shell_code_table0 );
+ decode_split( &pulses0[ 14 ], &pulses0[ 15 ], sRC, pulses1[ 7 ], SKP_Silk_shell_code_table0 );
+}
diff --git a/pkg/silk/csilk/SKP_Silk_sigm_Q15.c b/pkg/silk/csilk/SKP_Silk_sigm_Q15.c
new file mode 100644
index 0000000..6a104ab
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_sigm_Q15.c
@@ -0,0 +1,80 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_sigm_Q15.c *
+ * *
+ * Approximate sigmoid function *
+ * *
+ * Copyright 2006 (c), Skype Limited *
+ * Date: 060221 *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+#if EMBEDDED_ARM<4
+/********************************/
+/* approximate sigmoid function */
+/********************************/
+/* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */
+static const SKP_int32 sigm_LUT_slope_Q10[ 6 ] = {
+ 237, 153, 73, 30, 12, 7
+};
+/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */
+static const SKP_int32 sigm_LUT_pos_Q15[ 6 ] = {
+ 16384, 23955, 28861, 31213, 32178, 32548
+};
+/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */
+static const SKP_int32 sigm_LUT_neg_Q15[ 6 ] = {
+ 16384, 8812, 3906, 1554, 589, 219
+};
+
+SKP_int SKP_Silk_sigm_Q15( SKP_int in_Q5 )
+{
+ SKP_int ind;
+
+ if( in_Q5 < 0 ) {
+ /* Negative input */
+ in_Q5 = -in_Q5;
+ if( in_Q5 >= 6 * 32 ) {
+ return 0; /* Clip */
+ } else {
+ /* Linear interpolation of look up table */
+ ind = SKP_RSHIFT( in_Q5, 5 );
+ return( sigm_LUT_neg_Q15[ ind ] - SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
+ }
+ } else {
+ /* Positive input */
+ if( in_Q5 >= 6 * 32 ) {
+ return 32767; /* clip */
+ } else {
+ /* Linear interpolation of look up table */
+ ind = SKP_RSHIFT( in_Q5, 5 );
+ return( sigm_LUT_pos_Q15[ ind ] + SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
+ }
+ }
+}
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_solve_LS_FIX.c b/pkg/silk/csilk/SKP_Silk_solve_LS_FIX.c
new file mode 100644
index 0000000..7f026ec
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_solve_LS_FIX.c
@@ -0,0 +1,241 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+#include "SKP_Silk_tuning_parameters.h"
+
+/*****************************/
+/* Internal function headers */
+/*****************************/
+
+typedef struct {
+ SKP_int32 Q36_part;
+ SKP_int32 Q48_part;
+} inv_D_t;
+
+/* Factorize square matrix A into LDL form */
+SKP_INLINE void SKP_Silk_LDL_factorize_FIX(
+ SKP_int32 *A, /* I/O Pointer to Symetric Square Matrix */
+ SKP_int M, /* I Size of Matrix */
+ SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */
+ inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */
+);
+
+/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
+SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX(
+ const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ SKP_int M, /* I Dim of Matrix equation */
+ const SKP_int32 *b, /* I b Vector */
+ SKP_int32 *x_Q16 /* O x Vector */
+);
+
+/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
+SKP_INLINE void SKP_Silk_LS_SolveLast_FIX(
+ const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ const SKP_int M, /* I Dim of Matrix equation */
+ const SKP_int32 *b, /* I b Vector */
+ SKP_int32 *x_Q16 /* O x Vector */
+);
+
+SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX(
+ SKP_int32 T[], /* I/O Numenator vector */
+ inv_D_t *inv_D, /* I 1 / D vector */
+ SKP_int M /* I dimension */
+);
+
+/* Solves Ax = b, assuming A is symmetric */
+void SKP_Silk_solve_LDL_FIX(
+ SKP_int32 *A, /* I Pointer to symetric square matrix A */
+ SKP_int M, /* I Size of matrix */
+ const SKP_int32 *b, /* I Pointer to b vector */
+ SKP_int32 *x_Q16 /* O Pointer to x solution vector */
+)
+{
+ SKP_int32 L_Q16[ MAX_MATRIX_SIZE * MAX_MATRIX_SIZE ];
+ SKP_int32 Y[ MAX_MATRIX_SIZE ];
+ inv_D_t inv_D[ MAX_MATRIX_SIZE ];
+
+ SKP_assert( M <= MAX_MATRIX_SIZE );
+
+ /***************************************************
+ Factorize A by LDL such that A = L*D*L',
+ where L is lower triangular with ones on diagonal
+ ****************************************************/
+ SKP_Silk_LDL_factorize_FIX( A, M, L_Q16, inv_D );
+
+ /****************************************************
+ * substitute D*L'*x = Y. ie:
+ L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b
+ ******************************************************/
+ SKP_Silk_LS_SolveFirst_FIX( L_Q16, M, b, Y );
+
+ /****************************************************
+ D*L'*x = Y <=> L'*x = inv(D)*Y, because D is
+ diagonal just multiply with 1/d_i
+ ****************************************************/
+ SKP_Silk_LS_divide_Q16_FIX( Y, inv_D, M );
+
+ /****************************************************
+ x = inv(L') * inv(D) * Y
+ *****************************************************/
+ SKP_Silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 );
+}
+
+SKP_INLINE void SKP_Silk_LDL_factorize_FIX(
+ SKP_int32 *A, /* I Pointer to Symetric Square Matrix */
+ SKP_int M, /* I Size of Matrix */
+ SKP_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */
+ inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */
+)
+{
+ SKP_int i, j, k, status, loop_count;
+ const SKP_int32 *ptr1, *ptr2;
+ SKP_int32 diag_min_value, tmp_32, err;
+ SKP_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ];
+ SKP_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48;
+
+ SKP_assert( M <= MAX_MATRIX_SIZE );
+
+ status = 1;
+ diag_min_value = SKP_max_32( SKP_SMMUL( SKP_ADD_SAT32( A[ 0 ], A[ SKP_SMULBB( M, M ) - 1 ] ), SKP_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 );
+ for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) {
+ status = 0;
+ for( j = 0; j < M; j++ ) {
+ ptr1 = matrix_adr( L_Q16, j, 0, M );
+ tmp_32 = 0;
+ for( i = 0; i < j; i++ ) {
+ v_Q0[ i ] = SKP_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */
+ tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */
+ }
+ tmp_32 = SKP_SUB32( matrix_ptr( A, j, j, M ), tmp_32 );
+
+ if( tmp_32 < diag_min_value ) {
+ tmp_32 = SKP_SUB32( SKP_SMULBB( loop_count + 1, diag_min_value ), tmp_32 );
+ /* Matrix not positive semi-definite, or ill conditioned */
+ for( i = 0; i < M; i++ ) {
+ matrix_ptr( A, i, i, M ) = SKP_ADD32( matrix_ptr( A, i, i, M ), tmp_32 );
+ }
+ status = 1;
+ break;
+ }
+ D_Q0[ j ] = tmp_32; /* always < max(Correlation) */
+
+ /* two-step division */
+ one_div_diag_Q36 = SKP_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */
+ one_div_diag_Q40 = SKP_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */
+ err = SKP_SUB32( 1 << 24, SKP_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */
+ one_div_diag_Q48 = SKP_SMULWW( err, one_div_diag_Q40 ); /* Q48 */
+
+ /* Save 1/Ds */
+ inv_D[ j ].Q36_part = one_div_diag_Q36;
+ inv_D[ j ].Q48_part = one_div_diag_Q48;
+
+ matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */
+ ptr1 = matrix_adr( A, j, 0, M );
+ ptr2 = matrix_adr( L_Q16, j + 1, 0, M );
+ for( i = j + 1; i < M; i++ ) {
+ tmp_32 = 0;
+ for( k = 0; k < j; k++ ) {
+ tmp_32 = SKP_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */
+ }
+ tmp_32 = SKP_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */
+
+ /* tmp_32 / D_Q0[j] : Divide to Q16 */
+ matrix_ptr( L_Q16, i, j, M ) = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ),
+ SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
+
+ /* go to next column */
+ ptr2 += M;
+ }
+ }
+ }
+
+ SKP_assert( status == 0 );
+}
+
+SKP_INLINE void SKP_Silk_LS_divide_Q16_FIX(
+ SKP_int32 T[], /* I/O Numenator vector */
+ inv_D_t *inv_D, /* I 1 / D vector */
+ SKP_int M /* I Order */
+)
+{
+ SKP_int i;
+ SKP_int32 tmp_32;
+ SKP_int32 one_div_diag_Q36, one_div_diag_Q48;
+
+ for( i = 0; i < M; i++ ) {
+ one_div_diag_Q36 = inv_D[ i ].Q36_part;
+ one_div_diag_Q48 = inv_D[ i ].Q48_part;
+
+ tmp_32 = T[ i ];
+ T[ i ] = SKP_ADD32( SKP_SMMUL( tmp_32, one_div_diag_Q48 ), SKP_RSHIFT( SKP_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
+ }
+}
+
+/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
+SKP_INLINE void SKP_Silk_LS_SolveFirst_FIX(
+ const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ SKP_int M, /* I Dim of Matrix equation */
+ const SKP_int32 *b, /* I b Vector */
+ SKP_int32 *x_Q16 /* O x Vector */
+)
+{
+ SKP_int i, j;
+ const SKP_int32 *ptr32;
+ SKP_int32 tmp_32;
+
+ for( i = 0; i < M; i++ ) {
+ ptr32 = matrix_adr( L_Q16, i, 0, M );
+ tmp_32 = 0;
+ for( j = 0; j < i; j++ ) {
+ tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] );
+ }
+ x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 );
+ }
+}
+
+/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
+SKP_INLINE void SKP_Silk_LS_SolveLast_FIX(
+ const SKP_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ const SKP_int M, /* I Dim of Matrix equation */
+ const SKP_int32 *b, /* I b Vector */
+ SKP_int32 *x_Q16 /* O x Vector */
+)
+{
+ SKP_int i, j;
+ const SKP_int32 *ptr32;
+ SKP_int32 tmp_32;
+
+ for( i = M - 1; i >= 0; i-- ) {
+ ptr32 = matrix_adr( L_Q16, 0, i, M );
+ tmp_32 = 0;
+ for( j = M - 1; j > i; j-- ) {
+ tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ SKP_SMULBB( j, M ) ], x_Q16[ j ] );
+ }
+ x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 );
+ }
+}
diff --git a/pkg/silk/csilk/SKP_Silk_sort.c b/pkg/silk/csilk/SKP_Silk_sort.c
new file mode 100644
index 0000000..3753c7b
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_sort.c
@@ -0,0 +1,147 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* Insertion sort (fast for already almost sorted arrays): */
+/* Best case: O(n) for an already sorted array */
+/* Worst case: O(n^2) for an inversely sorted array */
+
+#include "SKP_Silk_SigProc_FIX.h"
+
+void SKP_Silk_insertion_sort_increasing(
+ SKP_int32 *a, /* I/O: Unsorted / Sorted vector */
+ SKP_int *index, /* O: Index vector for the sorted elements */
+ const SKP_int L, /* I: Vector length */
+ const SKP_int K /* I: Number of correctly sorted output positions */
+)
+{
+ SKP_int32 value;
+ SKP_int i, j;
+
+ /* Safety checks */
+ SKP_assert( K > 0 );
+ SKP_assert( L > 0 );
+ SKP_assert( L >= K );
+
+ /* Write start indices in index vector */
+ for( i = 0; i < K; i++ ) {
+ index[ i ] = i;
+ }
+
+ /* Sort vector elements by value, increasing order */
+ for( i = 1; i < K; i++ ) {
+ value = a[ i ];
+ for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {
+ a[ j + 1 ] = a[ j ]; /* Shift value */
+ index[ j + 1 ] = index[ j ]; /* Shift index */
+ }
+ a[ j + 1 ] = value; /* Write value */
+ index[ j + 1 ] = i; /* Write index */
+ }
+
+ /* If less than L values are asked for, check the remaining values, */
+ /* but only spend CPU to ensure that the K first values are correct */
+ for( i = K; i < L; i++ ) {
+ value = a[ i ];
+ if( value < a[ K - 1 ] ) {
+ for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {
+ a[ j + 1 ] = a[ j ]; /* Shift value */
+ index[ j + 1 ] = index[ j ]; /* Shift index */
+ }
+ a[ j + 1 ] = value; /* Write value */
+ index[ j + 1 ] = i; /* Write index */
+ }
+ }
+}
+
+void SKP_Silk_insertion_sort_decreasing_int16(
+ SKP_int16 *a, /* I/O: Unsorted / Sorted vector */
+ SKP_int *index, /* O: Index vector for the sorted elements */
+ const SKP_int L, /* I: Vector length */
+ const SKP_int K /* I: Number of correctly sorted output positions */
+)
+{
+ SKP_int i, j;
+ SKP_int value;
+
+ /* Safety checks */
+ SKP_assert( K > 0 );
+ SKP_assert( L > 0 );
+ SKP_assert( L >= K );
+
+ /* Write start indices in index vector */
+ for( i = 0; i < K; i++ ) {
+ index[ i ] = i;
+ }
+
+ /* Sort vector elements by value, decreasing order */
+ for( i = 1; i < K; i++ ) {
+ value = a[ i ];
+ for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {
+ a[ j + 1 ] = a[ j ]; /* Shift value */
+ index[ j + 1 ] = index[ j ]; /* Shift index */
+ }
+ a[ j + 1 ] = value; /* Write value */
+ index[ j + 1 ] = i; /* Write index */
+ }
+
+ /* If less than L values are asked for, check the remaining values, */
+ /* but only spend CPU to ensure that the K first values are correct */
+ for( i = K; i < L; i++ ) {
+ value = a[ i ];
+ if( value > a[ K - 1 ] ) {
+ for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {
+ a[ j + 1 ] = a[ j ]; /* Shift value */
+ index[ j + 1 ] = index[ j ]; /* Shift index */
+ }
+ a[ j + 1 ] = value; /* Write value */
+ index[ j + 1 ] = i; /* Write index */
+ }
+ }
+}
+
+void SKP_Silk_insertion_sort_increasing_all_values(
+ SKP_int *a, /* I/O: Unsorted / Sorted vector */
+ const SKP_int L /* I: Vector length */
+)
+{
+ SKP_int value;
+ SKP_int i, j;
+
+ /* Safety checks */
+ SKP_assert( L > 0 );
+
+ /* Sort vector elements by value, increasing order */
+ for( i = 1; i < L; i++ ) {
+ value = a[ i ];
+ for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) {
+ a[ j + 1 ] = a[ j ]; /* Shift value */
+ }
+ a[ j + 1 ] = value; /* Write value */
+ }
+}
+
+
diff --git a/pkg/silk/csilk/SKP_Silk_structs.h b/pkg/silk/csilk/SKP_Silk_structs.h
new file mode 100644
index 0000000..4cb1db5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_structs.h
@@ -0,0 +1,353 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_STRUCTS_H
+#define SKP_SILK_STRUCTS_H
+
+#include "SKP_Silk_typedef.h"
+#include "SKP_Silk_SigProc_FIX.h"
+#include "SKP_Silk_define.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************************/
+/* Noise shaping quantization state */
+/************************************/
+typedef struct {
+ SKP_int16 xq[ 2 * MAX_FRAME_LENGTH ]; /* Buffer for quantized output signal */
+ SKP_int32 sLTP_shp_Q10[ 2 * MAX_FRAME_LENGTH ];
+ SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + NSQ_LPC_BUF_LENGTH ];
+ SKP_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
+ SKP_int32 sLF_AR_shp_Q12;
+ SKP_int lagPrev;
+ SKP_int sLTP_buf_idx;
+ SKP_int sLTP_shp_buf_idx;
+ SKP_int32 rand_seed;
+ SKP_int32 prev_inv_gain_Q16;
+ SKP_int rewhite_flag;
+} SKP_Silk_nsq_state; /* FIX*/
+
+/* Struct for Low BitRate Redundant (LBRR) information */
+typedef struct {
+ SKP_uint8 payload[ MAX_ARITHM_BYTES ];
+ SKP_int nBytes; /* Number of bytes in payload */
+ SKP_int usage; /* Tells how the payload should be used as FEC */
+} SKP_SILK_LBRR_struct;
+
+/********************************/
+/* VAD state */
+/********************************/
+typedef struct {
+ SKP_int32 AnaState[ 2 ]; /* Analysis filterbank state: 0-8 kHz */
+ SKP_int32 AnaState1[ 2 ]; /* Analysis filterbank state: 0-4 kHz */
+ SKP_int32 AnaState2[ 2 ]; /* Analysis filterbank state: 0-2 kHz */
+ SKP_int32 XnrgSubfr[ VAD_N_BANDS ]; /* Subframe energies */
+ SKP_int32 NrgRatioSmth_Q8[ VAD_N_BANDS ]; /* Smoothed energy level in each band */
+ SKP_int16 HPstate; /* State of differentiator in the lowest band */
+ SKP_int32 NL[ VAD_N_BANDS ]; /* Noise energy level in each band */
+ SKP_int32 inv_NL[ VAD_N_BANDS ]; /* Inverse noise energy level in each band */
+ SKP_int32 NoiseLevelBias[ VAD_N_BANDS ]; /* Noise level estimator bias/offset */
+ SKP_int32 counter; /* Frame counter used in the initial phase */
+} SKP_Silk_VAD_state;
+
+/*******************************/
+/* Range encoder/decoder state */
+/*******************************/
+typedef struct {
+ SKP_int32 bufferLength;
+ SKP_int32 bufferIx;
+ SKP_uint32 base_Q32;
+ SKP_uint32 range_Q16;
+ SKP_int32 error;
+ SKP_uint8 buffer[ MAX_ARITHM_BYTES ]; /* Buffer containing payload */
+} SKP_Silk_range_coder_state;
+
+/* Input frequency range detection struct */
+typedef struct {
+ SKP_int32 S_HP_8_kHz[ NB_SOS ][ 2 ]; /* HP filter State */
+ SKP_int32 ConsecSmplsAboveThres;
+ SKP_int32 ActiveSpeech_ms; /* Accumulated time with active speech */
+ SKP_int SWB_detected; /* Flag to indicate SWB input */
+ SKP_int WB_detected; /* Flag to indicate WB input */
+} SKP_Silk_detect_SWB_state;
+
+#if SWITCH_TRANSITION_FILTERING
+/* Variable cut-off low-pass filter state */
+typedef struct {
+ SKP_int32 In_LP_State[ 2 ]; /* Low pass filter state */
+ SKP_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */
+ SKP_int mode; /* Operating mode, 0: switch down, 1: switch up */
+} SKP_Silk_LP_state;
+#endif
+
+/* Structure for one stage of MSVQ */
+typedef struct {
+ const SKP_int32 nVectors;
+ const SKP_int16 *CB_NLSF_Q15;
+ const SKP_int16 *Rates_Q5;
+} SKP_Silk_NLSF_CBS;
+
+/* Structure containing NLSF MSVQ codebook */
+typedef struct {
+ const SKP_int32 nStages;
+
+ /* Fields for (de)quantizing */
+ const SKP_Silk_NLSF_CBS *CBStages;
+ const SKP_int *NDeltaMin_Q15;
+
+ /* Fields for arithmetic (de)coding */
+ const SKP_uint16 *CDF;
+ const SKP_uint16 * const *StartPtr;
+ const SKP_int *MiddleIx;
+} SKP_Silk_NLSF_CB_struct;
+
+/********************************/
+/* Encoder state */
+/********************************/
+typedef struct {
+ SKP_Silk_range_coder_state sRC; /* Range coder state */
+ SKP_Silk_range_coder_state sRC_LBRR; /* Range coder state (for low bitrate redundancy) */
+ SKP_Silk_nsq_state sNSQ; /* Noise Shape Quantizer State */
+ SKP_Silk_nsq_state sNSQ_LBRR; /* Noise Shape Quantizer State ( for low bitrate redundancy ) */
+
+#if HIGH_PASS_INPUT
+ SKP_int32 In_HP_State[ 2 ]; /* High pass filter state */
+#endif
+#if SWITCH_TRANSITION_FILTERING
+ SKP_Silk_LP_state sLP; /* Low pass filter state */
+#endif
+ SKP_Silk_VAD_state sVAD; /* Voice activity detector state */
+
+ SKP_int LBRRprevLastGainIndex;
+ SKP_int prev_sigtype;
+ SKP_int typeOffsetPrev; /* Previous signal type and quantization offset */
+ SKP_int prevLag;
+ SKP_int prev_lagIndex;
+ SKP_int32 API_fs_Hz; /* API sampling frequency (Hz) */
+ SKP_int32 prev_API_fs_Hz; /* Previous API sampling frequency (Hz) */
+ SKP_int maxInternal_fs_kHz; /* Maximum internal sampling frequency (kHz) */
+ SKP_int fs_kHz; /* Internal sampling frequency (kHz) */
+ SKP_int fs_kHz_changed; /* Did we switch yet? */
+ SKP_int frame_length; /* Frame length (samples) */
+ SKP_int subfr_length; /* Subframe length (samples) */
+ SKP_int la_pitch; /* Look-ahead for pitch analysis (samples) */
+ SKP_int la_shape; /* Look-ahead for noise shape analysis (samples) */
+ SKP_int shapeWinLength; /* Window length for noise shape analysis (samples) */
+ SKP_int32 TargetRate_bps; /* Target bitrate (bps) */
+ SKP_int PacketSize_ms; /* Number of milliseconds to put in each packet */
+ SKP_int PacketLoss_perc; /* Packet loss rate measured by farend */
+ SKP_int32 frameCounter;
+ SKP_int Complexity; /* Complexity setting: 0-> low; 1-> medium; 2->high */
+ SKP_int nStatesDelayedDecision; /* Number of states in delayed decision quantization */
+ SKP_int useInterpolatedNLSFs; /* Flag for using NLSF interpolation */
+ SKP_int shapingLPCOrder; /* Filter order for noise shaping filters */
+ SKP_int predictLPCOrder; /* Filter order for prediction filters */
+ SKP_int pitchEstimationComplexity; /* Complexity level for pitch estimator */
+ SKP_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */
+ SKP_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */
+ SKP_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */
+ SKP_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */
+ SKP_int first_frame_after_reset; /* Flag for deactivating NLSF interp. and fluc. reduction after resets */
+ SKP_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */
+ SKP_int warping_Q16; /* Warping parameter for warped noise shaping */
+
+ /* Input/output buffering */
+ SKP_int16 inputBuf[ MAX_FRAME_LENGTH ]; /* buffer containin input signal */
+ SKP_int inputBufIx;
+ SKP_int nFramesInPayloadBuf; /* number of frames sitting in outputBuf */
+ SKP_int nBytesInPayloadBuf; /* number of bytes sitting in outputBuf */
+
+ /* Parameters For LTP scaling Control */
+ SKP_int frames_since_onset;
+
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB[ 2 ]; /* Pointers to voiced/unvoiced NLSF codebooks */
+
+ /* Struct for Inband LBRR */
+ SKP_SILK_LBRR_struct LBRR_buffer[ MAX_LBRR_DELAY ];
+ SKP_int oldest_LBRR_idx;
+ SKP_int useInBandFEC; /* Saves the API setting for query */
+ SKP_int LBRR_enabled;
+ SKP_int LBRR_GainIncreases; /* Number of shifts to Gains to get LBRR rate Voiced frames */
+
+ /* Bitrate control */
+ SKP_int32 bitrateDiff; /* Accumulated diff. between the target bitrate and the switch bitrates */
+ SKP_int32 bitrate_threshold_up; /* Threshold for switching to a higher internal sample frequency */
+ SKP_int32 bitrate_threshold_down; /* Threshold for switching to a lower internal sample frequency */
+
+ SKP_Silk_resampler_state_struct resampler_state;
+
+ /* DTX */
+ SKP_int noSpeechCounter; /* Counts concecutive nonactive frames, used by DTX */
+ SKP_int useDTX; /* Flag to enable DTX */
+ SKP_int inDTX; /* Flag to signal DTX period */
+ SKP_int vadFlag; /* Flag to indicate Voice Activity */
+
+ /* Struct for detecting SWB input */
+ SKP_Silk_detect_SWB_state sSWBdetect;
+
+
+ /* Buffers */
+ SKP_int8 q[ MAX_FRAME_LENGTH ]; /* pulse signal buffer */
+ SKP_int8 q_LBRR[ MAX_FRAME_LENGTH ]; /* pulse signal buffer */
+
+} SKP_Silk_encoder_state;
+
+
+/************************/
+/* Encoder control */
+/************************/
+typedef struct {
+ /* Quantization indices */
+ SKP_int lagIndex;
+ SKP_int contourIndex;
+ SKP_int PERIndex;
+ SKP_int LTPIndex[ NB_SUBFR ];
+ SKP_int NLSFIndices[ NLSF_MSVQ_MAX_CB_STAGES ]; /* NLSF path of quantized LSF vector */
+ SKP_int NLSFInterpCoef_Q2;
+ SKP_int GainsIndices[ NB_SUBFR ];
+ SKP_int32 Seed;
+ SKP_int LTP_scaleIndex;
+ SKP_int RateLevelIndex;
+ SKP_int QuantOffsetType;
+ SKP_int sigtype;
+
+ /* Prediction and coding parameters */
+ SKP_int pitchL[ NB_SUBFR ];
+
+ SKP_int LBRR_usage; /* Low bitrate redundancy usage */
+} SKP_Silk_encoder_control;
+
+/* Struct for Packet Loss Concealment */
+typedef struct {
+ SKP_int32 pitchL_Q8; /* Pitch lag to use for voiced concealment */
+ SKP_int16 LTPCoef_Q14[ LTP_ORDER ]; /* LTP coeficients to use for voiced concealment */
+ SKP_int16 prevLPC_Q12[ MAX_LPC_ORDER ];
+ SKP_int last_frame_lost; /* Was previous frame lost */
+ SKP_int32 rand_seed; /* Seed for unvoiced signal generation */
+ SKP_int16 randScale_Q14; /* Scaling of unvoiced random signal */
+ SKP_int32 conc_energy;
+ SKP_int conc_energy_shift;
+ SKP_int16 prevLTP_scale_Q14;
+ SKP_int32 prevGain_Q16[ NB_SUBFR ];
+ SKP_int fs_kHz;
+} SKP_Silk_PLC_struct;
+
+/* Struct for CNG */
+typedef struct {
+ SKP_int32 CNG_exc_buf_Q10[ MAX_FRAME_LENGTH ];
+ SKP_int CNG_smth_NLSF_Q15[ MAX_LPC_ORDER ];
+ SKP_int32 CNG_synth_state[ MAX_LPC_ORDER ];
+ SKP_int32 CNG_smth_Gain_Q16;
+ SKP_int32 rand_seed;
+ SKP_int fs_kHz;
+} SKP_Silk_CNG_struct;
+
+/********************************/
+/* Decoder state */
+/********************************/
+typedef struct {
+ SKP_Silk_range_coder_state sRC; /* Range coder state */
+ SKP_int32 prev_inv_gain_Q16;
+ SKP_int32 sLTP_Q16[ 2 * MAX_FRAME_LENGTH ];
+ SKP_int32 sLPC_Q14[ MAX_FRAME_LENGTH / NB_SUBFR + MAX_LPC_ORDER ];
+ SKP_int32 exc_Q10[ MAX_FRAME_LENGTH ];
+ SKP_int32 res_Q10[ MAX_FRAME_LENGTH ];
+ SKP_int16 outBuf[ 2 * MAX_FRAME_LENGTH ]; /* Buffer for output signal */
+ SKP_int lagPrev; /* Previous Lag */
+ SKP_int LastGainIndex; /* Previous gain index */
+ SKP_int LastGainIndex_EnhLayer; /* Previous gain index */
+ SKP_int typeOffsetPrev; /* Previous signal type and quantization offset */
+ SKP_int32 HPState[ DEC_HP_ORDER ]; /* HP filter state */
+ const SKP_int16 *HP_A; /* HP filter AR coefficients */
+ const SKP_int16 *HP_B; /* HP filter MA coefficients */
+ SKP_int fs_kHz; /* Sampling frequency in kHz */
+ SKP_int32 prev_API_sampleRate; /* Previous API sample frequency (Hz) */
+ SKP_int frame_length; /* Frame length (samples) */
+ SKP_int subfr_length; /* Subframe length (samples) */
+ SKP_int LPC_order; /* LPC order */
+ SKP_int prevNLSF_Q15[ MAX_LPC_ORDER ]; /* Used to interpolate LSFs */
+ SKP_int first_frame_after_reset; /* Flag for deactivating NLSF interp. and fluc. reduction after resets */
+
+ /* For buffering payload in case of more frames per packet */
+ SKP_int nBytesLeft;
+ SKP_int nFramesDecoded;
+ SKP_int nFramesInPacket;
+ SKP_int moreInternalDecoderFrames;
+ SKP_int FrameTermination;
+
+ SKP_Silk_resampler_state_struct resampler_state;
+
+ const SKP_Silk_NLSF_CB_struct *psNLSF_CB[ 2 ]; /* Pointers to voiced/unvoiced NLSF codebooks */
+
+ /* Parameters used to investigate if inband FEC is used */
+ SKP_int vadFlag;
+ SKP_int no_FEC_counter; /* Counts number of frames wo inband FEC */
+ SKP_int inband_FEC_offset; /* 0: no FEC, 1: FEC with 1 packet offset, 2: FEC w 2 packets offset */
+
+ /* CNG state */
+ SKP_Silk_CNG_struct sCNG;
+
+ /* Stuff used for PLC */
+ SKP_int lossCnt;
+ SKP_int prev_sigtype; /* Previous sigtype */
+
+ SKP_Silk_PLC_struct sPLC;
+
+
+
+} SKP_Silk_decoder_state;
+
+/************************/
+/* Decoder control */
+/************************/
+typedef struct {
+ /* prediction and coding parameters */
+ SKP_int pitchL[ NB_SUBFR ];
+ SKP_int32 Gains_Q16[ NB_SUBFR ];
+ SKP_int32 Seed;
+ /* holds interpolated and final coefficients, 4-byte aligned */
+ SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
+ SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ];
+ SKP_int LTP_scale_Q14;
+
+ /* quantization indices */
+ SKP_int PERIndex;
+ SKP_int RateLevelIndex;
+ SKP_int QuantOffsetType;
+ SKP_int sigtype;
+ SKP_int NLSFInterpCoef_Q2;
+} SKP_Silk_decoder_control;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_structs_FIX.h b/pkg/silk/csilk/SKP_Silk_structs_FIX.h
new file mode 100644
index 0000000..967c90c
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_structs_FIX.h
@@ -0,0 +1,151 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_STRUCTS_FIX_H
+#define SKP_SILK_STRUCTS_FIX_H
+
+#include "SKP_Silk_typedef.h"
+#include "SKP_Silk_main.h"
+#include "SKP_Silk_structs.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/********************************/
+/* Noise shaping analysis state */
+/********************************/
+typedef struct {
+ SKP_int LastGainIndex;
+ SKP_int32 HarmBoost_smth_Q16;
+ SKP_int32 HarmShapeGain_smth_Q16;
+ SKP_int32 Tilt_smth_Q16;
+} SKP_Silk_shape_state_FIX;
+
+/********************************/
+/* Prefilter state */
+/********************************/
+typedef struct {
+ SKP_int16 sLTP_shp[ LTP_BUF_LENGTH ];
+ SKP_int32 sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ]; // Q14
+ SKP_int sLTP_shp_buf_idx;
+ SKP_int32 sLF_AR_shp_Q12;
+ SKP_int32 sLF_MA_shp_Q12;
+ SKP_int sHarmHP;
+ SKP_int32 rand_seed;
+ SKP_int lagPrev;
+} SKP_Silk_prefilter_state_FIX;
+
+/*****************************/
+/* Prediction analysis state */
+/*****************************/
+typedef struct {
+ SKP_int pitch_LPC_win_length;
+ SKP_int min_pitch_lag; /* Lowest possible pitch lag (samples) */
+ SKP_int max_pitch_lag; /* Highest possible pitch lag (samples) */
+ SKP_int prev_NLSFq_Q15[ MAX_LPC_ORDER ]; /* Previously quantized NLSF vector */
+} SKP_Silk_predict_state_FIX;
+
+
+/********************************/
+/* Encoder state FIX */
+/********************************/
+typedef struct {
+ SKP_Silk_encoder_state sCmn; /* Common struct, shared with floating-point code */
+
+#if HIGH_PASS_INPUT
+ SKP_int32 variable_HP_smth1_Q15; /* State of first smoother */
+ SKP_int32 variable_HP_smth2_Q15; /* State of second smoother */
+#endif
+ SKP_Silk_shape_state_FIX sShape; /* Shape state */
+ SKP_Silk_prefilter_state_FIX sPrefilt; /* Prefilter State */
+ SKP_Silk_predict_state_FIX sPred; /* Prediction state */
+
+ /* Buffer for find pitch and noise shape analysis */
+ SKP_DWORD_ALIGN SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];
+ SKP_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator, approx Q15 */
+ SKP_int mu_LTP_Q8; /* Rate-distortion tradeoff in LTP quantization */
+ SKP_int32 SNR_dB_Q7; /* Quality setting */
+ SKP_int32 avgGain_Q16; /* average gain during active speech */
+ SKP_int32 avgGain_Q16_one_bit_per_sample; /* average gain during active speech */
+ SKP_int BufferedInChannel_ms; /* Simulated number of ms buffer because of exceeded TargetRate_bps */
+ SKP_int speech_activity_Q8; /* Speech activity in Q8 */
+
+ /* Parameters For LTP scaling Control */
+ SKP_int prevLTPredCodGain_Q7;
+ SKP_int HPLTPredCodGain_Q7;
+
+ SKP_int32 inBandFEC_SNR_comp_Q8; /* Compensation to SNR_dB when using inband FEC Voiced */
+
+} SKP_Silk_encoder_state_FIX;
+
+/************************/
+/* Encoder control FIX */
+/************************/
+typedef struct {
+ SKP_Silk_encoder_control sCmn; /* Common struct, shared with floating-point code */
+
+ /* Prediction and coding parameters */
+ SKP_int32 Gains_Q16[ NB_SUBFR ];
+ SKP_DWORD_ALIGN SKP_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
+ SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ];
+ SKP_int LTP_scale_Q14;
+
+ /* Noise shaping parameters */
+ /* Testing */
+ SKP_DWORD_ALIGN SKP_int16 AR1_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+ SKP_DWORD_ALIGN SKP_int16 AR2_Q13[ NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+ SKP_int32 LF_shp_Q14[ NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
+ SKP_int GainsPre_Q14[ NB_SUBFR ];
+ SKP_int HarmBoost_Q14[ NB_SUBFR ];
+ SKP_int Tilt_Q14[ NB_SUBFR ];
+ SKP_int HarmShapeGain_Q14[ NB_SUBFR ];
+ SKP_int Lambda_Q10;
+ SKP_int input_quality_Q14;
+ SKP_int coding_quality_Q14;
+ SKP_int32 pitch_freq_low_Hz;
+ SKP_int current_SNR_dB_Q7;
+
+ /* measures */
+ SKP_int sparseness_Q8;
+ SKP_int32 predGain_Q16;
+ SKP_int LTPredCodGain_Q7;
+ SKP_int input_quality_bands_Q15[ VAD_N_BANDS ];
+ SKP_int input_tilt_Q15;
+ SKP_int32 ResNrg[ NB_SUBFR ]; /* Residual energy per subframe */
+ SKP_int ResNrgQ[ NB_SUBFR ]; /* Q domain for the residual energy > 0 */
+
+} SKP_Silk_encoder_control_FIX;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_sum_sqr_shift.c b/pkg/silk/csilk/SKP_Silk_sum_sqr_shift.c
new file mode 100644
index 0000000..a67ecbe
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_sum_sqr_shift.c
@@ -0,0 +1,102 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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.
+***********************************************************************/
+
+/* *
+ * SKP_Silk_sum_sqr_shift.c *
+ * *
+ * compute number of bits to right shift the sum of squares of a vector *
+ * of int16s to make it fit in an int32 *
+ * *
+ * Copyright 2006-2008 (c), Skype Limited *
+ * */
+#include "SKP_Silk_SigProc_FIX.h"
+#if (EMBEDDED_ARM<5)
+/* Compute number of bits to right shift the sum of squares of a vector */
+/* of int16s to make it fit in an int32 */
+void SKP_Silk_sum_sqr_shift(
+ SKP_int32 *energy, /* O Energy of x, after shifting to the right */
+ SKP_int *shift, /* O Number of bits right shift applied to energy */
+ const SKP_int16 *x, /* I Input vector */
+ SKP_int len /* I Length of input vector */
+)
+{
+ SKP_int i, shft;
+ SKP_int32 in32, nrg_tmp, nrg;
+
+ if( (SKP_int32)( (SKP_int_ptr_size)x & 2 ) != 0 ) {
+ /* Input is not 4-byte aligned */
+ nrg = SKP_SMULBB( x[ 0 ], x[ 0 ] );
+ i = 1;
+ } else {
+ nrg = 0;
+ i = 0;
+ }
+ shft = 0;
+ len--;
+ while( i < len ) {
+ /* Load two values at once */
+ in32 = *( (SKP_int32 *)&x[ i ] );
+ nrg = SKP_SMLABB_ovflw( nrg, in32, in32 );
+ nrg = SKP_SMLATT_ovflw( nrg, in32, in32 );
+ i += 2;
+ if( nrg < 0 ) {
+ /* Scale down */
+ nrg = (SKP_int32)SKP_RSHIFT_uint( (SKP_uint32)nrg, 2 );
+ shft = 2;
+ break;
+ }
+ }
+ for( ; i < len; i += 2 ) {
+ /* Load two values at once */
+ in32 = *( (SKP_int32 *)&x[ i ] );
+ nrg_tmp = SKP_SMULBB( in32, in32 );
+ nrg_tmp = SKP_SMLATT_ovflw( nrg_tmp, in32, in32 );
+ nrg = (SKP_int32)SKP_ADD_RSHIFT_uint( nrg, (SKP_uint32)nrg_tmp, shft );
+ if( nrg < 0 ) {
+ /* Scale down */
+ nrg = (SKP_int32)SKP_RSHIFT_uint( (SKP_uint32)nrg, 2 );
+ shft += 2;
+ }
+ }
+ if( i == len ) {
+ /* One sample left to process */
+ nrg_tmp = SKP_SMULBB( x[ i ], x[ i ] );
+ nrg = (SKP_int32)SKP_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
+ }
+
+ /* Make sure to have at least one extra leading zero (two leading zeros in total) */
+ if( nrg & 0xC0000000 ) {
+ nrg = SKP_RSHIFT_uint( (SKP_uint32)nrg, 2 );
+ shft += 2;
+ }
+
+ /* Output arguments */
+ *shift = shft;
+ *energy = nrg;
+}
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_tables.h b/pkg/silk/csilk/SKP_Silk_tables.h
new file mode 100644
index 0000000..37613bd
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables.h
@@ -0,0 +1,168 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_TABLES_H
+#define SKP_SILK_TABLES_H
+
+#include "SKP_Silk_define.h"
+#include "SKP_Silk_structs.h"
+
+#define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */
+#define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* entropy coding tables */
+extern const SKP_uint16 SKP_Silk_type_offset_CDF[ 5 ]; /* 5 */
+extern const SKP_uint16 SKP_Silk_type_offset_joint_CDF[ 4 ][ 5 ]; /* 20 */
+extern const SKP_int SKP_Silk_type_offset_CDF_offset;
+
+extern const SKP_uint16 SKP_Silk_gain_CDF[ 2 ][ N_LEVELS_QGAIN + 1 ]; /* 130 */
+extern const SKP_int SKP_Silk_gain_CDF_offset;
+extern const SKP_uint16 SKP_Silk_delta_gain_CDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 2 ]; /* 46 */
+extern const SKP_int SKP_Silk_delta_gain_CDF_offset;
+
+extern const SKP_uint16 SKP_Silk_pitch_lag_NB_CDF[ 8 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 130 */
+extern const SKP_int SKP_Silk_pitch_lag_NB_CDF_offset;
+extern const SKP_uint16 SKP_Silk_pitch_lag_MB_CDF[ 12 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 194 */
+extern const SKP_int SKP_Silk_pitch_lag_MB_CDF_offset;
+extern const SKP_uint16 SKP_Silk_pitch_lag_WB_CDF[ 16 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 258 */
+extern const SKP_int SKP_Silk_pitch_lag_WB_CDF_offset;
+extern const SKP_uint16 SKP_Silk_pitch_lag_SWB_CDF[ 24 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ]; /* 386 */
+extern const SKP_int SKP_Silk_pitch_lag_SWB_CDF_offset;
+
+extern const SKP_uint16 SKP_Silk_pitch_contour_CDF[ 35 ]; /* 35 */
+extern const SKP_int SKP_Silk_pitch_contour_CDF_offset;
+extern const SKP_uint16 SKP_Silk_pitch_contour_NB_CDF[ 12 ]; /* 12 */
+extern const SKP_int SKP_Silk_pitch_contour_NB_CDF_offset;
+extern const SKP_uint16 SKP_Silk_pitch_delta_CDF[23]; /* 23 */
+extern const SKP_int SKP_Silk_pitch_delta_CDF_offset;
+
+extern const SKP_uint16 SKP_Silk_pulses_per_block_CDF[ N_RATE_LEVELS ][ MAX_PULSES + 3 ]; /* 210 */
+extern const SKP_int SKP_Silk_pulses_per_block_CDF_offset;
+extern const SKP_int16 SKP_Silk_pulses_per_block_BITS_Q6[ N_RATE_LEVELS - 1 ][ MAX_PULSES + 2 ]; /* 180 */
+
+extern const SKP_uint16 SKP_Silk_rate_levels_CDF[ 2 ][ N_RATE_LEVELS ]; /* 20 */
+extern const SKP_int SKP_Silk_rate_levels_CDF_offset;
+extern const SKP_int16 SKP_Silk_rate_levels_BITS_Q6[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */
+
+extern const SKP_int SKP_Silk_max_pulses_table[ 4 ]; /* 4 */
+
+extern const SKP_uint16 SKP_Silk_shell_code_table0[ 33 ]; /* 33 */
+extern const SKP_uint16 SKP_Silk_shell_code_table1[ 52 ]; /* 52 */
+extern const SKP_uint16 SKP_Silk_shell_code_table2[ 102 ]; /* 102 */
+extern const SKP_uint16 SKP_Silk_shell_code_table3[ 207 ]; /* 207 */
+extern const SKP_uint16 SKP_Silk_shell_code_table_offsets[ 19 ]; /* 19 */
+
+extern const SKP_uint16 SKP_Silk_lsb_CDF[ 3 ]; /* 3 */
+
+extern const SKP_uint16 SKP_Silk_sign_CDF[ 36 ]; /* 36 */
+
+extern const SKP_uint16 SKP_Silk_LTP_per_index_CDF[ 4 ]; /* 4 */
+extern const SKP_int SKP_Silk_LTP_per_index_CDF_offset;
+extern const SKP_int16 * const SKP_Silk_LTP_gain_BITS_Q6_ptrs[ NB_LTP_CBKS ]; /* 3 */
+extern const SKP_uint16 * const SKP_Silk_LTP_gain_CDF_ptrs[ NB_LTP_CBKS ]; /* 3 */
+extern const SKP_int SKP_Silk_LTP_gain_CDF_offsets[ NB_LTP_CBKS ]; /* 3 */
+extern const SKP_int32 SKP_Silk_LTP_gain_middle_avg_RD_Q14;
+extern const SKP_uint16 SKP_Silk_LTPscale_CDF[ 4 ]; /* 4 */
+extern const SKP_int SKP_Silk_LTPscale_offset;
+
+/* Tables for LTPScale */
+extern const SKP_int16 SKP_Silk_LTPScales_table_Q14[ 3 ];
+
+extern const SKP_uint16 SKP_Silk_vadflag_CDF[ 3 ]; /* 3 */
+extern const SKP_int SKP_Silk_vadflag_offset;
+
+extern const SKP_int SKP_Silk_SamplingRates_table[ 4 ]; /* 4 */
+extern const SKP_uint16 SKP_Silk_SamplingRates_CDF[ 5 ]; /* 5 */
+extern const SKP_int SKP_Silk_SamplingRates_offset;
+
+extern const SKP_uint16 SKP_Silk_NLSF_interpolation_factor_CDF[ 6 ];
+extern const SKP_int SKP_Silk_NLSF_interpolation_factor_offset;
+
+/* NLSF codebooks */
+extern const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_16, SKP_Silk_NLSF_CB1_16;
+extern const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_10, SKP_Silk_NLSF_CB1_10;
+
+/* quantization tables */
+extern const SKP_int16 * const SKP_Silk_LTP_vq_ptrs_Q14[ NB_LTP_CBKS ]; /* 168 */
+extern const SKP_int SKP_Silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */
+
+/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
+extern const SKP_int32 TargetRate_table_NB[ TARGET_RATE_TAB_SZ ];
+extern const SKP_int32 TargetRate_table_MB[ TARGET_RATE_TAB_SZ ];
+extern const SKP_int32 TargetRate_table_WB[ TARGET_RATE_TAB_SZ ];
+extern const SKP_int32 TargetRate_table_SWB[ TARGET_RATE_TAB_SZ ];
+extern const SKP_int32 SNR_table_Q1[ TARGET_RATE_TAB_SZ ];
+
+extern const SKP_int32 SNR_table_one_bit_per_sample_Q7[ 4 ];
+
+/* Filter coeficicnts for HP filter: 4. Order filter implementad as two biquad filters */
+extern const SKP_int16 SKP_Silk_SWB_detect_B_HP_Q13[ NB_SOS ][ 3 ];
+extern const SKP_int16 SKP_Silk_SWB_detect_A_HP_Q13[ NB_SOS ][ 2 ];
+
+/* Decoder high-pass filter coefficients for 24 kHz sampling */
+extern const SKP_int16 SKP_Silk_Dec_A_HP_24[ DEC_HP_ORDER ]; /* 2 */
+extern const SKP_int16 SKP_Silk_Dec_B_HP_24[ DEC_HP_ORDER + 1 ]; /* 3 */
+
+/* Decoder high-pass filter coefficients for 16 kHz sampling */
+extern const SKP_int16 SKP_Silk_Dec_A_HP_16[ DEC_HP_ORDER ]; /* 2 */
+extern const SKP_int16 SKP_Silk_Dec_B_HP_16[ DEC_HP_ORDER + 1 ]; /* 3 */
+
+/* Decoder high-pass filter coefficients for 12 kHz sampling */
+extern const SKP_int16 SKP_Silk_Dec_A_HP_12[ DEC_HP_ORDER ]; /* 2 */
+extern const SKP_int16 SKP_Silk_Dec_B_HP_12[ DEC_HP_ORDER + 1 ]; /* 3 */
+
+/* Decoder high-pass filter coefficients for 8 kHz sampling */
+extern const SKP_int16 SKP_Silk_Dec_A_HP_8[ DEC_HP_ORDER ]; /* 2 */
+extern const SKP_int16 SKP_Silk_Dec_B_HP_8[ DEC_HP_ORDER + 1 ]; /* 3 */
+
+/* Table for frame termination indication */
+extern const SKP_uint16 SKP_Silk_FrameTermination_CDF[ 5 ];
+extern const SKP_int SKP_Silk_FrameTermination_offset;
+
+/* Table for random seed */
+extern const SKP_uint16 SKP_Silk_Seed_CDF[ 5 ];
+extern const SKP_int SKP_Silk_Seed_offset;
+
+/* Quantization offsets */
+extern const SKP_int16 SKP_Silk_Quantization_Offsets_Q10[ 2 ][ 2 ];
+
+#if SWITCH_TRANSITION_FILTERING
+/* Interpolation points for filter coefficients used in the bandwidth transition smoother */
+extern const SKP_int32 SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ];
+extern const SKP_int32 SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ];
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_tables_LTP.c b/pkg/silk/csilk/SKP_Silk_tables_LTP.c
new file mode 100644
index 0000000..77533ab
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_LTP.c
@@ -0,0 +1,324 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_LTP_per_index_CDF[ 4 ] = {
+ 0, 20992, 40788, 65535
+};
+
+const SKP_int SKP_Silk_LTP_per_index_CDF_offset = 1;
+
+
+const SKP_uint16 SKP_Silk_LTP_gain_CDF_0[ 11 ] = {
+ 0, 49380, 54463, 56494, 58437, 60101, 61683, 62985,
+ 64066, 64823, 65535
+};
+
+const SKP_uint16 SKP_Silk_LTP_gain_CDF_1[ 21 ] = {
+ 0, 25290, 30654, 35710, 40386, 42937, 45250, 47459,
+ 49411, 51348, 52974, 54517, 55976, 57423, 58865, 60285,
+ 61667, 62895, 63827, 64724, 65535
+};
+
+const SKP_uint16 SKP_Silk_LTP_gain_CDF_2[ 41 ] = {
+ 0, 4958, 9439, 13581, 17638, 21651, 25015, 28025,
+ 30287, 32406, 34330, 36240, 38130, 39790, 41281, 42764,
+ 44229, 45676, 47081, 48431, 49675, 50849, 51932, 52966,
+ 53957, 54936, 55869, 56789, 57708, 58504, 59285, 60043,
+ 60796, 61542, 62218, 62871, 63483, 64076, 64583, 65062,
+ 65535
+};
+
+const SKP_int SKP_Silk_LTP_gain_CDF_offsets[ 3 ] = {
+ 1, 3, 10
+};
+
+const SKP_int32 SKP_Silk_LTP_gain_middle_avg_RD_Q14 = 11010;
+
+const SKP_int16 SKP_Silk_LTP_gain_BITS_Q6_0[ 10 ] = {
+ 26, 236, 321, 325, 339, 344, 362, 379,
+ 412, 418
+};
+
+const SKP_int16 SKP_Silk_LTP_gain_BITS_Q6_1[ 20 ] = {
+ 88, 231, 237, 244, 300, 309, 313, 324,
+ 325, 341, 346, 351, 352, 352, 354, 356,
+ 367, 393, 396, 406
+};
+
+const SKP_int16 SKP_Silk_LTP_gain_BITS_Q6_2[ 40 ] = {
+ 238, 248, 255, 257, 258, 274, 284, 311,
+ 317, 326, 326, 327, 339, 349, 350, 351,
+ 352, 355, 358, 366, 371, 379, 383, 387,
+ 388, 393, 394, 394, 407, 409, 412, 412,
+ 413, 422, 426, 432, 434, 449, 454, 455
+};
+
+const SKP_uint16 * const SKP_Silk_LTP_gain_CDF_ptrs[ NB_LTP_CBKS ] = {
+ SKP_Silk_LTP_gain_CDF_0,
+ SKP_Silk_LTP_gain_CDF_1,
+ SKP_Silk_LTP_gain_CDF_2
+};
+
+const SKP_int16 * const SKP_Silk_LTP_gain_BITS_Q6_ptrs[ NB_LTP_CBKS ] = {
+ SKP_Silk_LTP_gain_BITS_Q6_0,
+ SKP_Silk_LTP_gain_BITS_Q6_1,
+ SKP_Silk_LTP_gain_BITS_Q6_2
+};
+
+const SKP_int16 SKP_Silk_LTP_gain_vq_0_Q14[ 10 ][ 5 ] =
+{
+{
+ 594, 984, 2840, 1021, 669
+},
+{
+ 10, 35, 304, -1, 23
+},
+{
+ -694, 1923, 4603, 2975, 2335
+},
+{
+ 2437, 3176, 3778, 1940, 481
+},
+{
+ 214, -46, 7870, 4406, -521
+},
+{
+ -896, 4818, 8501, 1623, -887
+},
+{
+ -696, 3178, 6480, -302, 1081
+},
+{
+ 517, 599, 1002, 567, 560
+},
+{
+ -2075, -834, 4712, -340, 896
+},
+{
+ 1435, -644, 3993, -612, -2063
+}
+};
+
+const SKP_int16 SKP_Silk_LTP_gain_vq_1_Q14[ 20 ][ 5 ] =
+{
+{
+ 1655, 2918, 5001, 3010, 1775
+},
+{
+ 113, 198, 856, 176, 178
+},
+{
+ -843, 2479, 7858, 5371, 574
+},
+{
+ 59, 5356, 7648, 2850, -315
+},
+{
+ 3840, 4851, 6527, 1583, -1233
+},
+{
+ 1620, 1760, 2330, 1876, 2045
+},
+{
+ -545, 1854, 11792, 1547, -307
+},
+{
+ -604, 689, 5369, 5074, 4265
+},
+{
+ 521, -1331, 9829, 6209, -1211
+},
+{
+ -1315, 6747, 9929, -1410, 546
+},
+{
+ 117, -144, 2810, 1649, 5240
+},
+{
+ 5392, 3476, 2425, -38, 633
+},
+{
+ 14, -449, 5274, 3547, -171
+},
+{
+ -98, 395, 9114, 1676, 844
+},
+{
+ -908, 3843, 8861, -957, 1474
+},
+{
+ 396, 6747, 5379, -329, 1269
+},
+{
+ -335, 2830, 4281, 270, -54
+},
+{
+ 1502, 5609, 8958, 6045, 2059
+},
+{
+ -370, 479, 5267, 5726, 1174
+},
+{
+ 5237, -1144, 6510, 455, 512
+}
+};
+
+const SKP_int16 SKP_Silk_LTP_gain_vq_2_Q14[ 40 ][ 5 ] =
+{
+{
+ -278, 415, 9345, 7106, -431
+},
+{
+ -1006, 3863, 9524, 4724, -871
+},
+{
+ -954, 4624, 11722, 973, -300
+},
+{
+ -117, 7066, 8331, 1959, -901
+},
+{
+ 593, 3412, 6070, 4914, 1567
+},
+{
+ 54, -51, 12618, 4228, -844
+},
+{
+ 3157, 4822, 5229, 2313, 717
+},
+{
+ -244, 1161, 14198, 779, 69
+},
+{
+ -1218, 5603, 12894, -2301, 1001
+},
+{
+ -132, 3960, 9526, 577, 1806
+},
+{
+ -1633, 8815, 10484, -2452, 895
+},
+{
+ 235, 450, 1243, 667, 437
+},
+{
+ 959, -2630, 10897, 8772, -1852
+},
+{
+ 2420, 2046, 8893, 4427, -1569
+},
+{
+ 23, 7091, 8356, -1285, 1508
+},
+{
+ -1133, 835, 7662, 6043, 2800
+},
+{
+ 439, 391, 11016, 2253, 1362
+},
+{
+ -1020, 2876, 13436, 4015, -3020
+},
+{
+ 1060, -2690, 13512, 5565, -1394
+},
+{
+ -1420, 8007, 11421, -152, -1672
+},
+{
+ -893, 2895, 15434, -1490, 159
+},
+{
+ -1054, 428, 12208, 8538, -3344
+},
+{
+ 1772, -1304, 7593, 6185, 561
+},
+{
+ 525, -1207, 6659, 11151, -1170
+},
+{
+ 439, 2667, 4743, 2359, 5515
+},
+{
+ 2951, 7432, 7909, -230, -1564
+},
+{
+ -72, 2140, 5477, 1391, 1580
+},
+{
+ 476, -1312, 15912, 2174, -1027
+},
+{
+ 5737, 441, 2493, 2043, 2757
+},
+{
+ 228, -43, 1803, 6663, 7064
+},
+{
+ 4596, 9182, 1917, -200, 203
+},
+{
+ -704, 12039, 5451, -1188, 542
+},
+{
+ 1782, -1040, 10078, 7513, -2767
+},
+{
+ -2626, 7747, 9019, 62, 1710
+},
+{
+ 235, -233, 2954, 10921, 1947
+},
+{
+ 10854, 2814, 1232, -111, 222
+},
+{
+ 2267, 2778, 12325, 156, -1658
+},
+{
+ -2950, 8095, 16330, 268, -3626
+},
+{
+ 67, 2083, 7950, -80, -2432
+},
+{
+ 518, -66, 1718, 415, 11435
+}
+};
+
+const SKP_int16 * const SKP_Silk_LTP_vq_ptrs_Q14[ NB_LTP_CBKS ] = {
+ &SKP_Silk_LTP_gain_vq_0_Q14[ 0 ][ 0 ],
+ &SKP_Silk_LTP_gain_vq_1_Q14[ 0 ][ 0 ],
+ &SKP_Silk_LTP_gain_vq_2_Q14[ 0 ][ 0 ]
+};
+
+const SKP_int SKP_Silk_LTP_vq_sizes[ NB_LTP_CBKS ] = {
+ 10, 20, 40
+};
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_10.c b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_10.c
new file mode 100644
index 0000000..d91bda3
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_10.c
@@ -0,0 +1,890 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 file has been automatically generated */
+/* */
+/* ROM usage: 0.29 + 2.66 kB */
+/**********************************************/
+
+#include "SKP_Silk_structs.h"
+#include "SKP_Silk_tables_NLSF_CB0_10.h"
+#include "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ NLSF_MSVQ_CB0_10_VECTORS + NLSF_MSVQ_CB0_10_STAGES ] =
+{
+ 0,
+ 2658,
+ 4420,
+ 6107,
+ 7757,
+ 9408,
+ 10955,
+ 12502,
+ 13983,
+ 15432,
+ 16882,
+ 18331,
+ 19750,
+ 21108,
+ 22409,
+ 23709,
+ 25010,
+ 26256,
+ 27501,
+ 28747,
+ 29965,
+ 31158,
+ 32351,
+ 33544,
+ 34736,
+ 35904,
+ 36997,
+ 38091,
+ 39185,
+ 40232,
+ 41280,
+ 42327,
+ 43308,
+ 44290,
+ 45271,
+ 46232,
+ 47192,
+ 48132,
+ 49032,
+ 49913,
+ 50775,
+ 51618,
+ 52462,
+ 53287,
+ 54095,
+ 54885,
+ 55675,
+ 56449,
+ 57222,
+ 57979,
+ 58688,
+ 59382,
+ 60076,
+ 60726,
+ 61363,
+ 61946,
+ 62505,
+ 63052,
+ 63543,
+ 63983,
+ 64396,
+ 64766,
+ 65023,
+ 65279,
+ 65535,
+ 0,
+ 4977,
+ 9542,
+ 14106,
+ 18671,
+ 23041,
+ 27319,
+ 31596,
+ 35873,
+ 39969,
+ 43891,
+ 47813,
+ 51652,
+ 55490,
+ 59009,
+ 62307,
+ 65535,
+ 0,
+ 8571,
+ 17142,
+ 25529,
+ 33917,
+ 42124,
+ 49984,
+ 57844,
+ 65535,
+ 0,
+ 8732,
+ 17463,
+ 25825,
+ 34007,
+ 42189,
+ 50196,
+ 58032,
+ 65535,
+ 0,
+ 8948,
+ 17704,
+ 25733,
+ 33762,
+ 41791,
+ 49821,
+ 57678,
+ 65535,
+ 0,
+ 4374,
+ 8655,
+ 12936,
+ 17125,
+ 21313,
+ 25413,
+ 29512,
+ 33611,
+ 37710,
+ 41809,
+ 45820,
+ 49832,
+ 53843,
+ 57768,
+ 61694,
+ 65535
+};
+
+const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr[ NLSF_MSVQ_CB0_10_STAGES ] =
+{
+ &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 0 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 65 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 82 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 91 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 100 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ 109 ]
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx[ NLSF_MSVQ_CB0_10_STAGES ] =
+{
+ 23,
+ 8,
+ 5,
+ 5,
+ 5,
+ 9
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ NLSF_MSVQ_CB0_10_VECTORS ] =
+{
+ 148, 167,
+ 169, 170,
+ 170, 173,
+ 173, 175,
+ 176, 176,
+ 176, 177,
+ 179, 181,
+ 181, 181,
+ 183, 183,
+ 183, 184,
+ 185, 185,
+ 185, 185,
+ 186, 189,
+ 189, 189,
+ 191, 191,
+ 191, 194,
+ 194, 194,
+ 195, 195,
+ 196, 198,
+ 199, 200,
+ 201, 201,
+ 202, 203,
+ 204, 204,
+ 205, 205,
+ 206, 209,
+ 210, 210,
+ 213, 214,
+ 218, 220,
+ 221, 226,
+ 231, 234,
+ 239, 256,
+ 256, 256,
+ 119, 123,
+ 123, 123,
+ 125, 126,
+ 126, 126,
+ 128, 130,
+ 130, 131,
+ 131, 135,
+ 138, 139,
+ 94, 94,
+ 95, 95,
+ 96, 98,
+ 98, 99,
+ 93, 93,
+ 95, 96,
+ 96, 97,
+ 98, 100,
+ 92, 93,
+ 97, 97,
+ 97, 97,
+ 98, 98,
+ 125, 126,
+ 126, 127,
+ 127, 128,
+ 128, 128,
+ 128, 128,
+ 129, 129,
+ 129, 130,
+ 130, 131
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min_Q15[ 10 + 1 ] =
+{
+ 563,
+ 3,
+ 22,
+ 20,
+ 3,
+ 3,
+ 132,
+ 119,
+ 358,
+ 86,
+ 964
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * NLSF_MSVQ_CB0_10_VECTORS ] =
+{
+ 2210, 4023,
+ 6981, 9260,
+ 12573, 15687,
+ 19207, 22383,
+ 25981, 29142,
+ 3285, 4172,
+ 6116, 10856,
+ 15289, 16826,
+ 19701, 22010,
+ 24721, 29313,
+ 1554, 2511,
+ 6577, 10337,
+ 13837, 16511,
+ 20086, 23214,
+ 26480, 29464,
+ 3062, 4017,
+ 5771, 10037,
+ 13365, 14952,
+ 20140, 22891,
+ 25229, 29603,
+ 2085, 3457,
+ 5934, 8718,
+ 11501, 13670,
+ 17997, 21817,
+ 24935, 28745,
+ 2776, 4093,
+ 6421, 10413,
+ 15111, 16806,
+ 20825, 23826,
+ 26308, 29411,
+ 2717, 4034,
+ 5697, 8463,
+ 14301, 16354,
+ 19007, 23413,
+ 25812, 28506,
+ 2872, 3702,
+ 5881, 11034,
+ 17141, 18879,
+ 21146, 23451,
+ 25817, 29600,
+ 2999, 4015,
+ 7357, 11219,
+ 12866, 17307,
+ 20081, 22644,
+ 26774, 29107,
+ 2942, 3866,
+ 5918, 11915,
+ 13909, 16072,
+ 20453, 22279,
+ 27310, 29826,
+ 2271, 3527,
+ 6606, 9729,
+ 12943, 17382,
+ 20224, 22345,
+ 24602, 28290,
+ 2207, 3310,
+ 5844, 9339,
+ 11141, 15651,
+ 18576, 21177,
+ 25551, 28228,
+ 3963, 4975,
+ 6901, 11588,
+ 13466, 15577,
+ 19231, 21368,
+ 25510, 27759,
+ 2749, 3549,
+ 6966, 13808,
+ 15653, 17645,
+ 20090, 22599,
+ 26467, 28537,
+ 2126, 3504,
+ 5109, 9954,
+ 12550, 14620,
+ 19703, 21687,
+ 26457, 29106,
+ 3966, 5745,
+ 7442, 9757,
+ 14468, 16404,
+ 19135, 23048,
+ 25375, 28391,
+ 3197, 4751,
+ 6451, 9298,
+ 13038, 14874,
+ 17962, 20627,
+ 23835, 28464,
+ 3195, 4081,
+ 6499, 12252,
+ 14289, 16040,
+ 18357, 20730,
+ 26980, 29309,
+ 1533, 2471,
+ 4486, 7796,
+ 12332, 15758,
+ 19567, 22298,
+ 25673, 29051,
+ 2002, 2971,
+ 4985, 8083,
+ 13181, 15435,
+ 18237, 21517,
+ 24595, 28351,
+ 3808, 4925,
+ 6710, 10201,
+ 12011, 14300,
+ 18457, 20391,
+ 26525, 28956,
+ 2281, 3418,
+ 4979, 8726,
+ 15964, 18104,
+ 20250, 22771,
+ 25286, 28954,
+ 3051, 5479,
+ 7290, 9848,
+ 12744, 14503,
+ 18665, 23684,
+ 26065, 28947,
+ 2364, 3565,
+ 5502, 9621,
+ 14922, 16621,
+ 19005, 20996,
+ 26310, 29302,
+ 4093, 5212,
+ 6833, 9880,
+ 16303, 18286,
+ 20571, 23614,
+ 26067, 29128,
+ 2941, 3996,
+ 6038, 10638,
+ 12668, 14451,
+ 16798, 19392,
+ 26051, 28517,
+ 3863, 5212,
+ 7019, 9468,
+ 11039, 13214,
+ 19942, 22344,
+ 25126, 29539,
+ 4615, 6172,
+ 7853, 10252,
+ 12611, 14445,
+ 19719, 22441,
+ 24922, 29341,
+ 3566, 4512,
+ 6985, 8684,
+ 10544, 16097,
+ 18058, 22475,
+ 26066, 28167,
+ 4481, 5489,
+ 7432, 11414,
+ 13191, 15225,
+ 20161, 22258,
+ 26484, 29716,
+ 3320, 4320,
+ 6621, 9867,
+ 11581, 14034,
+ 21168, 23210,
+ 26588, 29903,
+ 3794, 4689,
+ 6916, 8655,
+ 10143, 16144,
+ 19568, 21588,
+ 27557, 29593,
+ 2446, 3276,
+ 5918, 12643,
+ 16601, 18013,
+ 21126, 23175,
+ 27300, 29634,
+ 2450, 3522,
+ 5437, 8560,
+ 15285, 19911,
+ 21826, 24097,
+ 26567, 29078,
+ 2580, 3796,
+ 5580, 8338,
+ 9969, 12675,
+ 18907, 22753,
+ 25450, 29292,
+ 3325, 4312,
+ 6241, 7709,
+ 9164, 14452,
+ 21665, 23797,
+ 27096, 29857,
+ 3338, 4163,
+ 7738, 11114,
+ 12668, 14753,
+ 16931, 22736,
+ 25671, 28093,
+ 3840, 4755,
+ 7755, 13471,
+ 15338, 17180,
+ 20077, 22353,
+ 27181, 29743,
+ 2504, 4079,
+ 8351, 12118,
+ 15046, 18595,
+ 21684, 24704,
+ 27519, 29937,
+ 5234, 6342,
+ 8267, 11821,
+ 15155, 16760,
+ 20667, 23488,
+ 25949, 29307,
+ 2681, 3562,
+ 6028, 10827,
+ 18458, 20458,
+ 22303, 24701,
+ 26912, 29956,
+ 3374, 4528,
+ 6230, 8256,
+ 9513, 12730,
+ 18666, 20720,
+ 26007, 28425,
+ 2731, 3629,
+ 8320, 12450,
+ 14112, 16431,
+ 18548, 22098,
+ 25329, 27718,
+ 3481, 4401,
+ 7321, 9319,
+ 11062, 13093,
+ 15121, 22315,
+ 26331, 28740,
+ 3577, 4945,
+ 6669, 8792,
+ 10299, 12645,
+ 19505, 24766,
+ 26996, 29634,
+ 4058, 5060,
+ 7288, 10190,
+ 11724, 13936,
+ 15849, 18539,
+ 26701, 29845,
+ 4262, 5390,
+ 7057, 8982,
+ 10187, 15264,
+ 20480, 22340,
+ 25958, 28072,
+ 3404, 4329,
+ 6629, 7946,
+ 10121, 17165,
+ 19640, 22244,
+ 25062, 27472,
+ 3157, 4168,
+ 6195, 9319,
+ 10771, 13325,
+ 15416, 19816,
+ 24672, 27634,
+ 2503, 3473,
+ 5130, 6767,
+ 8571, 14902,
+ 19033, 21926,
+ 26065, 28728,
+ 4133, 5102,
+ 7553, 10054,
+ 11757, 14924,
+ 17435, 20186,
+ 23987, 26272,
+ 4972, 6139,
+ 7894, 9633,
+ 11320, 14295,
+ 21737, 24306,
+ 26919, 29907,
+ 2958, 3816,
+ 6851, 9204,
+ 10895, 18052,
+ 20791, 23338,
+ 27556, 29609,
+ 5234, 6028,
+ 8034, 10154,
+ 11242, 14789,
+ 18948, 20966,
+ 26585, 29127,
+ 5241, 6838,
+ 10526, 12819,
+ 14681, 17328,
+ 19928, 22336,
+ 26193, 28697,
+ 3412, 4251,
+ 5988, 7094,
+ 9907, 18243,
+ 21669, 23777,
+ 26969, 29087,
+ 2470, 3217,
+ 7797, 15296,
+ 17365, 19135,
+ 21979, 24256,
+ 27322, 29442,
+ 4939, 5804,
+ 8145, 11809,
+ 13873, 15598,
+ 17234, 19423,
+ 26476, 29645,
+ 5051, 6167,
+ 8223, 9655,
+ 12159, 17995,
+ 20464, 22832,
+ 26616, 28462,
+ 4987, 5907,
+ 9319, 11245,
+ 13132, 15024,
+ 17485, 22687,
+ 26011, 28273,
+ 5137, 6884,
+ 11025, 14950,
+ 17191, 19425,
+ 21807, 24393,
+ 26938, 29288,
+ 7057, 7884,
+ 9528, 10483,
+ 10960, 14811,
+ 19070, 21675,
+ 25645, 28019,
+ 6759, 7160,
+ 8546, 11779,
+ 12295, 13023,
+ 16627, 21099,
+ 24697, 28287,
+ 3863, 9762,
+ 11068, 11445,
+ 12049, 13960,
+ 18085, 21507,
+ 25224, 28997,
+ 397, 335,
+ 651, 1168,
+ 640, 765,
+ 465, 331,
+ 214, -194,
+ -578, -647,
+ -657, 750,
+ 564, 613,
+ 549, 630,
+ 304, -52,
+ 828, 922,
+ 443, 111,
+ 138, 124,
+ 169, 14,
+ 144, 83,
+ 132, 58,
+ -413, -752,
+ 869, 336,
+ 385, 69,
+ 56, 830,
+ -227, -266,
+ -368, -440,
+ -1195, 163,
+ 126, -228,
+ 802, 156,
+ 188, 120,
+ 376, 59,
+ -358, -558,
+ -1326, -254,
+ -202, -789,
+ 296, 92,
+ -70, -129,
+ -718, -1135,
+ 292, -29,
+ -631, 487,
+ -157, -153,
+ -279, 2,
+ -419, -342,
+ -34, -514,
+ -799, -1571,
+ -687, -609,
+ -546, -130,
+ -215, -252,
+ -446, -574,
+ -1337, 207,
+ -72, 32,
+ 103, -642,
+ 942, 733,
+ 187, 29,
+ -211, -814,
+ 143, 225,
+ 20, 24,
+ -268, -377,
+ 1623, 1133,
+ 667, 164,
+ 307, 366,
+ 187, 34,
+ 62, -313,
+ -832, -1482,
+ -1181, 483,
+ -42, -39,
+ -450, -1406,
+ -587, -52,
+ -760, 334,
+ 98, -60,
+ -500, -488,
+ -1058, 299,
+ 131, -250,
+ -251, -703,
+ 1037, 568,
+ -413, -265,
+ 1687, 573,
+ 345, 323,
+ 98, 61,
+ -102, 31,
+ 135, 149,
+ 617, 365,
+ -39, 34,
+ -611, 1201,
+ 1421, 736,
+ -414, -393,
+ -492, -343,
+ -316, -532,
+ 528, 172,
+ 90, 322,
+ -294, -319,
+ -541, 503,
+ 639, 401,
+ 1, -149,
+ -73, -167,
+ 150, 118,
+ 308, 218,
+ 121, 195,
+ -143, -261,
+ -1013, -802,
+ 387, 436,
+ 130, -427,
+ -448, -681,
+ 123, -87,
+ -251, -113,
+ 274, 310,
+ 445, 501,
+ 354, 272,
+ 141, -285,
+ 569, 656,
+ 37, -49,
+ 251, -386,
+ -263, 1122,
+ 604, 606,
+ 336, 95,
+ 34, 0,
+ 85, 180,
+ 207, -367,
+ -622, 1070,
+ -6, -79,
+ -160, -92,
+ -137, -276,
+ -323, -371,
+ -696, -1036,
+ 407, 102,
+ -86, -214,
+ -482, -647,
+ -28, -291,
+ -97, -180,
+ -250, -435,
+ -18, -76,
+ -332, 410,
+ 407, 168,
+ 539, 411,
+ 254, 111,
+ 58, -145,
+ 200, 30,
+ 187, 116,
+ 131, -367,
+ -475, 781,
+ -559, 561,
+ 195, -115,
+ 8, -168,
+ 30, 55,
+ -122, 131,
+ 82, -5,
+ -273, -50,
+ -632, 668,
+ 4, 32,
+ -26, -279,
+ 315, 165,
+ 197, 377,
+ 155, -41,
+ -138, -324,
+ -109, -617,
+ 360, 98,
+ -53, -319,
+ -114, -245,
+ -82, 507,
+ 468, 263,
+ -137, -389,
+ 652, 354,
+ -18, -227,
+ -462, -135,
+ 317, 53,
+ -16, 66,
+ -72, -126,
+ -356, -347,
+ -328, -72,
+ -337, 324,
+ 152, 349,
+ 169, -196,
+ 179, 254,
+ 260, 325,
+ -74, -80,
+ 75, -31,
+ 270, 275,
+ 87, 278,
+ -446, -301,
+ 309, 71,
+ -25, -242,
+ 516, 161,
+ -162, -83,
+ 329, 230,
+ -311, -259,
+ 177, -26,
+ -462, 89,
+ 257, 6,
+ -130, -93,
+ -456, -317,
+ -221, -206,
+ -417, -182,
+ -74, 234,
+ 48, 261,
+ 359, 231,
+ 258, 85,
+ -282, 252,
+ -147, -222,
+ 251, -207,
+ 443, 123,
+ -417, -36,
+ 273, -241,
+ 240, -112,
+ 44, -167,
+ 126, -124,
+ -77, 58,
+ -401, 333,
+ -118, 82,
+ 126, 151,
+ -433, 359,
+ -130, -102,
+ 131, -244,
+ 86, 85,
+ -462, 414,
+ -240, 16,
+ 145, 28,
+ -205, -481,
+ 373, 293,
+ -72, -174,
+ 62, 259,
+ -8, -18,
+ 362, 233,
+ 185, 43,
+ 278, 27,
+ 193, 570,
+ -248, 189,
+ 92, 31,
+ -275, -3,
+ 243, 176,
+ 438, 209,
+ 206, -51,
+ 79, 109,
+ 168, -185,
+ -308, -68,
+ -618, 385,
+ -310, -108,
+ -164, 165,
+ 61, -152,
+ -101, -412,
+ -268, -257,
+ -40, -20,
+ -28, -158,
+ -301, 271,
+ 380, -338,
+ -367, -132,
+ 64, 114,
+ -131, -225,
+ -156, -260,
+ -63, -116,
+ 155, -586,
+ -202, 254,
+ -287, 178,
+ 227, -106,
+ -294, 164,
+ 298, -100,
+ 185, 317,
+ 193, -45,
+ 28, 80,
+ -87, -433,
+ 22, -48,
+ 48, -237,
+ -229, -139,
+ 120, -364,
+ 268, -136,
+ 396, 125,
+ 130, -89,
+ -272, 118,
+ -256, -68,
+ -451, 488,
+ 143, -165,
+ -48, -190,
+ 106, 219,
+ 47, 435,
+ 245, 97,
+ 75, -418,
+ 121, -187,
+ 570, -200,
+ -351, 225,
+ -21, -217,
+ 234, -111,
+ 194, 14,
+ 242, 118,
+ 140, -397,
+ 355, 361,
+ -45, -195
+};
+
+const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB0_10_Stage_info[ NLSF_MSVQ_CB0_10_STAGES ] =
+{
+ { 64, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 0 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 0 ] },
+ { 16, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 64 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 64 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 80 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 80 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 88 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 88 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 96 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 96 ] },
+ { 16, &SKP_Silk_NLSF_MSVQ_CB0_10_Q15[ 10 * 104 ], &SKP_Silk_NLSF_MSVQ_CB0_10_rates_Q5[ 104 ] }
+};
+
+const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_10 =
+{
+ NLSF_MSVQ_CB0_10_STAGES,
+ SKP_Silk_NLSF_CB0_10_Stage_info,
+ SKP_Silk_NLSF_MSVQ_CB0_10_ndelta_min_Q15,
+ SKP_Silk_NLSF_MSVQ_CB0_10_CDF,
+ SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr,
+ SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_10.h b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_10.h
new file mode 100644
index 0000000..37e2906
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_10.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_TABLES_NLSF_CB0_10_H
+#define SKP_SILK_TABLES_NLSF_CB0_10_H
+
+#include "SKP_Silk_define.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define NLSF_MSVQ_CB0_10_STAGES 6
+#define NLSF_MSVQ_CB0_10_VECTORS 120
+
+/* NLSF codebook entropy coding tables */
+extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_10_CDF[ NLSF_MSVQ_CB0_10_VECTORS + NLSF_MSVQ_CB0_10_STAGES ];
+extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_10_CDF_start_ptr[ NLSF_MSVQ_CB0_10_STAGES ];
+extern const SKP_int SKP_Silk_NLSF_MSVQ_CB0_10_CDF_middle_idx[ NLSF_MSVQ_CB0_10_STAGES ];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_16.c b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_16.c
new file mode 100644
index 0000000..cfa87c6
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_16.c
@@ -0,0 +1,1320 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 file has been automatically generated */
+/* */
+/* ROM usage: 0.51 + 7.38 kB */
+/**********************************************/
+
+#include "SKP_Silk_structs.h"
+#include "SKP_Silk_tables_NLSF_CB0_16.h"
+#include "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ NLSF_MSVQ_CB0_16_VECTORS + NLSF_MSVQ_CB0_16_STAGES ] =
+{
+ 0,
+ 1449,
+ 2749,
+ 4022,
+ 5267,
+ 6434,
+ 7600,
+ 8647,
+ 9695,
+ 10742,
+ 11681,
+ 12601,
+ 13444,
+ 14251,
+ 15008,
+ 15764,
+ 16521,
+ 17261,
+ 18002,
+ 18710,
+ 19419,
+ 20128,
+ 20837,
+ 21531,
+ 22225,
+ 22919,
+ 23598,
+ 24277,
+ 24956,
+ 25620,
+ 26256,
+ 26865,
+ 27475,
+ 28071,
+ 28667,
+ 29263,
+ 29859,
+ 30443,
+ 31026,
+ 31597,
+ 32168,
+ 32727,
+ 33273,
+ 33808,
+ 34332,
+ 34855,
+ 35379,
+ 35902,
+ 36415,
+ 36927,
+ 37439,
+ 37941,
+ 38442,
+ 38932,
+ 39423,
+ 39914,
+ 40404,
+ 40884,
+ 41364,
+ 41844,
+ 42324,
+ 42805,
+ 43285,
+ 43754,
+ 44224,
+ 44694,
+ 45164,
+ 45623,
+ 46083,
+ 46543,
+ 46993,
+ 47443,
+ 47892,
+ 48333,
+ 48773,
+ 49213,
+ 49653,
+ 50084,
+ 50515,
+ 50946,
+ 51377,
+ 51798,
+ 52211,
+ 52614,
+ 53018,
+ 53422,
+ 53817,
+ 54212,
+ 54607,
+ 55002,
+ 55388,
+ 55775,
+ 56162,
+ 56548,
+ 56910,
+ 57273,
+ 57635,
+ 57997,
+ 58352,
+ 58698,
+ 59038,
+ 59370,
+ 59702,
+ 60014,
+ 60325,
+ 60630,
+ 60934,
+ 61239,
+ 61537,
+ 61822,
+ 62084,
+ 62346,
+ 62602,
+ 62837,
+ 63072,
+ 63302,
+ 63517,
+ 63732,
+ 63939,
+ 64145,
+ 64342,
+ 64528,
+ 64701,
+ 64867,
+ 65023,
+ 65151,
+ 65279,
+ 65407,
+ 65535,
+ 0,
+ 5099,
+ 9982,
+ 14760,
+ 19538,
+ 24213,
+ 28595,
+ 32976,
+ 36994,
+ 41012,
+ 44944,
+ 48791,
+ 52557,
+ 56009,
+ 59388,
+ 62694,
+ 65535,
+ 0,
+ 9955,
+ 19697,
+ 28825,
+ 36842,
+ 44686,
+ 52198,
+ 58939,
+ 65535,
+ 0,
+ 8949,
+ 17335,
+ 25720,
+ 33926,
+ 41957,
+ 49987,
+ 57845,
+ 65535,
+ 0,
+ 9724,
+ 18642,
+ 26998,
+ 35355,
+ 43532,
+ 51534,
+ 59365,
+ 65535,
+ 0,
+ 8750,
+ 17499,
+ 26249,
+ 34448,
+ 42471,
+ 50494,
+ 58178,
+ 65535,
+ 0,
+ 8730,
+ 17273,
+ 25816,
+ 34176,
+ 42536,
+ 50203,
+ 57869,
+ 65535,
+ 0,
+ 8769,
+ 17538,
+ 26307,
+ 34525,
+ 42742,
+ 50784,
+ 58319,
+ 65535,
+ 0,
+ 8736,
+ 17101,
+ 25466,
+ 33653,
+ 41839,
+ 50025,
+ 57864,
+ 65535,
+ 0,
+ 4368,
+ 8735,
+ 12918,
+ 17100,
+ 21283,
+ 25465,
+ 29558,
+ 33651,
+ 37744,
+ 41836,
+ 45929,
+ 50022,
+ 54027,
+ 57947,
+ 61782,
+ 65535
+};
+
+const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr[ NLSF_MSVQ_CB0_16_STAGES ] =
+{
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 0 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 129 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 146 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 155 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 164 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 173 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 182 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 191 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 200 ],
+ &SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ 209 ]
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx[ NLSF_MSVQ_CB0_16_STAGES ] =
+{
+ 42,
+ 8,
+ 4,
+ 5,
+ 5,
+ 5,
+ 5,
+ 5,
+ 5,
+ 9
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ NLSF_MSVQ_CB0_16_VECTORS ] =
+{
+ 176, 181,
+ 182, 183,
+ 186, 186,
+ 191, 191,
+ 191, 196,
+ 197, 201,
+ 203, 206,
+ 206, 206,
+ 207, 207,
+ 209, 209,
+ 209, 209,
+ 210, 210,
+ 210, 211,
+ 211, 211,
+ 212, 214,
+ 216, 216,
+ 217, 217,
+ 217, 217,
+ 218, 218,
+ 219, 219,
+ 220, 221,
+ 222, 223,
+ 223, 223,
+ 223, 224,
+ 224, 224,
+ 225, 225,
+ 226, 226,
+ 226, 226,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 228, 228,
+ 228, 228,
+ 229, 229,
+ 229, 230,
+ 230, 230,
+ 231, 231,
+ 231, 231,
+ 232, 232,
+ 232, 232,
+ 233, 234,
+ 235, 235,
+ 235, 236,
+ 236, 236,
+ 236, 237,
+ 237, 237,
+ 237, 240,
+ 240, 240,
+ 240, 241,
+ 242, 243,
+ 244, 244,
+ 247, 247,
+ 248, 248,
+ 248, 249,
+ 251, 255,
+ 255, 256,
+ 260, 260,
+ 261, 264,
+ 264, 266,
+ 266, 268,
+ 271, 274,
+ 276, 279,
+ 288, 288,
+ 288, 288,
+ 118, 120,
+ 121, 121,
+ 122, 125,
+ 125, 129,
+ 129, 130,
+ 131, 132,
+ 136, 137,
+ 138, 145,
+ 87, 88,
+ 91, 97,
+ 98, 100,
+ 105, 106,
+ 92, 95,
+ 95, 96,
+ 97, 97,
+ 98, 99,
+ 88, 92,
+ 95, 95,
+ 96, 97,
+ 98, 109,
+ 93, 93,
+ 93, 96,
+ 97, 97,
+ 99, 101,
+ 93, 94,
+ 94, 95,
+ 95, 99,
+ 99, 99,
+ 93, 93,
+ 93, 96,
+ 96, 97,
+ 100, 102,
+ 93, 95,
+ 95, 96,
+ 96, 96,
+ 98, 99,
+ 125, 125,
+ 127, 127,
+ 127, 127,
+ 128, 128,
+ 128, 128,
+ 128, 128,
+ 129, 130,
+ 131, 132
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min_Q15[ 16 + 1 ] =
+{
+ 266,
+ 3,
+ 40,
+ 3,
+ 3,
+ 16,
+ 78,
+ 89,
+ 107,
+ 141,
+ 188,
+ 146,
+ 272,
+ 240,
+ 235,
+ 215,
+ 632
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * NLSF_MSVQ_CB0_16_VECTORS ] =
+{
+ 1170, 2278, 3658, 5374,
+ 7666, 9113, 11298, 13304,
+ 15371, 17549, 19587, 21487,
+ 23798, 26038, 28318, 30201,
+ 1628, 2334, 4115, 6036,
+ 7818, 9544, 11777, 14021,
+ 15787, 17408, 19466, 21261,
+ 22886, 24565, 26714, 28059,
+ 1724, 2670, 4056, 6532,
+ 8357, 10119, 12093, 14061,
+ 16491, 18795, 20417, 22402,
+ 24251, 26224, 28410, 29956,
+ 1493, 3427, 4789, 6399,
+ 8435, 10168, 12000, 14066,
+ 16229, 18210, 20040, 22098,
+ 24153, 26095, 28183, 30121,
+ 1119, 2089, 4295, 6245,
+ 8691, 10741, 12688, 15057,
+ 17028, 18792, 20717, 22514,
+ 24497, 26548, 28619, 30630,
+ 1363, 2417, 3927, 5556,
+ 7422, 9315, 11879, 13767,
+ 16143, 18520, 20458, 22578,
+ 24539, 26436, 28318, 30318,
+ 1122, 2503, 5216, 7148,
+ 9310, 11078, 13175, 14800,
+ 16864, 18700, 20436, 22488,
+ 24572, 26602, 28555, 30426,
+ 600, 1317, 2970, 5609,
+ 7694, 9784, 12169, 14087,
+ 16379, 18378, 20551, 22686,
+ 24739, 26697, 28646, 30355,
+ 941, 1882, 4274, 5540,
+ 8482, 9858, 11940, 14287,
+ 16091, 18501, 20326, 22612,
+ 24711, 26638, 28814, 30430,
+ 635, 1699, 4376, 5948,
+ 8097, 10115, 12274, 14178,
+ 16111, 17813, 19695, 21773,
+ 23927, 25866, 28022, 30134,
+ 1408, 2222, 3524, 5615,
+ 7345, 8849, 10989, 12772,
+ 15352, 17026, 18919, 21062,
+ 23329, 25215, 27209, 29023,
+ 701, 1307, 3548, 6301,
+ 7744, 9574, 11227, 12978,
+ 15170, 17565, 19775, 22097,
+ 24230, 26335, 28377, 30231,
+ 1752, 2364, 4879, 6569,
+ 7813, 9796, 11199, 14290,
+ 15795, 18000, 20396, 22417,
+ 24308, 26124, 28360, 30633,
+ 901, 1629, 3356, 4635,
+ 7256, 8767, 9971, 11558,
+ 15215, 17544, 19523, 21852,
+ 23900, 25978, 28133, 30184,
+ 981, 1669, 3323, 4693,
+ 6213, 8692, 10614, 12956,
+ 15211, 17711, 19856, 22122,
+ 24344, 26592, 28723, 30481,
+ 1607, 2577, 4220, 5512,
+ 8532, 10388, 11627, 13671,
+ 15752, 17199, 19840, 21859,
+ 23494, 25786, 28091, 30131,
+ 811, 1471, 3144, 5041,
+ 7430, 9389, 11174, 13255,
+ 15157, 16741, 19583, 22167,
+ 24115, 26142, 28383, 30395,
+ 1543, 2144, 3629, 6347,
+ 7333, 9339, 10710, 13596,
+ 15099, 17340, 20102, 21886,
+ 23732, 25637, 27818, 29917,
+ 492, 1185, 2940, 5488,
+ 7095, 8751, 11596, 13579,
+ 16045, 18015, 20178, 22127,
+ 24265, 26406, 28484, 30357,
+ 1547, 2282, 3693, 6341,
+ 7758, 9607, 11848, 13236,
+ 16564, 18069, 19759, 21404,
+ 24110, 26606, 28786, 30655,
+ 685, 1338, 3409, 5262,
+ 6950, 9222, 11414, 14523,
+ 16337, 17893, 19436, 21298,
+ 23293, 25181, 27973, 30520,
+ 887, 1581, 3057, 4318,
+ 7192, 8617, 10047, 13106,
+ 16265, 17893, 20233, 22350,
+ 24379, 26384, 28314, 30189,
+ 2285, 3745, 5662, 7576,
+ 9323, 11320, 13239, 15191,
+ 17175, 19225, 21108, 22972,
+ 24821, 26655, 28561, 30460,
+ 1496, 2108, 3448, 6898,
+ 8328, 9656, 11252, 12823,
+ 14979, 16482, 18180, 20085,
+ 22962, 25160, 27705, 29629,
+ 575, 1261, 3861, 6627,
+ 8294, 10809, 12705, 14768,
+ 17076, 19047, 20978, 23055,
+ 24972, 26703, 28720, 30345,
+ 1682, 2213, 3882, 6238,
+ 7208, 9646, 10877, 13431,
+ 14805, 16213, 17941, 20873,
+ 23550, 25765, 27756, 29461,
+ 888, 1616, 3924, 5195,
+ 7206, 8647, 9842, 11473,
+ 16067, 18221, 20343, 22774,
+ 24503, 26412, 28054, 29731,
+ 805, 1454, 2683, 4472,
+ 7936, 9360, 11398, 14345,
+ 16205, 17832, 19453, 21646,
+ 23899, 25928, 28387, 30463,
+ 1640, 2383, 3484, 5082,
+ 6032, 8606, 11640, 12966,
+ 15842, 17368, 19346, 21182,
+ 23638, 25889, 28368, 30299,
+ 1632, 2204, 4510, 7580,
+ 8718, 10512, 11962, 14096,
+ 15640, 17194, 19143, 22247,
+ 24563, 26561, 28604, 30509,
+ 2043, 2612, 3985, 6851,
+ 8038, 9514, 10979, 12789,
+ 15426, 16728, 18899, 20277,
+ 22902, 26209, 28711, 30618,
+ 2224, 2798, 4465, 5320,
+ 7108, 9436, 10986, 13222,
+ 14599, 18317, 20141, 21843,
+ 23601, 25700, 28184, 30582,
+ 835, 1541, 4083, 5769,
+ 7386, 9399, 10971, 12456,
+ 15021, 18642, 20843, 23100,
+ 25292, 26966, 28952, 30422,
+ 1795, 2343, 4809, 5896,
+ 7178, 8545, 10223, 13370,
+ 14606, 16469, 18273, 20736,
+ 23645, 26257, 28224, 30390,
+ 1734, 2254, 4031, 5188,
+ 6506, 7872, 9651, 13025,
+ 14419, 17305, 19495, 22190,
+ 24403, 26302, 28195, 30177,
+ 1841, 2349, 3968, 4764,
+ 6376, 9825, 11048, 13345,
+ 14682, 16252, 18183, 21363,
+ 23918, 26156, 28031, 29935,
+ 1432, 2047, 5631, 6927,
+ 8198, 9675, 11358, 13506,
+ 14802, 16419, 18339, 22019,
+ 24124, 26177, 28130, 30586,
+ 1730, 2320, 3744, 4808,
+ 6007, 9666, 10997, 13622,
+ 15234, 17495, 20088, 22002,
+ 23603, 25400, 27379, 29254,
+ 1267, 1915, 5483, 6812,
+ 8229, 9919, 11589, 13337,
+ 14747, 17965, 20552, 22167,
+ 24519, 26819, 28883, 30642,
+ 1526, 2229, 4240, 7388,
+ 8953, 10450, 11899, 13718,
+ 16861, 18323, 20379, 22672,
+ 24797, 26906, 28906, 30622,
+ 2175, 2791, 4104, 6875,
+ 8612, 9798, 12152, 13536,
+ 15623, 17682, 19213, 21060,
+ 24382, 26760, 28633, 30248,
+ 454, 1231, 4339, 5738,
+ 7550, 9006, 10320, 13525,
+ 16005, 17849, 20071, 21992,
+ 23949, 26043, 28245, 30175,
+ 2250, 2791, 4230, 5283,
+ 6762, 10607, 11879, 13821,
+ 15797, 17264, 20029, 22266,
+ 24588, 26437, 28244, 30419,
+ 1696, 2216, 4308, 8385,
+ 9766, 11030, 12556, 14099,
+ 16322, 17640, 19166, 20590,
+ 23967, 26858, 28798, 30562,
+ 2452, 3236, 4369, 6118,
+ 7156, 9003, 11509, 12796,
+ 15749, 17291, 19491, 22241,
+ 24530, 26474, 28273, 30073,
+ 1811, 2541, 3555, 5480,
+ 9123, 10527, 11894, 13659,
+ 15262, 16899, 19366, 21069,
+ 22694, 24314, 27256, 29983,
+ 1553, 2246, 4559, 5500,
+ 6754, 7874, 11739, 13571,
+ 15188, 17879, 20281, 22510,
+ 24614, 26649, 28786, 30755,
+ 1982, 2768, 3834, 5964,
+ 8732, 9908, 11797, 14813,
+ 16311, 17946, 21097, 22851,
+ 24456, 26304, 28166, 29755,
+ 1824, 2529, 3817, 5449,
+ 6854, 8714, 10381, 12286,
+ 14194, 15774, 19524, 21374,
+ 23695, 26069, 28096, 30212,
+ 2212, 2854, 3947, 5898,
+ 9930, 11556, 12854, 14788,
+ 16328, 17700, 20321, 22098,
+ 23672, 25291, 26976, 28586,
+ 2023, 2599, 4024, 4916,
+ 6613, 11149, 12457, 14626,
+ 16320, 17822, 19673, 21172,
+ 23115, 26051, 28825, 30758,
+ 1628, 2206, 3467, 4364,
+ 8679, 10173, 11864, 13679,
+ 14998, 16938, 19207, 21364,
+ 23850, 26115, 28124, 30273,
+ 2014, 2603, 4114, 7254,
+ 8516, 10043, 11822, 13503,
+ 16329, 17826, 19697, 21280,
+ 23151, 24661, 26807, 30161,
+ 2376, 2980, 4422, 5770,
+ 7016, 9723, 11125, 13516,
+ 15485, 16985, 19160, 20587,
+ 24401, 27180, 29046, 30647,
+ 2454, 3502, 4624, 6019,
+ 7632, 8849, 10792, 13964,
+ 15523, 17085, 19611, 21238,
+ 22856, 25108, 28106, 29890,
+ 1573, 2274, 3308, 5999,
+ 8977, 10104, 12457, 14258,
+ 15749, 18180, 19974, 21253,
+ 23045, 25058, 27741, 30315,
+ 1943, 2730, 4140, 6160,
+ 7491, 8986, 11309, 12775,
+ 14820, 16558, 17909, 19757,
+ 21512, 23605, 27274, 29527,
+ 2021, 2582, 4494, 5835,
+ 6993, 8245, 9827, 14733,
+ 16462, 17894, 19647, 21083,
+ 23764, 26667, 29072, 30990,
+ 1052, 1775, 3218, 4378,
+ 7666, 9403, 11248, 13327,
+ 14972, 17962, 20758, 22354,
+ 25071, 27209, 29001, 30609,
+ 2218, 2866, 4223, 5352,
+ 6581, 9980, 11587, 13121,
+ 15193, 16583, 18386, 20080,
+ 22013, 25317, 28127, 29880,
+ 2146, 2840, 4397, 5840,
+ 7449, 8721, 10512, 11936,
+ 13595, 17253, 19310, 20891,
+ 23417, 25627, 27749, 30231,
+ 1972, 2619, 3756, 6367,
+ 7641, 8814, 12286, 13768,
+ 15309, 18036, 19557, 20904,
+ 22582, 24876, 27800, 30440,
+ 2005, 2577, 4272, 7373,
+ 8558, 10223, 11770, 13402,
+ 16502, 18000, 19645, 21104,
+ 22990, 26806, 29505, 30942,
+ 1153, 1822, 3724, 5443,
+ 6990, 8702, 10289, 11899,
+ 13856, 15315, 17601, 21064,
+ 23692, 26083, 28586, 30639,
+ 1304, 1869, 3318, 7195,
+ 9613, 10733, 12393, 13728,
+ 15822, 17474, 18882, 20692,
+ 23114, 25540, 27684, 29244,
+ 2093, 2691, 4018, 6658,
+ 7947, 9147, 10497, 11881,
+ 15888, 17821, 19333, 21233,
+ 23371, 25234, 27553, 29998,
+ 575, 1331, 5304, 6910,
+ 8425, 10086, 11577, 13498,
+ 16444, 18527, 20565, 22847,
+ 24914, 26692, 28759, 30157,
+ 1435, 2024, 3283, 4156,
+ 7611, 10592, 12049, 13927,
+ 15459, 18413, 20495, 22270,
+ 24222, 26093, 28065, 30099,
+ 1632, 2168, 5540, 7478,
+ 8630, 10391, 11644, 14321,
+ 15741, 17357, 18756, 20434,
+ 22799, 26060, 28542, 30696,
+ 1407, 2245, 3405, 5639,
+ 9419, 10685, 12104, 13495,
+ 15535, 18357, 19996, 21689,
+ 24351, 26550, 28853, 30564,
+ 1675, 2226, 4005, 8223,
+ 9975, 11155, 12822, 14316,
+ 16504, 18137, 19574, 21050,
+ 22759, 24912, 28296, 30634,
+ 1080, 1614, 3622, 7565,
+ 8748, 10303, 11713, 13848,
+ 15633, 17434, 19761, 21825,
+ 23571, 25393, 27406, 29063,
+ 1693, 2229, 3456, 4354,
+ 5670, 10890, 12563, 14167,
+ 15879, 17377, 19817, 21971,
+ 24094, 26131, 28298, 30099,
+ 2042, 2959, 4195, 5740,
+ 7106, 8267, 11126, 14973,
+ 16914, 18295, 20532, 21982,
+ 23711, 25769, 27609, 29351,
+ 984, 1612, 3808, 5265,
+ 6885, 8411, 9547, 10889,
+ 12522, 16520, 19549, 21639,
+ 23746, 26058, 28310, 30374,
+ 2036, 2538, 4166, 7761,
+ 9146, 10412, 12144, 13609,
+ 15588, 17169, 18559, 20113,
+ 21820, 24313, 28029, 30612,
+ 1871, 2355, 4061, 5143,
+ 7464, 10129, 11941, 15001,
+ 16680, 18354, 19957, 22279,
+ 24861, 26872, 28988, 30615,
+ 2566, 3161, 4643, 6227,
+ 7406, 9970, 11618, 13416,
+ 15889, 17364, 19121, 20817,
+ 22592, 24720, 28733, 31082,
+ 1700, 2327, 4828, 5939,
+ 7567, 9154, 11087, 12771,
+ 14209, 16121, 20222, 22671,
+ 24648, 26656, 28696, 30745,
+ 3169, 3873, 5046, 6868,
+ 8184, 9480, 12335, 14068,
+ 15774, 17971, 20231, 21711,
+ 23520, 25245, 27026, 28730,
+ 1564, 2391, 4229, 6730,
+ 8905, 10459, 13026, 15033,
+ 17265, 19809, 21849, 23741,
+ 25490, 27312, 29061, 30527,
+ 2864, 3559, 4719, 6441,
+ 9592, 11055, 12763, 14784,
+ 16428, 18164, 20486, 22262,
+ 24183, 26263, 28383, 30224,
+ 2673, 3449, 4581, 5983,
+ 6863, 8311, 12464, 13911,
+ 15738, 17791, 19416, 21182,
+ 24025, 26561, 28723, 30440,
+ 2419, 3049, 4274, 6384,
+ 8564, 9661, 11288, 12676,
+ 14447, 17578, 19816, 21231,
+ 23099, 25270, 26899, 28926,
+ 1278, 2001, 3000, 5353,
+ 9995, 11777, 13018, 14570,
+ 16050, 17762, 19982, 21617,
+ 23371, 25083, 27656, 30172,
+ 932, 1624, 2798, 4570,
+ 8592, 9988, 11552, 13050,
+ 16921, 18677, 20415, 22810,
+ 24817, 26819, 28804, 30385,
+ 2324, 2973, 4156, 5702,
+ 6919, 8806, 10259, 12503,
+ 15015, 16567, 19418, 21375,
+ 22943, 24550, 27024, 29849,
+ 1564, 2373, 3455, 4907,
+ 5975, 7436, 11786, 14505,
+ 16107, 18148, 20019, 21653,
+ 23740, 25814, 28578, 30372,
+ 3025, 3729, 4866, 6520,
+ 9487, 10943, 12358, 14258,
+ 16174, 17501, 19476, 21408,
+ 23227, 24906, 27347, 29407,
+ 1270, 1965, 6802, 7995,
+ 9204, 10828, 12507, 14230,
+ 15759, 17860, 20369, 22502,
+ 24633, 26514, 28535, 30525,
+ 2210, 2749, 4266, 7487,
+ 9878, 11018, 12823, 14431,
+ 16247, 18626, 20450, 22054,
+ 23739, 25291, 27074, 29169,
+ 1275, 1926, 4330, 6573,
+ 8441, 10920, 13260, 15008,
+ 16927, 18573, 20644, 22217,
+ 23983, 25474, 27372, 28645,
+ 3015, 3670, 5086, 6372,
+ 7888, 9309, 10966, 12642,
+ 14495, 16172, 18080, 19972,
+ 22454, 24899, 27362, 29975,
+ 2882, 3733, 5113, 6482,
+ 8125, 9685, 11598, 13288,
+ 15405, 17192, 20178, 22426,
+ 24801, 27014, 29212, 30811,
+ 2300, 2968, 4101, 5442,
+ 6327, 7910, 12455, 13862,
+ 15747, 17505, 19053, 20679,
+ 22615, 24658, 27499, 30065,
+ 2257, 2940, 4430, 5991,
+ 7042, 8364, 9414, 11224,
+ 15723, 17420, 19253, 21469,
+ 23915, 26053, 28430, 30384,
+ 1227, 2045, 3818, 5011,
+ 6990, 9231, 11024, 13011,
+ 17341, 19017, 20583, 22799,
+ 25195, 26876, 29351, 30805,
+ 1354, 1924, 3789, 8077,
+ 10453, 11639, 13352, 14817,
+ 16743, 18189, 20095, 22014,
+ 24593, 26677, 28647, 30256,
+ 3142, 4049, 6197, 7417,
+ 8753, 10156, 11533, 13181,
+ 15947, 17655, 19606, 21402,
+ 23487, 25659, 28123, 30304,
+ 1317, 2263, 4725, 7611,
+ 9667, 11634, 14143, 16258,
+ 18724, 20698, 22379, 24007,
+ 25775, 27251, 28930, 30593,
+ 1570, 2323, 3818, 6215,
+ 9893, 11556, 13070, 14631,
+ 16152, 18290, 21386, 23346,
+ 25114, 26923, 28712, 30168,
+ 2297, 3905, 6287, 8558,
+ 10668, 12766, 15019, 17102,
+ 19036, 20677, 22341, 23871,
+ 25478, 27085, 28851, 30520,
+ 1915, 2507, 4033, 5749,
+ 7059, 8871, 10659, 12198,
+ 13937, 15383, 16869, 18707,
+ 23175, 25818, 28514, 30501,
+ 2404, 2918, 5190, 6252,
+ 7426, 9887, 12387, 14795,
+ 16754, 18368, 20338, 22003,
+ 24236, 26456, 28490, 30397,
+ 1621, 2227, 3479, 5085,
+ 9425, 12892, 14246, 15652,
+ 17205, 18674, 20446, 22209,
+ 23778, 25867, 27931, 30093,
+ 1869, 2390, 4105, 7021,
+ 11221, 12775, 14059, 15590,
+ 17024, 18608, 20595, 22075,
+ 23649, 25154, 26914, 28671,
+ 2551, 3252, 4688, 6562,
+ 7869, 9125, 10475, 11800,
+ 15402, 18780, 20992, 22555,
+ 24289, 25968, 27465, 29232,
+ 2705, 3493, 4735, 6360,
+ 7905, 9352, 11538, 13430,
+ 15239, 16919, 18619, 20094,
+ 21800, 23342, 25200, 29257,
+ 2166, 2791, 4011, 5081,
+ 5896, 9038, 13407, 14703,
+ 16543, 18189, 19896, 21857,
+ 24872, 26971, 28955, 30514,
+ 1865, 3021, 4696, 6534,
+ 8343, 9914, 12789, 14103,
+ 16533, 17729, 21340, 22439,
+ 24873, 26330, 28428, 30154,
+ 3369, 4345, 6573, 8763,
+ 10309, 11713, 13367, 14784,
+ 16483, 18145, 19839, 21247,
+ 23292, 25477, 27555, 29447,
+ 1265, 2184, 5443, 7893,
+ 10591, 13139, 15105, 16639,
+ 18402, 19826, 21419, 22995,
+ 24719, 26437, 28363, 30125,
+ 1584, 2004, 3535, 4450,
+ 8662, 10764, 12832, 14978,
+ 16972, 18794, 20932, 22547,
+ 24636, 26521, 28701, 30567,
+ 3419, 4528, 6602, 7890,
+ 9508, 10875, 12771, 14357,
+ 16051, 18330, 20630, 22490,
+ 25070, 26936, 28946, 30542,
+ 1726, 2252, 4597, 6950,
+ 8379, 9823, 11363, 12794,
+ 14306, 15476, 16798, 18018,
+ 21671, 25550, 28148, 30367,
+ 3385, 3870, 5307, 6388,
+ 7141, 8684, 12695, 14939,
+ 16480, 18277, 20537, 22048,
+ 23947, 25965, 28214, 29956,
+ 2771, 3306, 4450, 5560,
+ 6453, 9493, 13548, 14754,
+ 16743, 18447, 20028, 21736,
+ 23746, 25353, 27141, 29066,
+ 3028, 3900, 6617, 7893,
+ 9211, 10480, 12047, 13583,
+ 15182, 16662, 18502, 20092,
+ 22190, 24358, 26302, 28957,
+ 2000, 2550, 4067, 6837,
+ 9628, 11002, 12594, 14098,
+ 15589, 17195, 18679, 20099,
+ 21530, 23085, 24641, 29022,
+ 2844, 3302, 5103, 6107,
+ 6911, 8598, 12416, 14054,
+ 16026, 18567, 20672, 22270,
+ 23952, 25771, 27658, 30026,
+ 4043, 5150, 7268, 9056,
+ 10916, 12638, 14543, 16184,
+ 17948, 19691, 21357, 22981,
+ 24825, 26591, 28479, 30233,
+ 2109, 2625, 4320, 5525,
+ 7454, 10220, 12980, 14698,
+ 17627, 19263, 20485, 22381,
+ 24279, 25777, 27847, 30458,
+ 1550, 2667, 6473, 9496,
+ 10985, 12352, 13795, 15233,
+ 17099, 18642, 20461, 22116,
+ 24197, 26291, 28403, 30132,
+ 2411, 3084, 4145, 5394,
+ 6367, 8154, 13125, 16049,
+ 17561, 19125, 21258, 22762,
+ 24459, 26317, 28255, 29702,
+ 4159, 4516, 5956, 7635,
+ 8254, 8980, 11208, 14133,
+ 16210, 17875, 20196, 21864,
+ 23840, 25747, 28058, 30012,
+ 2026, 2431, 2845, 3618,
+ 7950, 9802, 12721, 14460,
+ 16576, 18984, 21376, 23319,
+ 24961, 26718, 28971, 30640,
+ 3429, 3833, 4472, 4912,
+ 7723, 10386, 12981, 15322,
+ 16699, 18807, 20778, 22551,
+ 24627, 26494, 28334, 30482,
+ 4740, 5169, 5796, 6485,
+ 6998, 8830, 11777, 14414,
+ 16831, 18413, 20789, 22369,
+ 24236, 25835, 27807, 30021,
+ 150, 168, -17, -107,
+ -142, -229, -320, -406,
+ -503, -620, -867, -935,
+ -902, -680, -398, -114,
+ -398, -355, 49, 255,
+ 114, 260, 399, 264,
+ 317, 431, 514, 531,
+ 435, 356, 238, 106,
+ -43, -36, -169, -224,
+ -391, -633, -776, -970,
+ -844, -455, -181, -12,
+ 85, 85, 164, 195,
+ 122, 85, -158, -640,
+ -903, 9, 7, -124,
+ 149, 32, 220, 369,
+ 242, 115, 79, 84,
+ -146, -216, -70, 1024,
+ 751, 574, 440, 377,
+ 352, 203, 30, 16,
+ -3, 81, 161, 100,
+ -148, -176, 933, 750,
+ 404, 171, -2, -146,
+ -411, -442, -541, -552,
+ -442, -269, -240, -52,
+ 603, 635, 405, 178,
+ 215, 19, -153, -167,
+ -290, -219, 151, 271,
+ 151, 119, 303, 266,
+ 100, 69, -293, -657,
+ 939, 659, 442, 351,
+ 132, 98, -16, -1,
+ -135, -200, -223, -89,
+ 167, 154, 172, 237,
+ -45, -183, -228, -486,
+ 263, 608, 158, -125,
+ -390, -227, -118, 43,
+ -457, -392, -769, -840,
+ 20, -117, -194, -189,
+ -173, -173, -33, 32,
+ 174, 144, 115, 167,
+ 57, 44, 14, 147,
+ 96, -54, -142, -129,
+ -254, -331, 304, 310,
+ -52, -419, -846, -1060,
+ -88, -123, -202, -343,
+ -554, -961, -951, 327,
+ 159, 81, 255, 227,
+ 120, 203, 256, 192,
+ 164, 224, 290, 195,
+ 216, 209, 128, 832,
+ 1028, 889, 698, 504,
+ 408, 355, 218, 32,
+ -115, -84, -276, -100,
+ -312, -484, 899, 682,
+ 465, 456, 241, -12,
+ -275, -425, -461, -367,
+ -33, -28, -102, -194,
+ -527, 863, 906, 463,
+ 245, 13, -212, -305,
+ -105, 163, 279, 176,
+ 93, 67, 115, 192,
+ 61, -50, -132, -175,
+ -224, -271, -629, -252,
+ 1158, 972, 638, 280,
+ 300, 326, 143, -152,
+ -214, -287, 53, -42,
+ -236, -352, -423, -248,
+ -129, -163, -178, -119,
+ 85, 57, 514, 382,
+ 374, 402, 424, 423,
+ 271, 197, 97, 40,
+ 39, -97, -191, -164,
+ -230, -256, -410, 396,
+ 327, 127, 10, -119,
+ -167, -291, -274, -141,
+ -99, -226, -218, -139,
+ -224, -209, -268, -442,
+ -413, 222, 58, 521,
+ 344, 258, 76, -42,
+ -142, -165, -123, -92,
+ 47, 8, -3, -191,
+ -11, -164, -167, -351,
+ -740, 311, 538, 291,
+ 184, 29, -105, 9,
+ -30, -54, -17, -77,
+ -271, -412, -622, -648,
+ 476, 186, -66, -197,
+ -73, -94, -15, 47,
+ 28, 112, -58, -33,
+ 65, 19, 84, 86,
+ 276, 114, 472, 786,
+ 799, 625, 415, 178,
+ -35, -26, 5, 9,
+ 83, 39, 37, 39,
+ -184, -374, -265, -362,
+ -501, 337, 716, 478,
+ -60, -125, -163, 362,
+ 17, -122, -233, 279,
+ 138, 157, 318, 193,
+ 189, 209, 266, 252,
+ -46, -56, -277, -429,
+ 464, 386, 142, 44,
+ -43, 66, 264, 182,
+ 47, 14, -26, -79,
+ 49, 15, -128, -203,
+ -400, -478, 325, 27,
+ 234, 411, 205, 129,
+ 12, 58, 123, 57,
+ 171, 137, 96, 128,
+ -32, 134, -12, 57,
+ 119, 26, -22, -165,
+ -500, -701, -528, -116,
+ 64, -8, 97, -9,
+ -162, -66, -156, -194,
+ -303, -546, -341, 546,
+ 358, 95, 45, 76,
+ 270, 403, 205, 100,
+ 123, 50, -53, -144,
+ -110, -13, 32, -228,
+ -130, 353, 296, 56,
+ -372, -253, 365, 73,
+ 10, -34, -139, -191,
+ -96, 5, 44, -85,
+ -179, -129, -192, -246,
+ -85, -110, -155, -44,
+ -27, 145, 138, 79,
+ 32, -148, -577, -634,
+ 191, 94, -9, -35,
+ -77, -84, -56, -171,
+ -298, -271, -243, -156,
+ -328, -235, -76, -128,
+ -121, 129, 13, -22,
+ 32, 45, -248, -65,
+ 193, -81, 299, 57,
+ -147, 192, -165, -354,
+ -334, -106, -156, -40,
+ -3, -68, 124, -257,
+ 78, 124, 170, 412,
+ 227, 105, -104, 12,
+ 154, 250, 274, 258,
+ 4, -27, 235, 152,
+ 51, 338, 300, 7,
+ -314, -411, 215, 170,
+ -9, -93, -77, 76,
+ 67, 54, 200, 315,
+ 163, 72, -91, -402,
+ 158, 187, -156, -91,
+ 290, 267, 167, 91,
+ 140, 171, 112, 9,
+ -42, -177, -440, 385,
+ 80, 15, 172, 129,
+ 41, -129, -372, -24,
+ -75, -30, -170, 10,
+ -118, 57, 78, -101,
+ 232, 161, 123, 256,
+ 277, 101, -192, -629,
+ -100, -60, -232, 66,
+ 13, -13, -80, -239,
+ 239, 37, 32, 89,
+ -319, -579, 450, 360,
+ 3, -29, -299, -89,
+ -54, -110, -246, -164,
+ 6, -188, 338, 176,
+ -92, 197, 137, 134,
+ 12, -2, 56, -183,
+ 114, -36, -131, -204,
+ 75, -25, -174, 191,
+ -15, -290, -429, -267,
+ 79, 37, 106, 23,
+ -384, 425, 70, -14,
+ 212, 105, 15, -2,
+ -42, -37, -123, 108,
+ 28, -48, 193, 197,
+ 173, -33, 37, 73,
+ -57, 256, 137, -58,
+ -430, -228, 217, -51,
+ -10, -58, -6, 22,
+ 104, 61, -119, 169,
+ 144, 16, -46, -394,
+ 60, 454, -80, -298,
+ -65, 25, 0, -24,
+ -65, -417, 465, 276,
+ -3, -194, -13, 130,
+ 19, -6, -21, -24,
+ -180, -53, -85, 20,
+ 118, 147, 113, -75,
+ -289, 226, -122, 227,
+ 270, 125, 109, 197,
+ 125, 138, 44, 60,
+ 25, -55, -167, -32,
+ -139, -193, -173, -316,
+ 287, -208, 253, 239,
+ 27, -80, -188, -28,
+ -182, -235, 156, -117,
+ 128, -48, -58, -226,
+ 172, 181, 167, 19,
+ 62, 10, 2, 181,
+ 151, 108, -16, -11,
+ -78, -331, 411, 133,
+ 17, 104, 64, -184,
+ 24, -30, -3, -283,
+ 121, 204, -8, -199,
+ -21, -80, -169, -157,
+ -191, -136, 81, 155,
+ 14, -131, 244, 74,
+ -57, -47, -280, 347,
+ 111, -77, -128, -142,
+ -194, -125, -6, -68,
+ 91, 1, 23, 14,
+ -154, -34, 23, -38,
+ -343, 503, 146, -38,
+ -46, -41, 58, 31,
+ 63, -48, -117, 45,
+ 28, 1, -89, -5,
+ -44, -29, -448, 487,
+ 204, 81, 46, -106,
+ -302, 380, 120, -38,
+ -12, -39, 70, -3,
+ 25, -65, 30, -11,
+ 34, -15, 22, -115,
+ 0, -79, -83, 45,
+ 114, 43, 150, 36,
+ 233, 149, 195, 5,
+ 25, -52, -475, 274,
+ 28, -39, -8, -66,
+ -255, 258, 56, 143,
+ -45, -190, 165, -60,
+ 20, 2, 125, -129,
+ 51, -8, -335, 288,
+ 38, 59, 25, -42,
+ 23, -118, -112, 11,
+ -55, -133, -109, 24,
+ -105, 78, -64, -245,
+ 202, -65, -127, 162,
+ 40, -94, 89, -85,
+ -119, -103, 97, 9,
+ -70, -28, 194, 86,
+ -112, -92, -114, 74,
+ -49, 46, -84, -178,
+ 113, 52, -205, 333,
+ 88, 222, 56, -55,
+ 13, 86, 4, -77,
+ 224, 114, -105, 112,
+ 125, -29, -18, -144,
+ 22, -58, -99, 28,
+ 114, -66, -32, -169,
+ -314, 285, 72, -74,
+ 179, 28, -79, -182,
+ 13, -55, 147, 13,
+ 12, -54, 31, -84,
+ -17, -75, -228, 83,
+ -375, 436, 110, -63,
+ -27, -136, 169, -56,
+ -8, -171, 184, -42,
+ 148, 68, 204, 235,
+ 110, -229, 91, 171,
+ -43, -3, -26, -99,
+ -111, 71, -170, 202,
+ -67, 181, -37, 109,
+ -120, 3, -55, -260,
+ -16, 152, 91, 142,
+ 42, 44, 134, 47,
+ 17, -35, 22, 79,
+ -169, 41, 46, 277,
+ -93, -49, -126, 37,
+ -103, -34, -22, -90,
+ -134, -205, 92, -9,
+ 1, -195, -239, 45,
+ 54, 18, -23, -1,
+ -80, -98, -20, -261,
+ 306, 72, 20, -89,
+ -217, 11, 6, -82,
+ 89, 13, -129, -89,
+ 83, -71, -55, 130,
+ -98, -146, -27, -57,
+ 53, 275, 17, 170,
+ -5, -54, 132, -64,
+ 72, 160, -125, -168,
+ 72, 40, 170, 78,
+ 248, 116, 20, 84,
+ 31, -34, 190, 38,
+ 13, -106, 225, 27,
+ -168, 24, -157, -122,
+ 165, 11, -161, -213,
+ -12, -51, -101, 42,
+ 101, 27, 55, 111,
+ 75, 71, -96, -1,
+ 65, -277, 393, -26,
+ -44, -68, -84, -66,
+ -95, 235, 179, -25,
+ -41, 27, -91, -128,
+ -222, 146, -72, -30,
+ -24, 55, -126, -68,
+ -58, -127, 13, -97,
+ -106, 174, -100, 155,
+ 101, -146, -21, 261,
+ 22, 38, -66, 65,
+ 4, 70, 64, 144,
+ 59, 213, 71, -337,
+ 303, -52, 51, -56,
+ 1, 10, -15, -5,
+ 34, 52, 228, 131,
+ 161, -127, -214, 238,
+ 123, 64, -147, -50,
+ -34, -127, 204, 162,
+ 85, 41, 5, -140,
+ 73, -150, 56, -96,
+ -66, -20, 2, -235,
+ 59, -22, -107, 150,
+ -16, -47, -4, 81,
+ -67, 167, 149, 149,
+ -157, 288, -156, -27,
+ -8, 18, 83, -24,
+ -41, -167, 158, -100,
+ 93, 53, 201, 15,
+ 42, 266, 278, -12,
+ -6, -37, 85, 6,
+ 20, -188, -271, 107,
+ -13, -80, 51, 202,
+ 173, -69, 78, -188,
+ 46, 4, 153, 12,
+ -138, 169, 5, -58,
+ -123, -108, -243, 150,
+ 10, -191, 246, -15,
+ 38, 25, -10, 14,
+ 61, 50, -206, -215,
+ -220, 90, 5, -149,
+ -219, 56, 142, 24,
+ -376, 77, -80, 75,
+ 6, 42, -101, 16,
+ 56, 14, -57, 3,
+ -17, 80, 57, -36,
+ 88, -59, -97, -19,
+ -148, 46, -219, 226,
+ 114, -4, -72, -15,
+ 37, -49, -28, 247,
+ 44, 123, 47, -122,
+ -38, 17, 4, -113,
+ -32, -224, 154, -134,
+ 196, 71, -267, -85,
+ 28, -70, 89, -120,
+ 99, -2, 64, 76,
+ -166, -48, 189, -35,
+ -92, -169, -123, 339,
+ 38, -25, 38, -35,
+ 225, -139, -50, -63,
+ 246, 60, -185, -109,
+ -49, -53, -167, 51,
+ 149, 60, -101, -33,
+ 25, -76, 120, 32,
+ -30, -83, 102, 91,
+ -186, -261, 131, -197
+};
+
+const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB0_16_Stage_info[ NLSF_MSVQ_CB0_16_STAGES ] =
+{
+ { 128, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 0 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 0 ] },
+ { 16, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 128 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 128 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 144 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 144 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 152 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 152 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 160 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 160 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 168 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 168 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 176 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 176 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 184 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 184 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 192 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 192 ] },
+ { 16, &SKP_Silk_NLSF_MSVQ_CB0_16_Q15[ 16 * 200 ], &SKP_Silk_NLSF_MSVQ_CB0_16_rates_Q5[ 200 ] }
+};
+
+const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB0_16 =
+{
+ NLSF_MSVQ_CB0_16_STAGES,
+ SKP_Silk_NLSF_CB0_16_Stage_info,
+ SKP_Silk_NLSF_MSVQ_CB0_16_ndelta_min_Q15,
+ SKP_Silk_NLSF_MSVQ_CB0_16_CDF,
+ SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr,
+ SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_16.h b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_16.h
new file mode 100644
index 0000000..bf110e5
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB0_16.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_TABLES_NLSF_CB0_16_H
+#define SKP_SILK_TABLES_NLSF_CB0_16_H
+
+#include "SKP_Silk_define.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define NLSF_MSVQ_CB0_16_STAGES 10
+#define NLSF_MSVQ_CB0_16_VECTORS 216
+
+/* NLSF codebook entropy coding tables */
+extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB0_16_CDF[ NLSF_MSVQ_CB0_16_VECTORS + NLSF_MSVQ_CB0_16_STAGES ];
+extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB0_16_CDF_start_ptr[ NLSF_MSVQ_CB0_16_STAGES ];
+extern const SKP_int SKP_Silk_NLSF_MSVQ_CB0_16_CDF_middle_idx[ NLSF_MSVQ_CB0_16_STAGES ];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_10.c b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_10.c
new file mode 100644
index 0000000..46b3543
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_10.c
@@ -0,0 +1,578 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 file has been automatically generated */
+/* */
+/* ROM usage: 0.19 + 1.61 kB */
+/**********************************************/
+
+#include "SKP_Silk_structs.h"
+#include "SKP_Silk_tables_NLSF_CB1_10.h"
+#include "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ NLSF_MSVQ_CB1_10_VECTORS + NLSF_MSVQ_CB1_10_STAGES ] =
+{
+ 0,
+ 17096,
+ 24130,
+ 28997,
+ 33179,
+ 36696,
+ 40213,
+ 42493,
+ 44252,
+ 45973,
+ 47551,
+ 49095,
+ 50542,
+ 51898,
+ 53196,
+ 54495,
+ 55685,
+ 56851,
+ 57749,
+ 58628,
+ 59435,
+ 60207,
+ 60741,
+ 61220,
+ 61700,
+ 62179,
+ 62659,
+ 63138,
+ 63617,
+ 64097,
+ 64576,
+ 65056,
+ 65535,
+ 0,
+ 20378,
+ 33032,
+ 40395,
+ 46721,
+ 51707,
+ 56585,
+ 61157,
+ 65535,
+ 0,
+ 15055,
+ 25472,
+ 35447,
+ 42501,
+ 48969,
+ 54773,
+ 60212,
+ 65535,
+ 0,
+ 12069,
+ 22440,
+ 32812,
+ 40145,
+ 46870,
+ 53595,
+ 59630,
+ 65535,
+ 0,
+ 10839,
+ 19954,
+ 27957,
+ 35961,
+ 43965,
+ 51465,
+ 58805,
+ 65535,
+ 0,
+ 8933,
+ 17674,
+ 26415,
+ 34785,
+ 42977,
+ 50820,
+ 58496,
+ 65535
+};
+
+const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr[ NLSF_MSVQ_CB1_10_STAGES ] =
+{
+ &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 0 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 33 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 42 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 51 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 60 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ 69 ]
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx[ NLSF_MSVQ_CB1_10_STAGES ] =
+{
+ 5,
+ 3,
+ 4,
+ 4,
+ 5,
+ 5
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ NLSF_MSVQ_CB1_10_VECTORS ] =
+{
+ 62, 103,
+ 120, 127,
+ 135, 135,
+ 155, 167,
+ 168, 172,
+ 173, 176,
+ 179, 181,
+ 181, 185,
+ 186, 198,
+ 199, 203,
+ 205, 222,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 54, 76,
+ 101, 108,
+ 119, 120,
+ 123, 125,
+ 68, 85,
+ 87, 103,
+ 107, 112,
+ 115, 116,
+ 78, 85,
+ 85, 101,
+ 105, 105,
+ 110, 111,
+ 83, 91,
+ 97, 97,
+ 97, 100,
+ 101, 105,
+ 92, 93,
+ 93, 95,
+ 96, 98,
+ 99, 103
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min_Q15[ 10 + 1 ] =
+{
+ 462,
+ 3,
+ 64,
+ 74,
+ 98,
+ 50,
+ 97,
+ 68,
+ 120,
+ 53,
+ 639
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * NLSF_MSVQ_CB1_10_VECTORS ] =
+{
+ 1877, 4646,
+ 7712, 10745,
+ 13964, 17028,
+ 20239, 23182,
+ 26471, 29287,
+ 1612, 3278,
+ 7086, 9975,
+ 13228, 16264,
+ 19596, 22690,
+ 26037, 28965,
+ 2169, 3830,
+ 6460, 8958,
+ 11960, 14750,
+ 18408, 21659,
+ 25018, 28043,
+ 3680, 6024,
+ 8986, 12256,
+ 15201, 18188,
+ 21741, 24460,
+ 27484, 30059,
+ 2584, 5187,
+ 7799, 10902,
+ 13179, 15765,
+ 19017, 22431,
+ 25891, 28698,
+ 3731, 5751,
+ 8650, 11742,
+ 15090, 17407,
+ 20391, 23421,
+ 26228, 29247,
+ 2107, 6323,
+ 8915, 12226,
+ 14775, 17791,
+ 20664, 23679,
+ 26829, 29353,
+ 1677, 2870,
+ 5386, 8077,
+ 11817, 15176,
+ 18657, 22006,
+ 25513, 28689,
+ 2111, 3625,
+ 7027, 10588,
+ 14059, 17193,
+ 21137, 24260,
+ 27577, 30036,
+ 2428, 4010,
+ 5765, 9376,
+ 13805, 15821,
+ 19444, 22389,
+ 25295, 29310,
+ 2256, 4628,
+ 8377, 12441,
+ 15283, 19462,
+ 22257, 25551,
+ 28432, 30304,
+ 2352, 3675,
+ 6129, 11868,
+ 14551, 16655,
+ 19624, 21883,
+ 26526, 28849,
+ 5243, 7248,
+ 10558, 13269,
+ 15651, 17919,
+ 21141, 23827,
+ 27102, 29519,
+ 4422, 6725,
+ 10449, 13273,
+ 16124, 19921,
+ 22826, 26061,
+ 28763, 30583,
+ 4508, 6291,
+ 9504, 11809,
+ 13827, 15950,
+ 19077, 22084,
+ 25740, 28658,
+ 2540, 4297,
+ 8579, 13578,
+ 16634, 19101,
+ 21547, 23887,
+ 26777, 29146,
+ 3377, 6358,
+ 10224, 14518,
+ 17905, 21056,
+ 23637, 25784,
+ 28161, 30109,
+ 4177, 5942,
+ 8159, 10108,
+ 12130, 15470,
+ 20191, 23326,
+ 26782, 29359,
+ 2492, 3801,
+ 6144, 9825,
+ 16000, 18671,
+ 20893, 23663,
+ 25899, 28974,
+ 3011, 4727,
+ 6834, 10505,
+ 12465, 14496,
+ 17065, 20052,
+ 25265, 28057,
+ 4149, 7197,
+ 12338, 15076,
+ 18002, 20190,
+ 22187, 24723,
+ 27083, 29125,
+ 2975, 4578,
+ 6448, 8378,
+ 9671, 13225,
+ 19502, 22277,
+ 26058, 28850,
+ 4102, 5760,
+ 7744, 9484,
+ 10744, 12308,
+ 14677, 19607,
+ 24841, 28381,
+ 4931, 9287,
+ 12477, 13395,
+ 13712, 14351,
+ 16048, 19867,
+ 24188, 28994,
+ 4141, 7867,
+ 13140, 17720,
+ 20064, 21108,
+ 21692, 22722,
+ 23736, 27449,
+ 4011, 8720,
+ 13234, 16206,
+ 17601, 18289,
+ 18524, 19689,
+ 23234, 27882,
+ 3420, 5995,
+ 11230, 15117,
+ 15907, 16783,
+ 17762, 23347,
+ 26898, 29946,
+ 3080, 6786,
+ 10465, 13676,
+ 18059, 23615,
+ 27058, 29082,
+ 29563, 29905,
+ 3038, 5620,
+ 9266, 12870,
+ 18803, 19610,
+ 20010, 20802,
+ 23882, 29306,
+ 3314, 6420,
+ 9046, 13262,
+ 15869, 23117,
+ 23667, 24215,
+ 24487, 25915,
+ 3469, 6963,
+ 10103, 15282,
+ 20531, 23240,
+ 25024, 26021,
+ 26736, 27255,
+ 3041, 6459,
+ 9777, 12896,
+ 16315, 19410,
+ 24070, 29353,
+ 31795, 32075,
+ -200, -134,
+ -113, -204,
+ -347, -440,
+ -352, -211,
+ -418, -172,
+ -313, 59,
+ 495, 772,
+ 721, 614,
+ 334, 444,
+ 225, 242,
+ 161, 16,
+ 274, 564,
+ -73, -188,
+ -395, -171,
+ 777, 508,
+ 1340, 1145,
+ 699, 196,
+ 223, 173,
+ 90, 25,
+ -26, 18,
+ 133, -105,
+ -360, -277,
+ 859, 634,
+ 41, -557,
+ -768, -926,
+ -601, -1021,
+ -1189, -365,
+ 225, 107,
+ 374, -50,
+ 433, 417,
+ 156, 39,
+ -597, -1397,
+ -1594, -592,
+ -485, -292,
+ 253, 87,
+ -0, -6,
+ -25, -345,
+ -240, 120,
+ 1261, 946,
+ 166, -277,
+ 241, 167,
+ 170, 429,
+ 518, 714,
+ 602, 254,
+ 134, 92,
+ -152, -324,
+ -394, 49,
+ -151, -304,
+ -724, -657,
+ -162, -369,
+ -35, 3,
+ -2, -312,
+ -200, -92,
+ -227, 242,
+ 628, 565,
+ -124, 1056,
+ 770, 101,
+ -84, -33,
+ 4, -192,
+ -272, 5,
+ -627, -977,
+ 419, 472,
+ 53, -103,
+ 145, 322,
+ -95, -31,
+ -100, -303,
+ -560, -1067,
+ -413, 714,
+ 283, 2,
+ -223, -367,
+ 523, 360,
+ -38, -115,
+ 378, -591,
+ -718, 448,
+ -481, -274,
+ 180, -88,
+ -581, -157,
+ -696, -1265,
+ 394, -479,
+ -23, 124,
+ -43, 19,
+ -113, -236,
+ -412, -659,
+ -200, 2,
+ -69, -342,
+ 199, 55,
+ 58, -36,
+ -51, -62,
+ 507, 507,
+ 427, 442,
+ 36, 601,
+ -141, 68,
+ 274, 274,
+ 68, -12,
+ -4, 71,
+ -193, -464,
+ -425, -383,
+ 408, 203,
+ -337, 236,
+ 410, -59,
+ -25, -341,
+ -449, 28,
+ -9, 90,
+ 332, -14,
+ -905, 96,
+ -540, -242,
+ 679, -59,
+ 192, -24,
+ 60, -217,
+ 5, -37,
+ 179, -20,
+ 311, 519,
+ 274, 72,
+ -326, -1030,
+ -262, 213,
+ 380, 82,
+ 328, 411,
+ -540, 574,
+ -283, 151,
+ 181, -402,
+ -278, -240,
+ -110, -227,
+ -264, -89,
+ -250, -259,
+ -27, 106,
+ -239, -98,
+ -390, 118,
+ 61, 104,
+ 294, 532,
+ 92, -13,
+ 60, -233,
+ 335, 541,
+ 307, -26,
+ -110, -91,
+ -231, -460,
+ 170, 201,
+ 96, -372,
+ 132, 435,
+ -302, 216,
+ -279, -41,
+ 74, 190,
+ 368, 273,
+ -186, -608,
+ -157, 159,
+ 12, 278,
+ 245, 307,
+ 25, -187,
+ -16, 55,
+ 30, -163,
+ 548, -307,
+ 106, -5,
+ 27, 330,
+ -416, 475,
+ 438, -235,
+ 104, 137,
+ 21, -5,
+ -300, -468,
+ 521, -347,
+ 170, -200,
+ -219, 308,
+ -122, -133,
+ 219, -16,
+ 359, 412,
+ -89, -111,
+ 48, 322,
+ 142, 177,
+ -286, -127,
+ -39, -63,
+ -42, -451,
+ 160, 308,
+ -57, 193,
+ -48, 74,
+ -346, 59,
+ -27, 27,
+ -469, -277,
+ -344, 282,
+ 262, 122,
+ 171, -249,
+ 27, 258,
+ 188, -3,
+ 67, -206,
+ -284, 291,
+ -117, -88,
+ -477, 375,
+ 50, 106,
+ 99, -182,
+ 438, -376,
+ -401, -49,
+ 119, -23,
+ -10, -48,
+ -116, -200,
+ -310, 121,
+ 73, 7,
+ 237, -226,
+ 139, -456,
+ 397, 35,
+ 3, -108,
+ 323, -75,
+ 332, 198,
+ -99, -21
+};
+
+const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB1_10_Stage_info[ NLSF_MSVQ_CB1_10_STAGES ] =
+{
+ { 32, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 0 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 0 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 32 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 32 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 40 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 40 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 48 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 48 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 56 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 56 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_10_Q15[ 10 * 64 ], &SKP_Silk_NLSF_MSVQ_CB1_10_rates_Q5[ 64 ] }
+};
+
+const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB1_10 =
+{
+ NLSF_MSVQ_CB1_10_STAGES,
+ SKP_Silk_NLSF_CB1_10_Stage_info,
+ SKP_Silk_NLSF_MSVQ_CB1_10_ndelta_min_Q15,
+ SKP_Silk_NLSF_MSVQ_CB1_10_CDF,
+ SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr,
+ SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_10.h b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_10.h
new file mode 100644
index 0000000..22fddf1
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_10.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_TABLES_NLSF_CB1_10_H
+#define SKP_SILK_TABLES_NLSF_CB1_10_H
+
+#include "SKP_Silk_define.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define NLSF_MSVQ_CB1_10_STAGES 6
+#define NLSF_MSVQ_CB1_10_VECTORS 72
+
+/* NLSF codebook entropy coding tables */
+extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_10_CDF[ NLSF_MSVQ_CB1_10_VECTORS + NLSF_MSVQ_CB1_10_STAGES ];
+extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_10_CDF_start_ptr[ NLSF_MSVQ_CB1_10_STAGES ];
+extern const SKP_int SKP_Silk_NLSF_MSVQ_CB1_10_CDF_middle_idx[ NLSF_MSVQ_CB1_10_STAGES ];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_16.c b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_16.c
new file mode 100644
index 0000000..e68aedc
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_16.c
@@ -0,0 +1,704 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 file has been automatically generated */
+/* */
+/* ROM usage: 0.29 + 3.57 kB */
+/**********************************************/
+
+#include "SKP_Silk_structs.h"
+#include "SKP_Silk_tables_NLSF_CB1_16.h"
+#include "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ NLSF_MSVQ_CB1_16_VECTORS + NLSF_MSVQ_CB1_16_STAGES ] =
+{
+ 0,
+ 19099,
+ 26957,
+ 30639,
+ 34242,
+ 37546,
+ 40447,
+ 43287,
+ 46005,
+ 48445,
+ 49865,
+ 51284,
+ 52673,
+ 53975,
+ 55221,
+ 56441,
+ 57267,
+ 58025,
+ 58648,
+ 59232,
+ 59768,
+ 60248,
+ 60729,
+ 61210,
+ 61690,
+ 62171,
+ 62651,
+ 63132,
+ 63613,
+ 64093,
+ 64574,
+ 65054,
+ 65535,
+ 0,
+ 28808,
+ 38775,
+ 46801,
+ 51785,
+ 55886,
+ 59410,
+ 62572,
+ 65535,
+ 0,
+ 27376,
+ 38639,
+ 45052,
+ 51465,
+ 55448,
+ 59021,
+ 62594,
+ 65535,
+ 0,
+ 33403,
+ 39569,
+ 45102,
+ 49961,
+ 54047,
+ 57959,
+ 61788,
+ 65535,
+ 0,
+ 25851,
+ 43356,
+ 47828,
+ 52204,
+ 55964,
+ 59413,
+ 62507,
+ 65535,
+ 0,
+ 34277,
+ 40337,
+ 45432,
+ 50311,
+ 54326,
+ 58171,
+ 61853,
+ 65535,
+ 0,
+ 33538,
+ 39865,
+ 45302,
+ 50076,
+ 54549,
+ 58478,
+ 62159,
+ 65535,
+ 0,
+ 27445,
+ 35258,
+ 40665,
+ 46072,
+ 51362,
+ 56540,
+ 61086,
+ 65535,
+ 0,
+ 22080,
+ 30779,
+ 37065,
+ 43085,
+ 48849,
+ 54613,
+ 60133,
+ 65535,
+ 0,
+ 13417,
+ 21748,
+ 30078,
+ 38231,
+ 46383,
+ 53091,
+ 59515,
+ 65535
+};
+
+const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr[ NLSF_MSVQ_CB1_16_STAGES ] =
+{
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 0 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 33 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 42 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 51 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 60 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 69 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 78 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 87 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 96 ],
+ &SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ 105 ]
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx[ NLSF_MSVQ_CB1_16_STAGES ] =
+{
+ 5,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 4
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ NLSF_MSVQ_CB1_16_VECTORS ] =
+{
+ 57, 98,
+ 133, 134,
+ 138, 144,
+ 145, 147,
+ 152, 177,
+ 177, 178,
+ 181, 183,
+ 184, 202,
+ 206, 215,
+ 218, 222,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 227, 227,
+ 38, 87,
+ 97, 119,
+ 128, 135,
+ 140, 143,
+ 40, 81,
+ 107, 107,
+ 129, 134,
+ 134, 143,
+ 31, 109,
+ 114, 120,
+ 128, 130,
+ 131, 132,
+ 43, 61,
+ 124, 125,
+ 132, 136,
+ 141, 142,
+ 30, 110,
+ 118, 120,
+ 129, 131,
+ 133, 133,
+ 31, 108,
+ 115, 121,
+ 124, 130,
+ 133, 137,
+ 40, 98,
+ 115, 115,
+ 116, 117,
+ 123, 124,
+ 50, 93,
+ 108, 110,
+ 112, 112,
+ 114, 115,
+ 73, 95,
+ 95, 96,
+ 96, 105,
+ 107, 110
+};
+
+const SKP_int SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min_Q15[ 16 + 1 ] =
+{
+ 148,
+ 3,
+ 60,
+ 68,
+ 117,
+ 86,
+ 121,
+ 124,
+ 152,
+ 153,
+ 207,
+ 151,
+ 225,
+ 239,
+ 126,
+ 183,
+ 792
+};
+
+const SKP_int16 SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * NLSF_MSVQ_CB1_16_VECTORS ] =
+{
+ 1309, 3060, 5071, 6996,
+ 9028, 10938, 12934, 14891,
+ 16933, 18854, 20792, 22764,
+ 24753, 26659, 28626, 30501,
+ 1264, 2745, 4610, 6408,
+ 8286, 10043, 12084, 14108,
+ 16118, 18163, 20095, 22164,
+ 24264, 26316, 28329, 30251,
+ 1044, 2080, 3672, 5179,
+ 7140, 9100, 11070, 13065,
+ 15423, 17790, 19931, 22101,
+ 24290, 26361, 28499, 30418,
+ 1131, 2476, 4478, 6149,
+ 7902, 9875, 11938, 13809,
+ 15869, 17730, 19948, 21707,
+ 23761, 25535, 27426, 28917,
+ 1040, 2004, 4026, 6100,
+ 8432, 10494, 12610, 14694,
+ 16797, 18775, 20799, 22782,
+ 24772, 26682, 28631, 30516,
+ 2310, 3812, 5913, 7933,
+ 10033, 11881, 13885, 15798,
+ 17751, 19576, 21482, 23276,
+ 25157, 27010, 28833, 30623,
+ 1254, 2847, 5013, 6781,
+ 8626, 10370, 12726, 14633,
+ 16281, 17852, 19870, 21472,
+ 23002, 24629, 26710, 27960,
+ 1468, 3059, 4987, 7026,
+ 8741, 10412, 12281, 14020,
+ 15970, 17723, 19640, 21522,
+ 23472, 25661, 27986, 30225,
+ 2171, 3566, 5605, 7384,
+ 9404, 11220, 13030, 14758,
+ 16687, 18417, 20346, 22091,
+ 24055, 26212, 28356, 30397,
+ 2409, 4676, 7543, 9786,
+ 11419, 12935, 14368, 15653,
+ 17366, 18943, 20762, 22477,
+ 24440, 26327, 28284, 30242,
+ 2354, 4222, 6820, 9107,
+ 11596, 13934, 15973, 17682,
+ 19158, 20517, 21991, 23420,
+ 25178, 26936, 28794, 30527,
+ 1323, 2414, 4184, 6039,
+ 7534, 9398, 11099, 13097,
+ 14799, 16451, 18434, 20887,
+ 23490, 25838, 28046, 30225,
+ 1361, 3243, 6048, 8511,
+ 11001, 13145, 15073, 16608,
+ 18126, 19381, 20912, 22607,
+ 24660, 26668, 28663, 30566,
+ 1216, 2648, 5901, 8422,
+ 10037, 11425, 12973, 14603,
+ 16686, 18600, 20555, 22415,
+ 24450, 26280, 28206, 30077,
+ 2417, 4048, 6316, 8433,
+ 10510, 12757, 15072, 17295,
+ 19573, 21503, 23329, 24782,
+ 26235, 27689, 29214, 30819,
+ 1012, 2345, 4991, 7377,
+ 9465, 11916, 14296, 16566,
+ 18672, 20544, 22292, 23838,
+ 25415, 27050, 28848, 30551,
+ 1937, 3693, 6267, 8019,
+ 10372, 12194, 14287, 15657,
+ 17431, 18864, 20769, 22206,
+ 24037, 25463, 27383, 28602,
+ 1969, 3305, 5017, 6726,
+ 8375, 9993, 11634, 13280,
+ 15078, 16751, 18464, 20119,
+ 21959, 23858, 26224, 29298,
+ 1198, 2647, 5428, 7423,
+ 9775, 12155, 14665, 16344,
+ 18121, 19790, 21557, 22847,
+ 24484, 25742, 27639, 28711,
+ 1636, 3353, 5447, 7597,
+ 9837, 11647, 13964, 16019,
+ 17862, 20116, 22319, 24037,
+ 25966, 28086, 29914, 31294,
+ 2676, 4105, 6378, 8223,
+ 10058, 11549, 13072, 14453,
+ 15956, 17355, 18931, 20402,
+ 22183, 23884, 25717, 27723,
+ 1373, 2593, 4449, 5633,
+ 7300, 8425, 9474, 10818,
+ 12769, 15722, 19002, 21429,
+ 23682, 25924, 28135, 30333,
+ 1596, 3183, 5378, 7164,
+ 8670, 10105, 11470, 12834,
+ 13991, 15042, 16642, 17903,
+ 20759, 25283, 27770, 30240,
+ 2037, 3987, 6237, 8117,
+ 9954, 12245, 14217, 15892,
+ 17775, 20114, 22314, 25942,
+ 26305, 26483, 26796, 28561,
+ 2181, 3858, 5760, 7924,
+ 10041, 11577, 13769, 15700,
+ 17429, 19879, 23583, 24538,
+ 25212, 25693, 28688, 30507,
+ 1992, 3882, 6474, 7883,
+ 9381, 12672, 14340, 15701,
+ 16658, 17832, 20850, 22885,
+ 24677, 26457, 28491, 30460,
+ 2391, 3988, 5448, 7432,
+ 11014, 12579, 13140, 14146,
+ 15898, 18592, 21104, 22993,
+ 24673, 27186, 28142, 29612,
+ 1713, 5102, 6989, 7798,
+ 8670, 10110, 12746, 14881,
+ 16709, 18407, 20126, 22107,
+ 24181, 26198, 28237, 30137,
+ 1612, 3617, 6148, 8359,
+ 9576, 11528, 14936, 17809,
+ 18287, 18729, 19001, 21111,
+ 24631, 26596, 28740, 30643,
+ 2266, 4168, 7862, 9546,
+ 9618, 9703, 10134, 13897,
+ 16265, 18432, 20587, 22605,
+ 24754, 26994, 29125, 30840,
+ 1840, 3917, 6272, 7809,
+ 9714, 11438, 13767, 15799,
+ 19244, 21972, 22980, 23180,
+ 23723, 25650, 29117, 31085,
+ 1458, 3612, 6008, 7488,
+ 9827, 11893, 14086, 15734,
+ 17440, 19535, 22424, 24767,
+ 29246, 29928, 30516, 30947,
+ -102, -121, -31, -6,
+ 5, -2, 8, -18,
+ -4, 6, 14, -2,
+ -12, -16, -12, -60,
+ -126, -353, -574, -677,
+ -657, -617, -498, -393,
+ -348, -277, -225, -164,
+ -102, -70, -31, 33,
+ 4, 379, 387, 551,
+ 605, 620, 532, 482,
+ 442, 454, 385, 347,
+ 322, 299, 266, 200,
+ 1168, 951, 672, 246,
+ 60, -161, -259, -234,
+ -253, -282, -203, -187,
+ -155, -176, -198, -178,
+ 10, 170, 393, 609,
+ 555, 208, -330, -571,
+ -769, -633, -319, -43,
+ 95, 105, 106, 116,
+ -152, -140, -125, 5,
+ 173, 274, 264, 331,
+ -37, -293, -609, -786,
+ -959, -814, -645, -238,
+ -91, 36, -11, -101,
+ -279, -227, -40, 90,
+ 530, 677, 890, 1104,
+ 999, 835, 564, 295,
+ -280, -364, -340, -331,
+ -284, 288, 761, 880,
+ 988, 627, 146, -226,
+ -203, -181, -142, 39,
+ 24, -26, -107, -92,
+ -161, -135, -131, -88,
+ -160, -156, -75, -43,
+ -36, -6, -33, 33,
+ -324, -415, -108, 124,
+ 157, 191, 203, 197,
+ 144, 109, 152, 176,
+ 190, 122, 101, 159,
+ 663, 668, 480, 400,
+ 379, 444, 446, 458,
+ 343, 351, 310, 228,
+ 133, 44, 75, 63,
+ -84, 39, -29, 35,
+ -94, -233, -261, -354,
+ 77, 262, -24, -145,
+ -333, -409, -404, -597,
+ -488, -300, 910, 592,
+ 412, 120, 130, -51,
+ -37, -77, -172, -181,
+ -159, -148, -72, -62,
+ 510, 516, 113, -585,
+ -1075, -957, -417, -195,
+ 9, 7, -88, -173,
+ -91, 54, 98, 95,
+ -28, 197, -527, -621,
+ 157, 122, -168, 147,
+ 309, 300, 336, 315,
+ 396, 408, 376, 106,
+ -162, -170, -315, 98,
+ 821, 908, 570, -33,
+ -312, -568, -572, -378,
+ -107, 23, 156, 93,
+ -129, -87, 20, -72,
+ -37, 40, 21, 27,
+ 48, 75, 77, 65,
+ 46, 71, 66, 47,
+ 136, 344, 236, 322,
+ 170, 283, 269, 291,
+ 162, -43, -204, -259,
+ -240, -305, -350, -312,
+ 447, 348, 345, 257,
+ 71, -131, -77, -190,
+ -202, -40, 35, 133,
+ 261, 365, 438, 303,
+ -8, 22, 140, 137,
+ -300, -641, -764, -268,
+ -23, -25, 73, -162,
+ -150, -212, -72, 6,
+ 39, 78, 104, -93,
+ -308, -136, 117, -71,
+ -513, -820, -700, -450,
+ -161, -23, 29, 78,
+ 337, 106, -406, -782,
+ -112, 233, 383, 62,
+ -126, 6, -77, -29,
+ -146, -123, -51, -27,
+ -27, -381, -641, 402,
+ 539, 8, -207, -366,
+ -36, -27, -204, -227,
+ -237, -189, -64, 51,
+ -92, -137, -281, 62,
+ 233, 92, 148, 294,
+ 363, 416, 564, 625,
+ 370, -36, -469, -462,
+ 102, 168, 32, 117,
+ -21, 97, 139, 89,
+ 104, 35, 4, 82,
+ 66, 58, 73, 93,
+ -76, -320, -236, -189,
+ -203, -142, -27, -73,
+ 9, -9, -25, 12,
+ -15, 4, 4, -50,
+ 314, 180, 162, -49,
+ 199, -108, -227, -66,
+ -447, -67, -264, -394,
+ 5, 55, -133, -176,
+ -116, -241, 272, 109,
+ 282, 262, 192, -64,
+ -392, -514, 156, 203,
+ 154, 72, -34, -160,
+ -73, 3, -33, -431,
+ 321, 18, -567, -590,
+ -108, 88, 66, 51,
+ -31, -193, -46, 65,
+ -29, -23, 215, -31,
+ 101, -113, 32, 304,
+ 88, 320, 448, 5,
+ -439, -562, -508, -135,
+ -13, -171, -8, 182,
+ -99, -181, -149, 376,
+ 476, 64, -396, -652,
+ -150, 176, 222, 65,
+ -590, 719, 271, 399,
+ 245, 72, -156, -152,
+ -176, 59, 94, 125,
+ -9, -7, 9, 1,
+ -61, -116, -82, 1,
+ 79, 22, -44, -15,
+ -48, -65, -62, -101,
+ -102, -54, -70, -78,
+ -80, -25, 398, 71,
+ 139, 38, 90, 194,
+ 222, 249, 165, 94,
+ 221, 262, 163, 91,
+ -206, 573, 200, -287,
+ -147, 5, -18, -85,
+ -74, -125, -87, 85,
+ 141, 4, -4, 28,
+ 234, 48, -150, -111,
+ -506, 237, -209, 345,
+ 94, -124, 77, 121,
+ 143, 12, -80, -48,
+ 191, 144, -93, -65,
+ -151, -643, 435, 106,
+ 87, 7, 65, 102,
+ 94, 68, 5, 99,
+ 222, 93, 94, 355,
+ -13, -89, -228, -503,
+ 287, 109, 108, 449,
+ 253, -29, -109, -116,
+ 15, -73, -20, 131,
+ -147, 72, 59, -150,
+ -594, 273, 316, 132,
+ 199, 106, 198, 212,
+ 220, 82, 45, -13,
+ 223, 137, 270, 38,
+ 252, 135, -177, -207,
+ -360, -102, 403, 406,
+ -14, 83, 64, 51,
+ -7, -99, -97, -88,
+ -124, -65, 42, 32,
+ 28, 29, 12, 20,
+ 119, -26, -212, -201,
+ 373, 251, 141, 103,
+ 36, -52, 66, 18,
+ -6, -95, -196, 5,
+ 98, -85, -108, 218,
+ -164, 20, 356, 172,
+ 37, 266, 23, 112,
+ -24, -99, -92, -178,
+ 29, -278, 388, -60,
+ -220, 300, -13, 154,
+ 191, 15, -37, -110,
+ -153, -150, -114, -7,
+ -94, -31, -62, -177,
+ 4, -70, 35, 453,
+ 147, -247, -328, 101,
+ 20, -114, 147, 108,
+ -119, -109, -102, -238,
+ 55, -102, 173, -89,
+ 129, 138, -330, -160,
+ 485, 154, -59, -170,
+ -20, -34, -261, -40,
+ -129, 77, -84, 69,
+ 83, 160, 169, 63,
+ -516, 30, 336, 52,
+ -0, -52, -124, 158,
+ 19, 197, -10, -375,
+ 405, 285, 114, -395,
+ -47, 196, 62, 87,
+ -106, -65, -75, -69,
+ -13, 34, 99, 59,
+ 83, 98, 44, 0,
+ 24, 18, 17, 70,
+ -22, 194, 208, 144,
+ -79, -15, 32, -104,
+ -28, -105, -186, -212,
+ -228, -79, -76, 51,
+ -71, 72, 118, -34,
+ -3, -171, 5, 2,
+ -108, -125, 62, -58,
+ 58, -121, 73, -466,
+ 92, 63, -94, -78,
+ -76, 212, 36, -225,
+ -71, -354, 152, 143,
+ -79, -246, -51, -31,
+ -6, -270, 240, 210,
+ 30, -157, -231, 74,
+ -146, 88, -273, 156,
+ 92, 56, 71, 2,
+ 318, 164, 32, -110,
+ -35, -41, -95, -106,
+ 11, 132, -68, 55,
+ 123, -83, -149, 212,
+ 132, 0, -194, 55,
+ 206, -108, -353, 289,
+ -195, 1, 233, -22,
+ -60, 20, 26, 68,
+ 166, 27, -58, 130,
+ 112, 107, 27, -165,
+ 115, -93, -37, 38,
+ 83, 483, 65, -229,
+ -13, 157, 85, 50,
+ 136, 10, 32, 83,
+ 82, 55, 5, -9,
+ -52, -78, -81, -51,
+ 40, 18, -127, -224,
+ -41, 53, -210, -113,
+ 24, -17, -187, -89,
+ 8, 121, 83, 77,
+ 91, -74, -35, -112,
+ -161, -173, 102, 132,
+ -125, -61, 103, -260,
+ 52, 166, -32, -156,
+ -87, -56, 60, -70,
+ -124, 242, 114, -251,
+ -166, 201, 127, 28,
+ -11, 23, -80, -115,
+ -20, -51, -348, 340,
+ -34, 133, 13, 92,
+ -124, -136, -120, -26,
+ -6, 17, 28, 21,
+ 120, -168, 160, -35,
+ 115, 28, 9, 7,
+ -56, 39, 156, 256,
+ -18, 1, 277, 82,
+ -70, -144, -88, -13,
+ -59, -157, 8, -134,
+ 21, -40, 58, -21,
+ 194, -276, 97, 279,
+ -56, -140, 125, 57,
+ -184, -204, -70, -2,
+ 128, -202, -78, 230,
+ -23, 161, -102, 1,
+ 1, 180, -31, -86,
+ -167, -57, -60, 27,
+ -13, 99, 108, 111,
+ 76, 69, 34, -21,
+ 53, 38, 34, 78,
+ 73, 219, 51, 15,
+ -72, -103, -207, 30,
+ 213, -14, 31, -94,
+ -40, -144, 67, 4,
+ 105, 59, -240, 25,
+ 244, 69, 58, 23,
+ -24, -5, -15, -133,
+ -71, -67, 181, 29,
+ -45, 121, 96, 51,
+ -72, -53, 56, -153,
+ -27, 85, 183, 211,
+ 105, -34, -46, 43,
+ -72, -93, 36, -128,
+ 29, 111, -95, -156,
+ -179, -235, 21, -39,
+ -71, -33, -61, -252,
+ 230, -131, 157, -21,
+ -85, -28, -123, 80,
+ -160, 63, 47, -6,
+ -49, -96, -19, 17,
+ -58, 17, -0, -13,
+ -170, 25, -35, 59,
+ 10, -31, -413, 81,
+ 62, 18, -164, 245,
+ 92, -165, 42, 26,
+ 126, -248, 193, -55,
+ 16, 39, 14, 50
+};
+
+const SKP_Silk_NLSF_CBS SKP_Silk_NLSF_CB1_16_Stage_info[ NLSF_MSVQ_CB1_16_STAGES ] =
+{
+ { 32, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 0 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 0 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 32 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 32 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 40 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 40 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 48 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 48 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 56 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 56 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 64 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 64 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 72 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 72 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 80 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 80 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 88 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 88 ] },
+ { 8, &SKP_Silk_NLSF_MSVQ_CB1_16_Q15[ 16 * 96 ], &SKP_Silk_NLSF_MSVQ_CB1_16_rates_Q5[ 96 ] }
+};
+
+const SKP_Silk_NLSF_CB_struct SKP_Silk_NLSF_CB1_16 =
+{
+ NLSF_MSVQ_CB1_16_STAGES,
+ SKP_Silk_NLSF_CB1_16_Stage_info,
+ SKP_Silk_NLSF_MSVQ_CB1_16_ndelta_min_Q15,
+ SKP_Silk_NLSF_MSVQ_CB1_16_CDF,
+ SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr,
+ SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_16.h b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_16.h
new file mode 100644
index 0000000..ca63a44
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_NLSF_CB1_16.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_TABLES_NLSF_CB1_16_H
+#define SKP_SILK_TABLES_NLSF_CB1_16_H
+
+#include "SKP_Silk_define.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define NLSF_MSVQ_CB1_16_STAGES 10
+#define NLSF_MSVQ_CB1_16_VECTORS 104
+
+/* NLSF codebook entropy coding tables */
+extern const SKP_uint16 SKP_Silk_NLSF_MSVQ_CB1_16_CDF[ NLSF_MSVQ_CB1_16_VECTORS + NLSF_MSVQ_CB1_16_STAGES ];
+extern const SKP_uint16 * const SKP_Silk_NLSF_MSVQ_CB1_16_CDF_start_ptr[ NLSF_MSVQ_CB1_16_STAGES ];
+extern const SKP_int SKP_Silk_NLSF_MSVQ_CB1_16_CDF_middle_idx[ NLSF_MSVQ_CB1_16_STAGES ];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_gain.c b/pkg/silk/csilk/SKP_Silk_tables_gain.c
new file mode 100644
index 0000000..7556123
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_gain.c
@@ -0,0 +1,77 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_tables.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+const SKP_uint16 SKP_Silk_gain_CDF[ 2 ][ 65 ] =
+{
+{
+ 0, 18, 45, 94, 181, 320, 519, 777,
+ 1093, 1468, 1909, 2417, 2997, 3657, 4404, 5245,
+ 6185, 7228, 8384, 9664, 11069, 12596, 14244, 16022,
+ 17937, 19979, 22121, 24345, 26646, 29021, 31454, 33927,
+ 36438, 38982, 41538, 44068, 46532, 48904, 51160, 53265,
+ 55184, 56904, 58422, 59739, 60858, 61793, 62568, 63210,
+ 63738, 64165, 64504, 64769, 64976, 65133, 65249, 65330,
+ 65386, 65424, 65451, 65471, 65487, 65501, 65513, 65524,
+ 65535
+},
+{
+ 0, 214, 581, 1261, 2376, 3920, 5742, 7632,
+ 9449, 11157, 12780, 14352, 15897, 17427, 18949, 20462,
+ 21957, 23430, 24889, 26342, 27780, 29191, 30575, 31952,
+ 33345, 34763, 36200, 37642, 39083, 40519, 41930, 43291,
+ 44602, 45885, 47154, 48402, 49619, 50805, 51959, 53069,
+ 54127, 55140, 56128, 57101, 58056, 58979, 59859, 60692,
+ 61468, 62177, 62812, 63368, 63845, 64242, 64563, 64818,
+ 65023, 65184, 65306, 65391, 65447, 65482, 65505, 65521,
+ 65535
+}
+};
+
+const SKP_int SKP_Silk_gain_CDF_offset = 32;
+
+
+const SKP_uint16 SKP_Silk_delta_gain_CDF[ 46 ] = {
+ 0, 2358, 3856, 7023, 15376, 53058, 59135, 61555,
+ 62784, 63498, 63949, 64265, 64478, 64647, 64783, 64894,
+ 64986, 65052, 65113, 65169, 65213, 65252, 65284, 65314,
+ 65338, 65359, 65377, 65392, 65403, 65415, 65424, 65432,
+ 65440, 65448, 65455, 65462, 65470, 65477, 65484, 65491,
+ 65499, 65506, 65513, 65521, 65528, 65535
+};
+
+const SKP_int SKP_Silk_delta_gain_CDF_offset = 5;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_tables_other.c b/pkg/silk/csilk/SKP_Silk_tables_other.c
new file mode 100644
index 0000000..27bba2b
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_other.c
@@ -0,0 +1,148 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_structs.h"
+#include "SKP_Silk_define.h"
+#include "SKP_Silk_tables.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
+const SKP_int32 TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = {
+ 0, 8000, 9000, 11000, 13000, 16000, 22000, MAX_TARGET_RATE_BPS
+};
+const SKP_int32 TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = {
+ 0, 10000, 12000, 14000, 17000, 21000, 28000, MAX_TARGET_RATE_BPS
+};
+const SKP_int32 TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = {
+ 0, 11000, 14000, 17000, 21000, 26000, 36000, MAX_TARGET_RATE_BPS
+};
+const SKP_int32 TargetRate_table_SWB[ TARGET_RATE_TAB_SZ ] = {
+ 0, 13000, 16000, 19000, 25000, 32000, 46000, MAX_TARGET_RATE_BPS
+};
+const SKP_int32 SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = {
+ 19, 31, 35, 39, 43, 47, 54, 64
+};
+
+const SKP_int32 SNR_table_one_bit_per_sample_Q7[ 4 ] = {
+ 1984, 2240, 2408, 2708
+};
+
+/* Filter coeficicnts for HP filter: 4. Order filter implementad as two biquad filters */
+const SKP_int16 SKP_Silk_SWB_detect_B_HP_Q13[ NB_SOS ][ 3 ] = {
+ //{400, -550, 400}, {400, 130, 400}, {400, 390, 400}
+ {575, -948, 575}, {575, -221, 575}, {575, 104, 575}
+};
+const SKP_int16 SKP_Silk_SWB_detect_A_HP_Q13[ NB_SOS ][ 2 ] = {
+ {14613, 6868}, {12883, 7337}, {11586, 7911}
+ //{14880, 6900}, {14400, 7300}, {13700, 7800}
+};
+
+/* Decoder high-pass filter coefficients for 24 kHz sampling, -6 dB @ 44 Hz */
+const SKP_int16 SKP_Silk_Dec_A_HP_24[ DEC_HP_ORDER ] = {-16220, 8030}; // second order AR coefs, Q13
+const SKP_int16 SKP_Silk_Dec_B_HP_24[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13
+
+/* Decoder high-pass filter coefficients for 16 kHz sampling, - 6 dB @ 46 Hz */
+const SKP_int16 SKP_Silk_Dec_A_HP_16[ DEC_HP_ORDER ] = {-16127, 7940}; // second order AR coefs, Q13
+const SKP_int16 SKP_Silk_Dec_B_HP_16[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13
+
+/* Decoder high-pass filter coefficients for 12 kHz sampling, -6 dB @ 44 Hz */
+const SKP_int16 SKP_Silk_Dec_A_HP_12[ DEC_HP_ORDER ] = {-16043, 7859}; // second order AR coefs, Q13
+const SKP_int16 SKP_Silk_Dec_B_HP_12[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13
+
+/* Decoder high-pass filter coefficients for 8 kHz sampling, -6 dB @ 43 Hz */
+const SKP_int16 SKP_Silk_Dec_A_HP_8[ DEC_HP_ORDER ] = {-15885, 7710}; // second order AR coefs, Q13
+const SKP_int16 SKP_Silk_Dec_B_HP_8[ DEC_HP_ORDER + 1 ] = {8000, -16000, 8000}; // second order MA coefs, Q13
+
+/* table for LSB coding */
+const SKP_uint16 SKP_Silk_lsb_CDF[ 3 ] = {0, 40000, 65535};
+
+/* tables for LTPScale */
+const SKP_uint16 SKP_Silk_LTPscale_CDF[ 4 ] = {0, 32000, 48000, 65535};
+const SKP_int SKP_Silk_LTPscale_offset = 2;
+
+/* tables for VAD flag */
+const SKP_uint16 SKP_Silk_vadflag_CDF[ 3 ] = {0, 22000, 65535}; // 66% for speech, 33% for no speech
+const SKP_int SKP_Silk_vadflag_offset = 1;
+
+/* tables for sampling rate */
+const SKP_int SKP_Silk_SamplingRates_table[ 4 ] = {8, 12, 16, 24};
+const SKP_uint16 SKP_Silk_SamplingRates_CDF[ 5 ] = {0, 16000, 32000, 48000, 65535};
+const SKP_int SKP_Silk_SamplingRates_offset = 2;
+
+/* tables for NLSF interpolation factor */
+const SKP_uint16 SKP_Silk_NLSF_interpolation_factor_CDF[ 6 ] = {0, 3706, 8703, 19226, 30926, 65535};
+const SKP_int SKP_Silk_NLSF_interpolation_factor_offset = 4;
+
+/* Table for frame termination indication */
+const SKP_uint16 SKP_Silk_FrameTermination_CDF[ 5 ] = {0, 20000, 45000, 56000, 65535};
+const SKP_int SKP_Silk_FrameTermination_offset = 2;
+
+/* Table for random seed */
+const SKP_uint16 SKP_Silk_Seed_CDF[ 5 ] = {0, 16384, 32768, 49152, 65535};
+const SKP_int SKP_Silk_Seed_offset = 2;
+
+/* Quantization offsets */
+const SKP_int16 SKP_Silk_Quantization_Offsets_Q10[ 2 ][ 2 ] = {
+ { OFFSET_VL_Q10, OFFSET_VH_Q10 }, { OFFSET_UVL_Q10, OFFSET_UVH_Q10 }
+};
+
+/* Table for LTPScale */
+const SKP_int16 SKP_Silk_LTPScales_table_Q14[ 3 ] = { 15565, 11469, 8192 };
+
+#if SWITCH_TRANSITION_FILTERING
+/* Elliptic/Cauer filters designed with 0.1 dB passband ripple,
+ 80 dB minimum stopband attenuation, and
+ [0.95 : 0.15 : 0.35] normalized cut off frequencies. */
+
+/* Interpolation points for filter coefficients used in the bandwidth transition smoother */
+const SKP_int32 SKP_Silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ] =
+{
+{ 250767114, 501534038, 250767114 },
+{ 209867381, 419732057, 209867381 },
+{ 170987846, 341967853, 170987846 },
+{ 131531482, 263046905, 131531482 },
+{ 89306658, 178584282, 89306658 }
+};
+
+/* Interpolation points for filter coefficients used in the bandwidth transition smoother */
+const SKP_int32 SKP_Silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ] =
+{
+{ 506393414, 239854379 },
+{ 411067935, 169683996 },
+{ 306733530, 116694253 },
+{ 185807084, 77959395 },
+{ 35497197, 57401098 }
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_pitch_lag.c b/pkg/silk/csilk/SKP_Silk_tables_pitch_lag.c
new file mode 100644
index 0000000..555bc67
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_pitch_lag.c
@@ -0,0 +1,199 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_pitch_lag_NB_CDF[ 8 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = {
+ 0, 194, 395, 608, 841, 1099, 1391, 1724,
+ 2105, 2544, 3047, 3624, 4282, 5027, 5865, 6799,
+ 7833, 8965, 10193, 11510, 12910, 14379, 15905, 17473,
+ 19065, 20664, 22252, 23814, 25335, 26802, 28206, 29541,
+ 30803, 31992, 33110, 34163, 35156, 36098, 36997, 37861,
+ 38698, 39515, 40319, 41115, 41906, 42696, 43485, 44273,
+ 45061, 45847, 46630, 47406, 48175, 48933, 49679, 50411,
+ 51126, 51824, 52502, 53161, 53799, 54416, 55011, 55584,
+ 56136, 56666, 57174, 57661, 58126, 58570, 58993, 59394,
+ 59775, 60134, 60472, 60790, 61087, 61363, 61620, 61856,
+ 62075, 62275, 62458, 62625, 62778, 62918, 63045, 63162,
+ 63269, 63368, 63459, 63544, 63623, 63698, 63769, 63836,
+ 63901, 63963, 64023, 64081, 64138, 64194, 64248, 64301,
+ 64354, 64406, 64457, 64508, 64558, 64608, 64657, 64706,
+ 64754, 64803, 64851, 64899, 64946, 64994, 65041, 65088,
+ 65135, 65181, 65227, 65272, 65317, 65361, 65405, 65449,
+ 65492, 65535
+};
+
+const SKP_int SKP_Silk_pitch_lag_NB_CDF_offset = 43;
+
+const SKP_uint16 SKP_Silk_pitch_contour_NB_CDF[ 12 ] = {
+ 0, 14445, 18587, 25628, 30013, 34859, 40597, 48426,
+ 54460, 59033, 62990, 65535
+};
+
+const SKP_int SKP_Silk_pitch_contour_NB_CDF_offset = 5;
+
+const SKP_uint16 SKP_Silk_pitch_lag_MB_CDF[ 12 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = {
+ 0, 132, 266, 402, 542, 686, 838, 997,
+ 1167, 1349, 1546, 1760, 1993, 2248, 2528, 2835,
+ 3173, 3544, 3951, 4397, 4882, 5411, 5984, 6604,
+ 7270, 7984, 8745, 9552, 10405, 11300, 12235, 13206,
+ 14209, 15239, 16289, 17355, 18430, 19507, 20579, 21642,
+ 22688, 23712, 24710, 25677, 26610, 27507, 28366, 29188,
+ 29971, 30717, 31427, 32104, 32751, 33370, 33964, 34537,
+ 35091, 35630, 36157, 36675, 37186, 37692, 38195, 38697,
+ 39199, 39701, 40206, 40713, 41222, 41733, 42247, 42761,
+ 43277, 43793, 44309, 44824, 45336, 45845, 46351, 46851,
+ 47347, 47836, 48319, 48795, 49264, 49724, 50177, 50621,
+ 51057, 51484, 51902, 52312, 52714, 53106, 53490, 53866,
+ 54233, 54592, 54942, 55284, 55618, 55944, 56261, 56571,
+ 56873, 57167, 57453, 57731, 58001, 58263, 58516, 58762,
+ 58998, 59226, 59446, 59656, 59857, 60050, 60233, 60408,
+ 60574, 60732, 60882, 61024, 61159, 61288, 61410, 61526,
+ 61636, 61742, 61843, 61940, 62033, 62123, 62210, 62293,
+ 62374, 62452, 62528, 62602, 62674, 62744, 62812, 62879,
+ 62945, 63009, 63072, 63135, 63196, 63256, 63316, 63375,
+ 63434, 63491, 63549, 63605, 63661, 63717, 63772, 63827,
+ 63881, 63935, 63988, 64041, 64094, 64147, 64199, 64252,
+ 64304, 64356, 64409, 64461, 64513, 64565, 64617, 64669,
+ 64721, 64773, 64824, 64875, 64925, 64975, 65024, 65072,
+ 65121, 65168, 65215, 65262, 65308, 65354, 65399, 65445,
+ 65490, 65535
+};
+
+const SKP_int SKP_Silk_pitch_lag_MB_CDF_offset = 64;
+
+const SKP_uint16 SKP_Silk_pitch_lag_WB_CDF[ 16 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = {
+ 0, 106, 213, 321, 429, 539, 651, 766,
+ 884, 1005, 1132, 1264, 1403, 1549, 1705, 1870,
+ 2047, 2236, 2439, 2658, 2893, 3147, 3420, 3714,
+ 4030, 4370, 4736, 5127, 5546, 5993, 6470, 6978,
+ 7516, 8086, 8687, 9320, 9985, 10680, 11405, 12158,
+ 12938, 13744, 14572, 15420, 16286, 17166, 18057, 18955,
+ 19857, 20759, 21657, 22547, 23427, 24293, 25141, 25969,
+ 26774, 27555, 28310, 29037, 29736, 30406, 31048, 31662,
+ 32248, 32808, 33343, 33855, 34345, 34815, 35268, 35704,
+ 36127, 36537, 36938, 37330, 37715, 38095, 38471, 38844,
+ 39216, 39588, 39959, 40332, 40707, 41084, 41463, 41844,
+ 42229, 42615, 43005, 43397, 43791, 44186, 44583, 44982,
+ 45381, 45780, 46179, 46578, 46975, 47371, 47765, 48156,
+ 48545, 48930, 49312, 49690, 50064, 50433, 50798, 51158,
+ 51513, 51862, 52206, 52544, 52877, 53204, 53526, 53842,
+ 54152, 54457, 54756, 55050, 55338, 55621, 55898, 56170,
+ 56436, 56697, 56953, 57204, 57449, 57689, 57924, 58154,
+ 58378, 58598, 58812, 59022, 59226, 59426, 59620, 59810,
+ 59994, 60173, 60348, 60517, 60681, 60840, 60993, 61141,
+ 61284, 61421, 61553, 61679, 61800, 61916, 62026, 62131,
+ 62231, 62326, 62417, 62503, 62585, 62663, 62737, 62807,
+ 62874, 62938, 62999, 63057, 63113, 63166, 63217, 63266,
+ 63314, 63359, 63404, 63446, 63488, 63528, 63567, 63605,
+ 63642, 63678, 63713, 63748, 63781, 63815, 63847, 63879,
+ 63911, 63942, 63973, 64003, 64033, 64063, 64092, 64121,
+ 64150, 64179, 64207, 64235, 64263, 64291, 64319, 64347,
+ 64374, 64401, 64428, 64455, 64481, 64508, 64534, 64560,
+ 64585, 64610, 64635, 64660, 64685, 64710, 64734, 64758,
+ 64782, 64807, 64831, 64855, 64878, 64902, 64926, 64950,
+ 64974, 64998, 65022, 65045, 65069, 65093, 65116, 65139,
+ 65163, 65186, 65209, 65231, 65254, 65276, 65299, 65321,
+ 65343, 65364, 65386, 65408, 65429, 65450, 65471, 65493,
+ 65514, 65535
+};
+
+const SKP_int SKP_Silk_pitch_lag_WB_CDF_offset = 86;
+
+
+const SKP_uint16 SKP_Silk_pitch_lag_SWB_CDF[ 24 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) + 2 ] = {
+ 0, 253, 505, 757, 1008, 1258, 1507, 1755,
+ 2003, 2249, 2494, 2738, 2982, 3225, 3469, 3713,
+ 3957, 4202, 4449, 4698, 4949, 5203, 5460, 5720,
+ 5983, 6251, 6522, 6798, 7077, 7361, 7650, 7942,
+ 8238, 8539, 8843, 9150, 9461, 9775, 10092, 10411,
+ 10733, 11057, 11383, 11710, 12039, 12370, 12701, 13034,
+ 13368, 13703, 14040, 14377, 14716, 15056, 15398, 15742,
+ 16087, 16435, 16785, 17137, 17492, 17850, 18212, 18577,
+ 18946, 19318, 19695, 20075, 20460, 20849, 21243, 21640,
+ 22041, 22447, 22856, 23269, 23684, 24103, 24524, 24947,
+ 25372, 25798, 26225, 26652, 27079, 27504, 27929, 28352,
+ 28773, 29191, 29606, 30018, 30427, 30831, 31231, 31627,
+ 32018, 32404, 32786, 33163, 33535, 33902, 34264, 34621,
+ 34973, 35320, 35663, 36000, 36333, 36662, 36985, 37304,
+ 37619, 37929, 38234, 38535, 38831, 39122, 39409, 39692,
+ 39970, 40244, 40513, 40778, 41039, 41295, 41548, 41796,
+ 42041, 42282, 42520, 42754, 42985, 43213, 43438, 43660,
+ 43880, 44097, 44312, 44525, 44736, 44945, 45153, 45359,
+ 45565, 45769, 45972, 46175, 46377, 46578, 46780, 46981,
+ 47182, 47383, 47585, 47787, 47989, 48192, 48395, 48599,
+ 48804, 49009, 49215, 49422, 49630, 49839, 50049, 50259,
+ 50470, 50682, 50894, 51107, 51320, 51533, 51747, 51961,
+ 52175, 52388, 52601, 52813, 53025, 53236, 53446, 53655,
+ 53863, 54069, 54274, 54477, 54679, 54879, 55078, 55274,
+ 55469, 55662, 55853, 56042, 56230, 56415, 56598, 56779,
+ 56959, 57136, 57311, 57484, 57654, 57823, 57989, 58152,
+ 58314, 58473, 58629, 58783, 58935, 59084, 59230, 59373,
+ 59514, 59652, 59787, 59919, 60048, 60174, 60297, 60417,
+ 60533, 60647, 60757, 60865, 60969, 61070, 61167, 61262,
+ 61353, 61442, 61527, 61609, 61689, 61765, 61839, 61910,
+ 61979, 62045, 62109, 62170, 62230, 62287, 62343, 62396,
+ 62448, 62498, 62547, 62594, 62640, 62685, 62728, 62770,
+ 62811, 62852, 62891, 62929, 62967, 63004, 63040, 63075,
+ 63110, 63145, 63178, 63212, 63244, 63277, 63308, 63340,
+ 63371, 63402, 63432, 63462, 63491, 63521, 63550, 63578,
+ 63607, 63635, 63663, 63690, 63718, 63744, 63771, 63798,
+ 63824, 63850, 63875, 63900, 63925, 63950, 63975, 63999,
+ 64023, 64046, 64069, 64092, 64115, 64138, 64160, 64182,
+ 64204, 64225, 64247, 64268, 64289, 64310, 64330, 64351,
+ 64371, 64391, 64411, 64431, 64450, 64470, 64489, 64508,
+ 64527, 64545, 64564, 64582, 64600, 64617, 64635, 64652,
+ 64669, 64686, 64702, 64719, 64735, 64750, 64766, 64782,
+ 64797, 64812, 64827, 64842, 64857, 64872, 64886, 64901,
+ 64915, 64930, 64944, 64959, 64974, 64988, 65003, 65018,
+ 65033, 65048, 65063, 65078, 65094, 65109, 65125, 65141,
+ 65157, 65172, 65188, 65204, 65220, 65236, 65252, 65268,
+ 65283, 65299, 65314, 65330, 65345, 65360, 65375, 65390,
+ 65405, 65419, 65434, 65449, 65463, 65477, 65492, 65506,
+ 65521, 65535
+};
+
+const SKP_int SKP_Silk_pitch_lag_SWB_CDF_offset = 128;
+
+
+const SKP_uint16 SKP_Silk_pitch_contour_CDF[ 35 ] = {
+ 0, 372, 843, 1315, 1836, 2644, 3576, 4719,
+ 6088, 7621, 9396, 11509, 14245, 17618, 20777, 24294,
+ 27992, 33116, 40100, 44329, 47558, 50679, 53130, 55557,
+ 57510, 59022, 60285, 61345, 62316, 63140, 63762, 64321,
+ 64729, 65099, 65535
+};
+
+const SKP_int SKP_Silk_pitch_contour_CDF_offset = 17;
+
+const SKP_uint16 SKP_Silk_pitch_delta_CDF[23] = {
+ 0, 343, 740, 1249, 1889, 2733, 3861, 5396,
+ 7552, 10890, 16053, 24152, 30220, 34680, 37973, 40405,
+ 42243, 43708, 44823, 45773, 46462, 47055, 65535
+};
+
+const SKP_int SKP_Silk_pitch_delta_CDF_offset = 11;
diff --git a/pkg/silk/csilk/SKP_Silk_tables_pulses_per_block.c b/pkg/silk/csilk/SKP_Silk_tables_pulses_per_block.c
new file mode 100644
index 0000000..b5803d4
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_pulses_per_block.c
@@ -0,0 +1,235 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_tables.h"
+
+const SKP_int SKP_Silk_max_pulses_table[ 4 ] = {
+ 6, 8, 12, 18
+};
+
+const SKP_uint16 SKP_Silk_pulses_per_block_CDF[ 10 ][ 21 ] =
+{
+{
+ 0, 47113, 61501, 64590, 65125, 65277, 65352, 65407,
+ 65450, 65474, 65488, 65501, 65508, 65514, 65516, 65520,
+ 65521, 65523, 65524, 65526, 65535
+},
+{
+ 0, 26368, 47760, 58803, 63085, 64567, 65113, 65333,
+ 65424, 65474, 65498, 65511, 65517, 65520, 65523, 65525,
+ 65526, 65528, 65529, 65530, 65535
+},
+{
+ 0, 9601, 28014, 45877, 57210, 62560, 64611, 65260,
+ 65447, 65500, 65511, 65519, 65521, 65525, 65526, 65529,
+ 65530, 65531, 65532, 65534, 65535
+},
+{
+ 0, 3351, 12462, 25972, 39782, 50686, 57644, 61525,
+ 63521, 64506, 65009, 65255, 65375, 65441, 65471, 65488,
+ 65497, 65505, 65509, 65512, 65535
+},
+{
+ 0, 488, 2944, 9295, 19712, 32160, 43976, 53121,
+ 59144, 62518, 64213, 65016, 65346, 65470, 65511, 65515,
+ 65525, 65529, 65531, 65534, 65535
+},
+{
+ 0, 17013, 30405, 40812, 48142, 53466, 57166, 59845,
+ 61650, 62873, 63684, 64223, 64575, 64811, 64959, 65051,
+ 65111, 65143, 65165, 65183, 65535
+},
+{
+ 0, 2994, 8323, 15845, 24196, 32300, 39340, 45140,
+ 49813, 53474, 56349, 58518, 60167, 61397, 62313, 62969,
+ 63410, 63715, 63906, 64056, 65535
+},
+{
+ 0, 88, 721, 2795, 7542, 14888, 24420, 34593,
+ 43912, 51484, 56962, 60558, 62760, 64037, 64716, 65069,
+ 65262, 65358, 65398, 65420, 65535
+},
+{
+ 0, 287, 789, 2064, 4398, 8174, 13534, 20151,
+ 27347, 34533, 41295, 47242, 52070, 55772, 58458, 60381,
+ 61679, 62533, 63109, 63519, 65535
+},
+{
+ 0, 1, 3, 91, 4521, 14708, 28329, 41955,
+ 52116, 58375, 61729, 63534, 64459, 64924, 65092, 65164,
+ 65182, 65198, 65203, 65211, 65535
+}
+};
+
+const SKP_int SKP_Silk_pulses_per_block_CDF_offset = 6;
+
+
+const SKP_int16 SKP_Silk_pulses_per_block_BITS_Q6[ 9 ][ 20 ] =
+{
+{
+ 30, 140, 282, 444, 560, 625, 654, 677,
+ 731, 780, 787, 844, 859, 960, 896, 1024,
+ 960, 1024, 960, 821
+},
+{
+ 84, 103, 164, 252, 350, 442, 526, 607,
+ 663, 731, 787, 859, 923, 923, 960, 1024,
+ 960, 1024, 1024, 875
+},
+{
+ 177, 117, 120, 162, 231, 320, 426, 541,
+ 657, 803, 832, 960, 896, 1024, 923, 1024,
+ 1024, 1024, 960, 1024
+},
+{
+ 275, 182, 146, 144, 166, 207, 261, 322,
+ 388, 450, 516, 582, 637, 710, 762, 821,
+ 832, 896, 923, 734
+},
+{
+ 452, 303, 216, 170, 153, 158, 182, 220,
+ 274, 337, 406, 489, 579, 681, 896, 811,
+ 896, 960, 923, 1024
+},
+{
+ 125, 147, 170, 202, 232, 265, 295, 332,
+ 368, 406, 443, 483, 520, 563, 606, 646,
+ 704, 739, 757, 483
+},
+{
+ 285, 232, 200, 190, 193, 206, 224, 244,
+ 266, 289, 315, 340, 367, 394, 425, 462,
+ 496, 539, 561, 350
+},
+{
+ 611, 428, 319, 242, 202, 178, 172, 180,
+ 199, 229, 268, 313, 364, 422, 482, 538,
+ 603, 683, 739, 586
+},
+{
+ 501, 450, 364, 308, 264, 231, 212, 204,
+ 204, 210, 222, 241, 265, 295, 326, 362,
+ 401, 437, 469, 321
+}
+};
+
+const SKP_uint16 SKP_Silk_rate_levels_CDF[ 2 ][ 10 ] =
+{
+{
+ 0, 2005, 12717, 20281, 31328, 36234, 45816, 57753,
+ 63104, 65535
+},
+{
+ 0, 8553, 23489, 36031, 46295, 53519, 56519, 59151,
+ 64185, 65535
+}
+};
+
+const SKP_int SKP_Silk_rate_levels_CDF_offset = 4;
+
+
+const SKP_int16 SKP_Silk_rate_levels_BITS_Q6[ 2 ][ 9 ] =
+{
+{
+ 322, 167, 199, 164, 239, 178, 157, 231,
+ 304
+},
+{
+ 188, 137, 153, 171, 204, 285, 297, 237,
+ 358
+}
+};
+
+const SKP_uint16 SKP_Silk_shell_code_table0[ 33 ] = {
+ 0, 32748, 65535, 0, 9505, 56230, 65535, 0,
+ 4093, 32204, 61720, 65535, 0, 2285, 16207, 48750,
+ 63424, 65535, 0, 1709, 9446, 32026, 55752, 63876,
+ 65535, 0, 1623, 6986, 21845, 45381, 59147, 64186,
+ 65535
+};
+
+const SKP_uint16 SKP_Silk_shell_code_table1[ 52 ] = {
+ 0, 32691, 65535, 0, 12782, 52752, 65535, 0,
+ 4847, 32665, 60899, 65535, 0, 2500, 17305, 47989,
+ 63369, 65535, 0, 1843, 10329, 32419, 55433, 64277,
+ 65535, 0, 1485, 7062, 21465, 43414, 59079, 64623,
+ 65535, 0, 0, 4841, 14797, 31799, 49667, 61309,
+ 65535, 65535, 0, 0, 0, 8032, 21695, 41078,
+ 56317, 65535, 65535, 65535
+};
+
+const SKP_uint16 SKP_Silk_shell_code_table2[ 102 ] = {
+ 0, 32615, 65535, 0, 14447, 50912, 65535, 0,
+ 6301, 32587, 59361, 65535, 0, 3038, 18640, 46809,
+ 62852, 65535, 0, 1746, 10524, 32509, 55273, 64278,
+ 65535, 0, 1234, 6360, 21259, 43712, 59651, 64805,
+ 65535, 0, 1020, 4461, 14030, 32286, 51249, 61904,
+ 65100, 65535, 0, 851, 3435, 10006, 23241, 40797,
+ 55444, 63009, 65252, 65535, 0, 0, 2075, 7137,
+ 17119, 31499, 46982, 58723, 63976, 65535, 65535, 0,
+ 0, 0, 3820, 11572, 23038, 37789, 51969, 61243,
+ 65535, 65535, 65535, 0, 0, 0, 0, 6882,
+ 16828, 30444, 44844, 57365, 65535, 65535, 65535, 65535,
+ 0, 0, 0, 0, 0, 10093, 22963, 38779,
+ 54426, 65535, 65535, 65535, 65535, 65535
+};
+
+const SKP_uint16 SKP_Silk_shell_code_table3[ 207 ] = {
+ 0, 32324, 65535, 0, 15328, 49505, 65535, 0,
+ 7474, 32344, 57955, 65535, 0, 3944, 19450, 45364,
+ 61873, 65535, 0, 2338, 11698, 32435, 53915, 63734,
+ 65535, 0, 1506, 7074, 21778, 42972, 58861, 64590,
+ 65535, 0, 1027, 4490, 14383, 32264, 50980, 61712,
+ 65043, 65535, 0, 760, 3022, 9696, 23264, 41465,
+ 56181, 63253, 65251, 65535, 0, 579, 2256, 6873,
+ 16661, 31951, 48250, 59403, 64198, 65360, 65535, 0,
+ 464, 1783, 5181, 12269, 24247, 39877, 53490, 61502,
+ 64591, 65410, 65535, 0, 366, 1332, 3880, 9273,
+ 18585, 32014, 45928, 56659, 62616, 64899, 65483, 65535,
+ 0, 286, 1065, 3089, 6969, 14148, 24859, 38274,
+ 50715, 59078, 63448, 65091, 65481, 65535, 0, 0,
+ 482, 2010, 5302, 10408, 18988, 30698, 43634, 54233,
+ 60828, 64119, 65288, 65535, 65535, 0, 0, 0,
+ 1006, 3531, 7857, 14832, 24543, 36272, 47547, 56883,
+ 62327, 64746, 65535, 65535, 65535, 0, 0, 0,
+ 0, 1863, 4950, 10730, 19284, 29397, 41382, 52335,
+ 59755, 63834, 65535, 65535, 65535, 65535, 0, 0,
+ 0, 0, 0, 2513, 7290, 14487, 24275, 35312,
+ 46240, 55841, 62007, 65535, 65535, 65535, 65535, 65535,
+ 0, 0, 0, 0, 0, 0, 3606, 9573,
+ 18764, 28667, 40220, 51290, 59924, 65535, 65535, 65535,
+ 65535, 65535, 65535, 0, 0, 0, 0, 0,
+ 0, 0, 4879, 13091, 23376, 36061, 49395, 59315,
+ 65535, 65535, 65535, 65535, 65535, 65535, 65535
+};
+
+const SKP_uint16 SKP_Silk_shell_code_table_offsets[ 19 ] = {
+ 0, 0, 3, 7, 12, 18, 25, 33,
+ 42, 52, 63, 75, 88, 102, 117, 133,
+ 150, 168, 187
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_sign.c b/pkg/silk/csilk/SKP_Silk_tables_sign.c
new file mode 100644
index 0000000..96fc34d
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_sign.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_sign_CDF[ 36 ] =
+{
+ 37840, 36944, 36251, 35304,
+ 34715, 35503, 34529, 34296,
+ 34016, 47659, 44945, 42503,
+ 40235, 38569, 40254, 37851,
+ 37243, 36595, 43410, 44121,
+ 43127, 40978, 38845, 40433,
+ 38252, 37795, 36637, 59159,
+ 55630, 51806, 48073, 45036,
+ 48416, 43857, 42678, 41146,
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_tables_type_offset.c b/pkg/silk/csilk/SKP_Silk_tables_type_offset.c
new file mode 100644
index 0000000..7effe38
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tables_type_offset.c
@@ -0,0 +1,52 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_tables.h"
+
+const SKP_uint16 SKP_Silk_type_offset_CDF[ 5 ] = {
+ 0, 37522, 41030, 44212, 65535
+};
+
+const SKP_int SKP_Silk_type_offset_CDF_offset = 2;
+
+
+const SKP_uint16 SKP_Silk_type_offset_joint_CDF[ 4 ][ 5 ] =
+{
+{
+ 0, 57686, 61230, 62358, 65535
+},
+{
+ 0, 18346, 40067, 43659, 65535
+},
+{
+ 0, 22694, 24279, 35507, 65535
+},
+{
+ 0, 6067, 7215, 13010, 65535
+}
+};
+
diff --git a/pkg/silk/csilk/SKP_Silk_tuning_parameters.h b/pkg/silk/csilk/SKP_Silk_tuning_parameters.h
new file mode 100644
index 0000000..09b96ed
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_tuning_parameters.h
@@ -0,0 +1,183 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 SKP_SILK_TUNING_PARAMETERS_H
+#define SKP_SILK_TUNING_PARAMETERS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************/
+/* Pitch estimator */
+/*******************/
+
+/* Level of noise floor for whitening filter LPC analysis in pitch analysis */
+#define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f
+
+/* Bandwidth expansion for whitening filter in pitch analysis */
+#define FIND_PITCH_BANDWITH_EXPANSION 0.99f
+
+/* Threshold used by pitch estimator for early escape */
+#define FIND_PITCH_CORRELATION_THRESHOLD_HC_MODE 0.7f
+#define FIND_PITCH_CORRELATION_THRESHOLD_MC_MODE 0.75f
+#define FIND_PITCH_CORRELATION_THRESHOLD_LC_MODE 0.8f
+
+/*********************/
+/* Linear prediction */
+/*********************/
+
+/* LPC analysis defines: regularization and bandwidth expansion */
+#define FIND_LPC_COND_FAC 2.5e-5f
+#define FIND_LPC_CHIRP 0.99995f
+
+/* LTP analysis defines */
+#define FIND_LTP_COND_FAC 1e-5f
+#define LTP_DAMPING 0.01f
+#define LTP_SMOOTHING 0.1f
+
+/* LTP quantization settings */
+#define MU_LTP_QUANT_NB 0.03f
+#define MU_LTP_QUANT_MB 0.025f
+#define MU_LTP_QUANT_WB 0.02f
+#define MU_LTP_QUANT_SWB 0.016f
+
+/***********************/
+/* High pass filtering */
+/***********************/
+
+/* Smoothing parameters for low end of pitch frequency range estimation */
+#define VARIABLE_HP_SMTH_COEF1 0.1f
+#define VARIABLE_HP_SMTH_COEF2 0.015f
+
+/* Min and max values for low end of pitch frequency range estimation */
+#define VARIABLE_HP_MIN_FREQ 80.0f
+#define VARIABLE_HP_MAX_FREQ 150.0f
+
+/* Max absolute difference between log2 of pitch frequency and smoother state, to enter the smoother */
+#define VARIABLE_HP_MAX_DELTA_FREQ 0.4f
+
+/***********/
+/* Various */
+/***********/
+
+/* Required speech activity for counting frame as active */
+#define WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES 0.7f
+
+#define SPEECH_ACTIVITY_DTX_THRES 0.1f
+
+/* Speech Activity LBRR enable threshold (needs tuning) */
+#define LBRR_SPEECH_ACTIVITY_THRES 0.5f
+
+/*************************/
+/* Perceptual parameters */
+/*************************/
+
+/* reduction in coding SNR during low speech activity */
+#define BG_SNR_DECR_dB 4.0f
+
+/* factor for reducing quantization noise during voiced speech */
+#define HARM_SNR_INCR_dB 2.0f
+
+/* factor for reducing quantization noise for unvoiced sparse signals */
+#define SPARSE_SNR_INCR_dB 2.0f
+
+/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */
+#define SPARSENESS_THRESHOLD_QNT_OFFSET 0.75f
+
+/* warping control */
+#define WARPING_MULTIPLIER 0.015f
+
+/* fraction added to first autocorrelation value */
+#define SHAPE_WHITE_NOISE_FRACTION 1e-5f
+
+/* noise shaping filter chirp factor */
+#define BANDWIDTH_EXPANSION 0.95f
+
+/* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */
+#define LOW_RATE_BANDWIDTH_EXPANSION_DELTA 0.01f
+
+/* gain reduction for fricatives */
+#define DE_ESSER_COEF_SWB_dB 2.0f
+#define DE_ESSER_COEF_WB_dB 1.0f
+
+/* extra harmonic boosting (signal shaping) at low bitrates */
+#define LOW_RATE_HARMONIC_BOOST 0.1f
+
+/* extra harmonic boosting (signal shaping) for noisy input signals */
+#define LOW_INPUT_QUALITY_HARMONIC_BOOST 0.1f
+
+/* harmonic noise shaping */
+#define HARMONIC_SHAPING 0.3f
+
+/* extra harmonic noise shaping for high bitrates or noisy input */
+#define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f
+
+/* parameter for shaping noise towards higher frequencies */
+#define HP_NOISE_COEF 0.3f
+
+/* parameter for shaping noise even more towards higher frequencies during voiced speech */
+#define HARM_HP_NOISE_COEF 0.35f
+
+/* parameter for applying a high-pass tilt to the input signal */
+#define INPUT_TILT 0.05f
+
+/* parameter for extra high-pass tilt to the input signal at high rates */
+#define HIGH_RATE_INPUT_TILT 0.1f
+
+/* parameter for reducing noise at the very low frequencies */
+#define LOW_FREQ_SHAPING 3.0f
+
+/* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */
+#define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f
+
+/* noise floor to put a lower limit on the quantization step size */
+#define NOISE_FLOOR_dB 4.0f
+
+/* noise floor relative to active speech gain level */
+#define RELATIVE_MIN_GAIN_dB -50.0f
+
+/* subframe smoothing coefficient for determining active speech gain level (lower -> more smoothing) */
+#define GAIN_SMOOTHING_COEF 1e-3f
+
+/* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */
+#define SUBFR_SMTH_COEF 0.4f
+
+/* parameters defining the R/D tradeoff in the residual quantizer */
+#define LAMBDA_OFFSET 1.2f
+#define LAMBDA_SPEECH_ACT -0.3f
+#define LAMBDA_DELAYED_DECISIONS -0.05f
+#define LAMBDA_INPUT_QUALITY -0.2f
+#define LAMBDA_CODING_QUALITY -0.1f
+#define LAMBDA_QUANT_OFFSET 1.5f
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SKP_SILK_TUNING_PARAMETERS_H
diff --git a/pkg/silk/csilk/SKP_Silk_typedef.h b/pkg/silk/csilk/SKP_Silk_typedef.h
new file mode 100644
index 0000000..5e1d2e7
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_typedef.h
@@ -0,0 +1,107 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 _SKP_SILK_API_TYPDEF_H_
+#define _SKP_SILK_API_TYPDEF_H_
+
+#ifndef SKP_USE_DOUBLE_PRECISION_FLOATS
+#define SKP_USE_DOUBLE_PRECISION_FLOATS 0
+#endif
+
+#include
+#if defined( __GNUC__ )
+#include
+#endif
+
+#define SKP_int int /* used for counters etc; at least 16 bits */
+#ifdef __GNUC__
+# define SKP_int64 int64_t
+#else
+# define SKP_int64 long long
+#endif
+#define SKP_int32 int
+#define SKP_int16 short
+#define SKP_int8 signed char
+
+#define SKP_uint unsigned int /* used for counters etc; at least 16 bits */
+#ifdef __GNUC__
+# define SKP_uint64 uint64_t
+#else
+# define SKP_uint64 unsigned long long
+#endif
+#define SKP_uint32 unsigned int
+#define SKP_uint16 unsigned short
+#define SKP_uint8 unsigned char
+
+#define SKP_int_ptr_size intptr_t
+
+#if SKP_USE_DOUBLE_PRECISION_FLOATS
+# define SKP_float double
+# define SKP_float_MAX DBL_MAX
+#else
+# define SKP_float float
+# define SKP_float_MAX FLT_MAX
+#endif
+
+#define SKP_INLINE static __inline
+
+#ifdef _WIN32
+# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)
+#else
+# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)
+#endif
+
+#define SKP_int64_MAX ((SKP_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */
+#define SKP_int64_MIN ((SKP_int64)0x8000000000000000LL) /* -2^63 */
+#define SKP_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647*/
+#define SKP_int32_MIN ((SKP_int32)0x80000000) /* -2^31 = -2147483648*/
+#define SKP_int16_MAX 0x7FFF /* 2^15 - 1 = 32767*/
+#define SKP_int16_MIN ((SKP_int16)0x8000) /* -2^15 = -32768*/
+#define SKP_int8_MAX 0x7F /* 2^7 - 1 = 127*/
+#define SKP_int8_MIN ((SKP_int8)0x80) /* -2^7 = -128*/
+
+#define SKP_uint32_MAX 0xFFFFFFFF /* 2^32 - 1 = 4294967295 */
+#define SKP_uint32_MIN 0x00000000
+#define SKP_uint16_MAX 0xFFFF /* 2^16 - 1 = 65535 */
+#define SKP_uint16_MIN 0x0000
+#define SKP_uint8_MAX 0xFF /* 2^8 - 1 = 255 */
+#define SKP_uint8_MIN 0x00
+
+#define SKP_TRUE 1
+#define SKP_FALSE 0
+
+/* assertions */
+#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS))
+# ifndef SKP_assert
+# include /* ASSERTE() */
+# define SKP_assert(COND) _ASSERTE(COND)
+# endif
+#else
+# define SKP_assert(COND)
+#endif
+
+#endif
diff --git a/pkg/silk/csilk/SKP_Silk_warped_autocorrelation_FIX.c b/pkg/silk/csilk/SKP_Silk_warped_autocorrelation_FIX.c
new file mode 100644
index 0000000..6adb627
--- /dev/null
+++ b/pkg/silk/csilk/SKP_Silk_warped_autocorrelation_FIX.c
@@ -0,0 +1,88 @@
+/***********************************************************************
+Copyright (c) 2006-2012, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, (subject to the limitations in the disclaimer below)
+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.
+- Neither the name of Skype Limited, nor the names of specific
+contributors, may be used to endorse or promote products derived from
+this software without specific prior written permission.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
+BY THIS LICENSE. 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 "SKP_Silk_main_FIX.h"
+
+#define QC 10
+#define QS 14
+
+
+#if EMBEDDED_ARM<6
+/* Autocorrelations for a warped frequency axis */
+void SKP_Silk_warped_autocorrelation_FIX(
+ SKP_int32 *corr, /* O Result [order + 1] */
+ SKP_int *scale, /* O Scaling of the correlation vector */
+ const SKP_int16 *input, /* I Input data to correlate */
+ const SKP_int16 warping_Q16, /* I Warping coefficient */
+ const SKP_int length, /* I Length of input */
+ const SKP_int order /* I Correlation order (even) */
+)
+{
+ SKP_int n, i, lsh;
+ SKP_int32 tmp1_QS, tmp2_QS;
+ SKP_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
+ SKP_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
+
+ /* Order must be even */
+ SKP_assert( ( order & 1 ) == 0 );
+ SKP_assert( 2 * QS - QC >= 0 );
+
+ /* Loop over samples */
+ for( n = 0; n < length; n++ ) {
+ tmp1_QS = SKP_LSHIFT32( ( SKP_int32 )input[ n ], QS );
+ /* Loop over allpass sections */
+ for( i = 0; i < order; i += 2 ) {
+ /* Output of allpass section */
+ tmp2_QS = SKP_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
+ state_QS[ i ] = tmp1_QS;
+ corr_QC[ i ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
+ /* Output of allpass section */
+ tmp1_QS = SKP_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
+ state_QS[ i + 1 ] = tmp2_QS;
+ corr_QC[ i + 1 ] += SKP_RSHIFT64( SKP_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC );
+ }
+ state_QS[ order ] = tmp1_QS;
+ corr_QC[ order ] += SKP_RSHIFT64( SKP_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
+ }
+
+ lsh = SKP_Silk_CLZ64( corr_QC[ 0 ] ) - 35;
+ lsh = SKP_LIMIT( lsh, -12 - QC, 30 - QC );
+ *scale = -( QC + lsh );
+ SKP_assert( *scale >= -30 && *scale <= 12 );
+ if( lsh >= 0 ) {
+ for( i = 0; i < order + 1; i++ ) {
+ corr[ i ] = ( SKP_int32 )SKP_CHECK_FIT32( SKP_LSHIFT64( corr_QC[ i ], lsh ) );
+ }
+ } else {
+ for( i = 0; i < order + 1; i++ ) {
+ corr[ i ] = ( SKP_int32 )SKP_CHECK_FIT32( SKP_RSHIFT64( corr_QC[ i ], -lsh ) );
+ }
+ }
+ SKP_assert( corr_QC[ 0 ] >= 0 ); // If breaking, decrease QC
+}
+#endif
+
diff --git a/pkg/silk/csilk/skp_silk_sdk.h b/pkg/silk/csilk/skp_silk_sdk.h
new file mode 100644
index 0000000..811ed71
--- /dev/null
+++ b/pkg/silk/csilk/skp_silk_sdk.h
@@ -0,0 +1,11 @@
+#ifndef __SKP_SILK_SDK_H
+#define __SKP_SILK_SDK_H
+
+struct silk_handle;
+
+struct silk_handle *silk_decoder_init(void);
+void silk_decoder_deinit(struct silk_handle *h);
+int silk_decoder_process(struct silk_handle *h, unsigned char *frame, int frame_size, unsigned char *output_payload, int output_len);
+int silk_decoder_set_sample_rate(struct silk_handle *h, int rate);
+
+#endif /* __SKP_SILK_SDK_H */
diff --git a/pkg/silk/silk.go b/pkg/silk/silk.go
new file mode 100644
index 0000000..9c34607
--- /dev/null
+++ b/pkg/silk/silk.go
@@ -0,0 +1,122 @@
+package silk
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "unsafe"
+)
+
+/*
+#cgo CFLAGS: -I./csilk/
+#include
+#include "skp_silk_sdk.h"
+*/
+import "C"
+
+const (
+ MAX_BYTES_PER_FRAME = 1024
+ MAX_INPUT_FRAMES = 5
+ MAX_FRAME_LENGTH = 480
+ FRAME_LENGTH_MS = 20
+ MAX_API_FS_KHZ = 48
+)
+
+type Handle *C.struct_silk_handle
+
+type Decoder struct {
+ handle Handle
+ remainder []byte
+ closed bool
+ foundHead bool
+}
+
+func SilkInit() *Decoder {
+ h := C.silk_decoder_init()
+ decoder := &Decoder{h, make([]byte, 0), false, false}
+
+ return decoder
+}
+
+func (d *Decoder) SetSampleRate(rate int) {
+ C.silk_decoder_set_sample_rate(d.handle, C.int(rate))
+}
+
+func (d *Decoder) Decode(buf []byte) []byte {
+ d.remainder = append(d.remainder, buf...)
+
+ if len(buf) == 0 || d.closed {
+ return make([]byte, 0)
+ }
+
+ if !d.foundHead {
+ var head []byte
+ if d.remainder[0] == 0x02 {
+ head = d.remainder[1:10]
+ d.remainder = d.remainder[10:]
+ } else {
+ head = d.remainder[0:9]
+ d.remainder = d.remainder[9:]
+ }
+
+ if string(head) == "#!SILK_V3" {
+ d.foundHead = true
+ } else {
+ fmt.Println("not found head")
+ return make([]byte, 0)
+ }
+ }
+
+ // fmt.Println("remainder:", d.remainder[0:10])
+ out := make([]byte, 0)
+ for {
+ if len(d.remainder) < 2 {
+ break
+ }
+ buffer := bytes.NewBuffer(d.remainder[0:2])
+ // fmt.Println("remainder:", d.remainder[0:2])
+
+ var nlen int16
+ if err := binary.Read(buffer, binary.LittleEndian, &nlen); err != nil {
+ fmt.Println("Error reading int16:", err)
+ d.remainder = d.remainder[2:]
+ return make([]byte, 0)
+ }
+
+ if nlen <= 0 {
+ fmt.Println("d.remainder:", d.remainder)
+ d.remainder = d.remainder[2:]
+ continue
+ }
+ // fmt.Println("nlen:", nlen)
+
+ if len(d.remainder) < (int(nlen) + 2) {
+ break
+ }
+
+ frame := d.remainder[2 : 2+nlen]
+ // fmt.Println("frame:", frame)
+ payload_len := ((FRAME_LENGTH_MS * MAX_API_FS_KHZ) << 1) * MAX_INPUT_FRAMES
+ payload := make([]byte, payload_len)
+ cframe := (*C.uchar)(unsafe.Pointer(&frame[0]))
+ cpayload := (*C.uchar)(unsafe.Pointer(&payload[0]))
+ outlen := C.int(C.silk_decoder_process(d.handle, cframe, C.int(nlen), cpayload, C.int(payload_len)))
+ append_payload := payload[0:outlen]
+ out = append(out, append_payload...)
+ d.remainder = d.remainder[2+nlen:]
+ }
+
+ return out
+}
+
+func (d *Decoder) Close() {
+ if !d.closed {
+ d.closed = true
+ C.silk_decoder_deinit(d.handle)
+ }
+}
+
+func (d *Decoder) Flush() []byte {
+ var tmp []byte
+ return d.Decode(tmp)
+}
diff --git a/pkg/silk/writer.go b/pkg/silk/writer.go
new file mode 100644
index 0000000..fdbf1bc
--- /dev/null
+++ b/pkg/silk/writer.go
@@ -0,0 +1,41 @@
+package silk
+
+import (
+ "io"
+)
+
+type SilkWriter struct {
+ output io.Writer
+ Decoder *Decoder
+ DecodedChunkSize int
+}
+
+func NewWriter(out io.Writer) *SilkWriter {
+ writer := &SilkWriter{out, SilkInit(), 0}
+ return writer
+}
+
+func (sw *SilkWriter) Write(p []byte) (int, error) {
+ // fmt.Println("silk Write len:", len(p))
+ out := sw.Decoder.Decode(p)
+ sw.DecodedChunkSize = len(out)
+
+ if sw.DecodedChunkSize > 0 {
+ _, err := sw.output.Write(out)
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ return len(p), nil
+}
+
+func (sw *SilkWriter) Close() error {
+ out := sw.Decoder.Flush()
+ if len(out) == 0 {
+ return nil
+ }
+ sw.Decoder.Close()
+ _, err := sw.output.Write(out)
+ return err
+}
diff --git a/pkg/silk/z_link_silk_c.c b/pkg/silk/z_link_silk_c.c
new file mode 100644
index 0000000..7d90e89
--- /dev/null
+++ b/pkg/silk/z_link_silk_c.c
@@ -0,0 +1,111 @@
+#include "./csilk/SKP_Silk_NLSF_MSVQ_decode.c"
+#include "./csilk/SKP_Silk_scale_copy_vector16.c"
+#include "./csilk/SKP_Silk_NLSF2A.c"
+#include "./csilk/SKP_Silk_LTP_scale_ctrl_FIX.c"
+#include "./csilk/SKP_Silk_NLSF_VQ_weights_laroia.c"
+#include "./csilk/SKP_Silk_encode_parameters.c"
+#include "./csilk/SKP_Silk_tables_NLSF_CB0_10.c"
+#include "./csilk/SKP_Silk_autocorr.c"
+#include "./csilk/SKP_Silk_decode_parameters.c"
+#include "./csilk/SKP_Silk_k2a_Q16.c"
+#include "./csilk/SKP_Silk_NLSF_stabilize.c"
+#include "./csilk/SKP_Silk_decode_pitch.c"
+#include "./csilk/SKP_Silk_tables_NLSF_CB1_16.c"
+#include "./csilk/SKP_Silk_HP_variable_cutoff_FIX.c"
+#include "./csilk/SKP_Silk_apply_sine_window.c"
+#include "./csilk/SKP_Silk_decode_core.c"
+#include "./csilk/SKP_Silk_resampler_down2_3.c"
+#include "./csilk/SKP_Silk_log2lin.c"
+#include "./csilk/SKP_Silk_NLSF_VQ_rate_distortion_FIX.c"
+#include "./csilk/SKP_Silk_PLC.c"
+#include "./csilk/SKP_Silk_VQ_nearest_neighbor_FIX.c"
+#include "./csilk/SKP_Silk_quant_LTP_gains_FIX.c"
+#include "./csilk/SKP_Silk_array_maxabs.c"
+#include "./csilk/SKP_Silk_resampler_private_down_FIR.c"
+#include "./csilk/SKP_Silk_tables_other.c"
+#include "./csilk/Decoder_Api.c"
+#include "./csilk/SKP_Silk_NLSF2A_stable.c"
+#include "./csilk/SKP_Silk_find_pitch_lags_FIX.c"
+#include "./csilk/SKP_Silk_CNG.c"
+#include "./csilk/SKP_Silk_LPC_synthesis_order16.c"
+#include "./csilk/SKP_Silk_corrMatrix_FIX.c"
+#include "./csilk/SKP_Silk_init_encoder_FIX.c"
+#include "./csilk/SKP_Silk_sort.c"
+#include "./csilk/SKP_Silk_MA.c"
+#include "./csilk/SKP_Silk_process_gains_FIX.c"
+#include "./csilk/SKP_Silk_decode_pulses.c"
+#include "./csilk/SKP_Silk_find_LTP_FIX.c"
+#include "./csilk/SKP_Silk_resampler_private_AR2.c"
+#include "./csilk/SKP_Silk_shell_coder.c"
+#include "./csilk/SKP_Silk_LP_variable_cutoff.c"
+#include "./csilk/SKP_Silk_inner_prod_aligned.c"
+#include "./csilk/SKP_Silk_tables_pitch_lag.c"
+#include "./csilk/SKP_Silk_warped_autocorrelation_FIX.c"
+#include "./csilk/SKP_Silk_tables_LTP.c"
+#include "./csilk/SKP_Silk_process_NLSFs_FIX.c"
+#include "./csilk/SKP_Silk_ana_filt_bank_1.c"
+#include "./csilk/SKP_Silk_NSQ.c"
+#include "./csilk/SKP_Silk_biquad.c"
+#include "./csilk/SKP_Silk_biquad_alt.c"
+#include "./csilk/SKP_Silk_tables_NLSF_CB1_10.c"
+#include "./csilk/SKP_Silk_scale_vector.c"
+#include "./csilk/SKP_Silk_resampler.c"
+#include "./csilk/SKP_Silk_range_coder.c"
+#include "./csilk/SKP_Silk_decoder_set_fs.c"
+#include "./csilk/SKP_Silk_lin2log.c"
+#include "./csilk/SKP_Silk_tables_gain.c"
+#include "./csilk/SKP_Silk_k2a.c"
+#include "./csilk/SKP_Silk_sum_sqr_shift.c"
+#include "./csilk/SKP_Silk_resampler_private_ARMA4.c"
+#include "./csilk/SKP_Silk_resampler_private_copy.c"
+#include "./csilk/SKP_Silk_resampler_rom.c"
+#include "./csilk/SKP_Silk_noise_shape_analysis_FIX.c"
+#include "./csilk/SKP_Silk_solve_LS_FIX.c"
+#include "./csilk/SKP_Silk_div_oabi.c"
+#include "./csilk/SKP_Silk_bwexpander.c"
+#include "./csilk/SKP_Silk_find_pred_coefs_FIX.c"
+#include "./csilk/SKP_Silk_resampler_down2.c"
+#include "./csilk/SKP_Silk_enc_API.c"
+#include "./csilk/SKP_Silk_resampler_private_up2_HQ.c"
+#include "./csilk/SKP_Silk_resampler_private_up4.c"
+#include "./csilk/SKP_Silk_LBRR_reset.c"
+#include "./csilk/SKP_Silk_detect_SWB_input.c"
+#include "./csilk/SKP_Silk_control_audio_bandwidth.c"
+#include "./csilk/SKP_Silk_prefilter_FIX.c"
+#include "./csilk/SKP_Silk_find_LPC_FIX.c"
+#include "./csilk/SKP_Silk_resampler_up2.c"
+#include "./csilk/SKP_Silk_bwexpander_32.c"
+#include "./csilk/SKP_Silk_encode_pulses.c"
+#include "./csilk/SKP_Silk_NLSF_MSVQ_encode_FIX.c"
+#include "./csilk/SKP_Silk_tables_pulses_per_block.c"
+#include "./csilk/SKP_Silk_control_codec_FIX.c"
+#include "./csilk/SKP_Silk_VAD.c"
+#include "./csilk/SKP_Silk_NSQ_del_dec.c"
+#include "./csilk/SKP_Silk_code_signs.c"
+#include "./csilk/SKP_Silk_decode_frame.c"
+#include "./csilk/SKP_Silk_burg_modified.c"
+#include "./csilk/SKP_Silk_sigm_Q15.c"
+#include "./csilk/SKP_Silk_pitch_analysis_core.c"
+#include "./csilk/SKP_Silk_NLSF_VQ_sum_error_FIX.c"
+#include "./csilk/SKP_Silk_interpolate.c"
+#include "./csilk/SKP_Silk_LSF_cos_table.c"
+#include "./csilk/SKP_Silk_encode_frame_FIX.c"
+#include "./csilk/SKP_Silk_resampler_private_IIR_FIR.c"
+#include "./csilk/SKP_Silk_schur.c"
+#include "./csilk/SKP_Silk_LPC_synthesis_filter.c"
+#include "./csilk/SKP_Silk_pitch_est_tables.c"
+#include "./csilk/SKP_Silk_A2NLSF.c"
+#include "./csilk/SKP_Silk_residual_energy16_FIX.c"
+#include "./csilk/SKP_Silk_LPC_inv_pred_gain.c"
+#include "./csilk/SKP_Silk_resampler_down3.c"
+#include "./csilk/SKP_Silk_schur64.c"
+#include "./csilk/SKP_Silk_gain_quant.c"
+#include "./csilk/SKP_Silk_residual_energy_FIX.c"
+#include "./csilk/SKP_Silk_resampler_private_down4.c"
+#include "./csilk/SKP_Silk_create_init_destroy.c"
+#include "./csilk/SKP_Silk_regularize_correlations_FIX.c"
+#include "./csilk/SKP_Silk_LTP_analysis_filter_FIX.c"
+#include "./csilk/SKP_Silk_dec_API.c"
+#include "./csilk/SKP_Silk_tables_sign.c"
+#include "./csilk/SKP_Silk_tables_NLSF_CB0_16.c"
+#include "./csilk/SKP_Silk_tables_type_offset.c"
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
new file mode 100644
index 0000000..c7af718
--- /dev/null
+++ b/pkg/utils/utils.go
@@ -0,0 +1,77 @@
+package utils
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "strings"
+
+ "github.com/pkg/browser"
+ "golang.org/x/sys/windows/registry"
+)
+
+func getDefaultProgram(fileExtension string) (string, error) {
+ key, err := registry.OpenKey(registry.CLASSES_ROOT, fmt.Sprintf(`.%s`, fileExtension), registry.QUERY_VALUE)
+ if err != nil {
+ return "", err
+ }
+ defer key.Close()
+
+ // 读取默认程序关联值
+ defaultProgram, _, err := key.GetStringValue("")
+ if err != nil {
+ return "", err
+ }
+
+ return defaultProgram, nil
+}
+
+func hasDefaultProgram(fileExtension string) bool {
+ prog, err := getDefaultProgram(fileExtension)
+ if err != nil {
+ log.Println("getDefaultProgram Error:", err)
+ return false
+ }
+
+ if prog == "" {
+ return false
+ }
+
+ return true
+}
+
+func OpenFileOrExplorer(filePath string, explorer bool) error {
+ if _, err := os.Stat(filePath); err != nil {
+ log.Printf("%s %v\n", filePath, err)
+ return err
+ }
+
+ canOpen := false
+ fileExtension := ""
+ index := strings.LastIndex(filePath, ".")
+ if index > 0 {
+ fileExtension = filePath[index+1:]
+ canOpen = hasDefaultProgram(fileExtension)
+ }
+
+ if canOpen && !explorer {
+ return browser.OpenFile(filePath)
+ }
+
+ commandArgs := []string{"/select,", filePath}
+ fmt.Println("cmd:", "explorer", commandArgs)
+
+ // 创建一个Cmd结构体表示要执行的命令
+ cmd := exec.Command("explorer", commandArgs...)
+
+ // 执行命令并等待它完成
+ err := cmd.Run()
+ if err != nil {
+ log.Printf("Error executing command: %s\n", err)
+ // return err
+ }
+
+ fmt.Println("Command executed successfully")
+ return nil
+}
diff --git a/pkg/wechat/msg.pb.go b/pkg/wechat/msg.pb.go
new file mode 100644
index 0000000..ab16df5
--- /dev/null
+++ b/pkg/wechat/msg.pb.go
@@ -0,0 +1,301 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.33.0
+// protoc v3.6.1
+// source: msg.proto
+
+package wechat
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type SubMessage1 struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Field1 int32 `protobuf:"varint,1,opt,name=field1,proto3" json:"field1,omitempty"`
+ Field2 int32 `protobuf:"varint,2,opt,name=field2,proto3" json:"field2,omitempty"`
+}
+
+func (x *SubMessage1) Reset() {
+ *x = SubMessage1{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_msg_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SubMessage1) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SubMessage1) ProtoMessage() {}
+
+func (x *SubMessage1) ProtoReflect() protoreflect.Message {
+ mi := &file_msg_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SubMessage1.ProtoReflect.Descriptor instead.
+func (*SubMessage1) Descriptor() ([]byte, []int) {
+ return file_msg_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *SubMessage1) GetField1() int32 {
+ if x != nil {
+ return x.Field1
+ }
+ return 0
+}
+
+func (x *SubMessage1) GetField2() int32 {
+ if x != nil {
+ return x.Field2
+ }
+ return 0
+}
+
+type SubMessage2 struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Field1 int32 `protobuf:"varint,1,opt,name=field1,proto3" json:"field1,omitempty"`
+ Field2 string `protobuf:"bytes,2,opt,name=field2,proto3" json:"field2,omitempty"`
+}
+
+func (x *SubMessage2) Reset() {
+ *x = SubMessage2{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_msg_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SubMessage2) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SubMessage2) ProtoMessage() {}
+
+func (x *SubMessage2) ProtoReflect() protoreflect.Message {
+ mi := &file_msg_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SubMessage2.ProtoReflect.Descriptor instead.
+func (*SubMessage2) Descriptor() ([]byte, []int) {
+ return file_msg_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SubMessage2) GetField1() int32 {
+ if x != nil {
+ return x.Field1
+ }
+ return 0
+}
+
+func (x *SubMessage2) GetField2() string {
+ if x != nil {
+ return x.Field2
+ }
+ return ""
+}
+
+type MessageBytesExtra struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Message1 *SubMessage1 `protobuf:"bytes,1,opt,name=message1,proto3" json:"message1,omitempty"`
+ Message2 []*SubMessage2 `protobuf:"bytes,3,rep,name=message2,proto3" json:"message2,omitempty"`
+}
+
+func (x *MessageBytesExtra) Reset() {
+ *x = MessageBytesExtra{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_msg_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MessageBytesExtra) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MessageBytesExtra) ProtoMessage() {}
+
+func (x *MessageBytesExtra) ProtoReflect() protoreflect.Message {
+ mi := &file_msg_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MessageBytesExtra.ProtoReflect.Descriptor instead.
+func (*MessageBytesExtra) Descriptor() ([]byte, []int) {
+ return file_msg_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *MessageBytesExtra) GetMessage1() *SubMessage1 {
+ if x != nil {
+ return x.Message1
+ }
+ return nil
+}
+
+func (x *MessageBytesExtra) GetMessage2() []*SubMessage2 {
+ if x != nil {
+ return x.Message2
+ }
+ return nil
+}
+
+var File_msg_proto protoreflect.FileDescriptor
+
+var file_msg_proto_rawDesc = []byte{
+ 0x0a, 0x09, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x61, 0x70, 0x70,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x3d, 0x0a, 0x0b, 0x53, 0x75, 0x62,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x31, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c,
+ 0x64, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31,
+ 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x22, 0x3d, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x4d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64,
+ 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x12,
+ 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x22, 0x81, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x45, 0x78, 0x74, 0x72, 0x61, 0x12, 0x35, 0x0a,
+ 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x19, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
+ 0x75, 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x31, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73,
+ 0x61, 0x67, 0x65, 0x31, 0x12, 0x35, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32,
+ 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x75, 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x32, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x42, 0x09, 0x5a, 0x07, 0x2e,
+ 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_msg_proto_rawDescOnce sync.Once
+ file_msg_proto_rawDescData = file_msg_proto_rawDesc
+)
+
+func file_msg_proto_rawDescGZIP() []byte {
+ file_msg_proto_rawDescOnce.Do(func() {
+ file_msg_proto_rawDescData = protoimpl.X.CompressGZIP(file_msg_proto_rawDescData)
+ })
+ return file_msg_proto_rawDescData
+}
+
+var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_msg_proto_goTypes = []interface{}{
+ (*SubMessage1)(nil), // 0: app.protobuf.SubMessage1
+ (*SubMessage2)(nil), // 1: app.protobuf.SubMessage2
+ (*MessageBytesExtra)(nil), // 2: app.protobuf.MessageBytesExtra
+}
+var file_msg_proto_depIdxs = []int32{
+ 0, // 0: app.protobuf.MessageBytesExtra.message1:type_name -> app.protobuf.SubMessage1
+ 1, // 1: app.protobuf.MessageBytesExtra.message2:type_name -> app.protobuf.SubMessage2
+ 2, // [2:2] is the sub-list for method output_type
+ 2, // [2:2] is the sub-list for method input_type
+ 2, // [2:2] is the sub-list for extension type_name
+ 2, // [2:2] is the sub-list for extension extendee
+ 0, // [0:2] is the sub-list for field type_name
+}
+
+func init() { file_msg_proto_init() }
+func file_msg_proto_init() {
+ if File_msg_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_msg_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SubMessage1); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_msg_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SubMessage2); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_msg_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MessageBytesExtra); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_msg_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 3,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_msg_proto_goTypes,
+ DependencyIndexes: file_msg_proto_depIdxs,
+ MessageInfos: file_msg_proto_msgTypes,
+ }.Build()
+ File_msg_proto = out.File
+ file_msg_proto_rawDesc = nil
+ file_msg_proto_goTypes = nil
+ file_msg_proto_depIdxs = nil
+}
diff --git a/pkg/wechat/wechat.go b/pkg/wechat/wechat.go
new file mode 100644
index 0000000..2815392
--- /dev/null
+++ b/pkg/wechat/wechat.go
@@ -0,0 +1,653 @@
+package wechat
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/hmac"
+ "crypto/sha1"
+ "database/sql"
+ "encoding/binary"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+ "unsafe"
+ "wechatDataBackup/pkg/lame"
+ "wechatDataBackup/pkg/silk"
+
+ _ "github.com/mattn/go-sqlite3"
+ "github.com/shirou/gopsutil/v3/process"
+ "golang.org/x/sys/windows"
+)
+
+type WeChatInfo struct {
+ ProcessID uint32
+ FilePath string
+ AcountName string
+ Version string
+ Is64Bits bool
+ DllBaseAddr uintptr
+ DllBaseSize uint32
+ DBKey string
+}
+
+type wechatMediaMSG struct {
+ Key string
+ MsgSvrID int
+ Buf []byte
+}
+
+func GetWeChatAllInfo() (WeChatInfo, error) {
+ info, err := GetWeChatInfo()
+ if err != nil {
+ log.Println("GetWeChatInfo:", err)
+ return info, err
+ }
+
+ info.DBKey = GetWeChatKey(&info)
+
+ return info, nil
+}
+
+func ExportWeChatAllData(info WeChatInfo, expPath string, progress chan<- string) {
+ defer close(progress)
+ fileInfo, err := os.Stat(info.FilePath)
+ if err != nil || !fileInfo.IsDir() {
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%s error\"}", info.FilePath)
+ return
+ }
+ if !exportWeChatDateBase(info, expPath, progress) {
+ return
+ }
+
+ exportWeChatBat(info, expPath, progress)
+ exportWeChatVideoAndFile(info, expPath, progress)
+ exportWeChatVoice(info, expPath, progress)
+}
+
+func exportWeChatVoice(info WeChatInfo, expPath string, progress chan<- string) {
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat voice start\", \"progress\": 61}"
+
+ voicePath := fmt.Sprintf("%s\\FileStorage\\Voice", expPath)
+ if _, err := os.Stat(voicePath); err != nil {
+ if err := os.MkdirAll(voicePath, 0644); err != nil {
+ log.Printf("MkdirAll %s failed: %v\n", voicePath, err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%v error\"}", err)
+ return
+ }
+ }
+
+ var wg sync.WaitGroup
+ index := -1
+ MSGChan := make(chan wechatMediaMSG, 100)
+ go func() {
+ for {
+ index += 1
+ mediaMSGDB := fmt.Sprintf("%s\\Msg\\Multi\\MediaMSG%d.db", expPath, index)
+ _, err := os.Stat(mediaMSGDB)
+ if err != nil {
+ break
+ }
+
+ db, err := sql.Open("sqlite3", mediaMSGDB)
+ if err != nil {
+ log.Printf("open %s failed: %v\n", mediaMSGDB, err)
+ continue
+ }
+ defer db.Close()
+
+ rows, err := db.Query("select Key, Reserved0, Buf from Media;")
+ if err != nil {
+ log.Printf("Query failed: %v\n", err)
+ continue
+ }
+
+ msg := wechatMediaMSG{}
+ for rows.Next() {
+ err := rows.Scan(&msg.Key, &msg.MsgSvrID, &msg.Buf)
+ if err != nil {
+ log.Println("Scan failed: ", err)
+ break
+ }
+
+ MSGChan <- msg
+ }
+ }
+ close(MSGChan)
+ }()
+
+ for i := 0; i < 20; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for msg := range MSGChan {
+ mp3Path := fmt.Sprintf("%s\\%d.mp3", voicePath, msg.MsgSvrID)
+ _, err := os.Stat(mp3Path)
+ if err == nil {
+ continue
+ }
+
+ err = silkToMp3(msg.Buf[:], mp3Path)
+ if err != nil {
+ log.Printf("silkToMp3 %s failed: %v\n", mp3Path, err)
+ }
+ }
+ }()
+ }
+ wg.Wait()
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat voice end\", \"progress\": 100}"
+}
+
+func exportWeChatVideoAndFile(info WeChatInfo, expPath string, progress chan<- string) {
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat Video and File start\", , \"progress\": 41}"
+ videoRootPath := info.FilePath + "\\FileStorage\\Video"
+ fileRootPath := info.FilePath + "\\FileStorage\\File"
+ cacheRootPath := info.FilePath + "\\FileStorage\\Cache"
+ rootPaths := []string{videoRootPath, fileRootPath, cacheRootPath}
+ var wg sync.WaitGroup
+ taskChan := make(chan [2]string, 100)
+ go func() {
+ for _, rootPath := range rootPaths {
+ log.Println(rootPath)
+ err := filepath.Walk(rootPath, func(path string, finfo os.FileInfo, err error) error {
+ if err != nil {
+ log.Printf("filepath.Walk:%v\n", err)
+ return err
+ }
+
+ if !finfo.IsDir() {
+ expFile := expPath + path[len(info.FilePath):]
+ _, err := os.Stat(filepath.Dir(expFile))
+ if err != nil {
+ os.MkdirAll(filepath.Dir(expFile), 0644)
+ }
+
+ _, err = os.Stat(expFile)
+ if err == nil {
+ return nil
+ }
+ task := [2]string{path, expFile}
+ taskChan <- task
+ return nil
+ }
+
+ return nil
+ })
+ if err != nil {
+ log.Println("filepath.Walk:", err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%v\"}", err)
+ }
+ }
+ close(taskChan)
+ }()
+
+ for i := 1; i < 30; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for task := range taskChan {
+ _, err := copyFile(task[0], task[1])
+ if err != nil {
+ log.Println("DecryptDat:", err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"copyFile %v\"}", err)
+ }
+ }
+ }()
+ }
+ wg.Wait()
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat Video and File end\", \"progress\": 60}"
+}
+
+func exportWeChatBat(info WeChatInfo, expPath string, progress chan<- string) {
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat Dat start\", \"progress\": 21}"
+ datRootPath := info.FilePath + "\\FileStorage\\MsgAttach"
+ fileInfo, err := os.Stat(datRootPath)
+ if err != nil || !fileInfo.IsDir() {
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%s error\"}", datRootPath)
+ return
+ }
+
+ var wg sync.WaitGroup
+ taskChan := make(chan [2]string, 100)
+ go func() {
+ err = filepath.Walk(datRootPath, func(path string, finfo os.FileInfo, err error) error {
+ if err != nil {
+ log.Printf("filepath.Walk:%v\n", err)
+ return err
+ }
+
+ if !finfo.IsDir() && strings.HasSuffix(path, ".dat") {
+ expFile := expPath + path[len(info.FilePath):]
+ _, err := os.Stat(filepath.Dir(expFile))
+ if err != nil {
+ os.MkdirAll(filepath.Dir(expFile), 0644)
+ }
+
+ _, err = os.Stat(expFile)
+ if err == nil {
+ return nil
+ }
+
+ task := [2]string{path, expFile}
+ taskChan <- task
+ return nil
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ log.Println("filepath.Walk:", err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%v\"}", err)
+ }
+ close(taskChan)
+ }()
+
+ for i := 1; i < 30; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for task := range taskChan {
+ err = DecryptDat(task[0], task[1])
+ if err != nil {
+ log.Println("DecryptDat:", err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"DecryptDat %v\"}", err)
+ }
+ }
+ }()
+ }
+ wg.Wait()
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat Dat end\", \"progress\": 40}"
+}
+
+func exportWeChatDateBase(info WeChatInfo, expPath string, progress chan<- string) bool {
+
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat DateBase start\", \"progress\": 1}"
+
+ dbKey, err := hex.DecodeString(info.DBKey)
+ if err != nil {
+ log.Println("DecodeString:", err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%v\"}", err)
+ return false
+ }
+
+ var wg sync.WaitGroup
+ taskChan := make(chan [2]string, 20)
+ go func() {
+ err = filepath.Walk(info.FilePath+"\\Msg", func(path string, finfo os.FileInfo, err error) error {
+ if err != nil {
+ log.Printf("filepath.Walk:%v\n", err)
+ return err
+ }
+ if !finfo.IsDir() && strings.HasSuffix(path, ".db") {
+ expFile := expPath + path[len(info.FilePath):]
+ _, err := os.Stat(filepath.Dir(expFile))
+ if err != nil {
+ os.MkdirAll(filepath.Dir(expFile), 0644)
+ }
+
+ task := [2]string{path, expFile}
+ taskChan <- task
+ }
+
+ return nil
+ })
+ if err != nil {
+ log.Println("filepath.Walk:", err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%v\"}", err)
+ }
+ close(taskChan)
+ }()
+
+ for i := 1; i < 20; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for task := range taskChan {
+ if filepath.Base(task[0]) == "xInfo.db" {
+ copyFile(task[0], task[1])
+ } else {
+ err = DecryptDataBase(task[0], dbKey, task[1])
+ if err != nil {
+ log.Println("DecryptDataBase:", err)
+ progress <- fmt.Sprintf("{\"status\":\"error\", \"result\":\"%s %v\"}", task[0], err)
+ }
+ }
+ }
+ }()
+ }
+ wg.Wait()
+ progress <- "{\"status\":\"processing\", \"result\":\"export WeChat DateBase end\", \"progress\": 20}"
+ return true
+}
+
+func GetWeChatInfo() (info WeChatInfo, rerr error) {
+ info = WeChatInfo{}
+ processes, err := process.Processes()
+ if err != nil {
+ log.Println("Error getting processes:", err)
+ rerr = err
+ return
+ }
+
+ found := false
+ for _, p := range processes {
+ name, err := p.Name()
+ if err != nil {
+ continue
+ }
+ if name == "WeChat.exe" {
+ found = true
+ info.ProcessID = uint32(p.Pid)
+ info.Is64Bits, _ = Is64BitProcess(info.ProcessID)
+ log.Println("ProcessID", info.ProcessID)
+ files, err := p.OpenFiles()
+ if err != nil {
+ log.Println("OpenFiles failed")
+ return
+ }
+
+ for _, f := range files {
+ if strings.HasSuffix(f.Path, "\\Media.db") {
+ // fmt.Printf("opened %s\n", f.Path[4:])
+ filePath := f.Path[4:]
+ parts := strings.Split(filePath, string(filepath.Separator))
+ if len(parts) < 4 {
+ return info, errors.New("Error filePath " + filePath)
+ }
+ info.FilePath = strings.Join(parts[:len(parts)-2], string(filepath.Separator))
+ info.AcountName = strings.Join(parts[len(parts)-3:len(parts)-2], string(filepath.Separator))
+ }
+
+ }
+
+ if len(info.FilePath) == 0 {
+ rerr = errors.New("wechat not log in")
+ return
+ }
+
+ hModuleSnap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE|windows.TH32CS_SNAPMODULE32, uint32(p.Pid))
+ if err != nil {
+ log.Println("CreateToolhelp32Snapshot failed", err)
+ return
+ }
+ defer windows.CloseHandle(hModuleSnap)
+
+ var me32 windows.ModuleEntry32
+ me32.Size = uint32(windows.SizeofModuleEntry32)
+
+ err = windows.Module32First(hModuleSnap, &me32)
+ if err != nil {
+ log.Println("Module32First failed", err)
+ return
+ }
+
+ for ; err == nil; err = windows.Module32Next(hModuleSnap, &me32) {
+ if windows.UTF16ToString(me32.Module[:]) == "WeChatWin.dll" {
+ // fmt.Printf("MODULE NAME: %s\n", windows.UTF16ToString(me32.Module[:]))
+ // fmt.Printf("executable NAME: %s\n", windows.UTF16ToString(me32.ExePath[:]))
+ // fmt.Printf("base address: 0x%08X\n", me32.ModBaseAddr)
+ // fmt.Printf("base ModBaseSize: %d\n", me32.ModBaseSize)
+ info.DllBaseAddr = me32.ModBaseAddr
+ info.DllBaseSize = me32.ModBaseSize
+
+ var zero windows.Handle
+ driverPath := windows.UTF16ToString(me32.ExePath[:])
+ infoSize, err := windows.GetFileVersionInfoSize(driverPath, &zero)
+ if err != nil {
+ log.Println("GetFileVersionInfoSize failed", err)
+ return
+ }
+ versionInfo := make([]byte, infoSize)
+ if err = windows.GetFileVersionInfo(driverPath, 0, infoSize, unsafe.Pointer(&versionInfo[0])); err != nil {
+ log.Println("GetFileVersionInfo failed", err)
+ return
+ }
+ var fixedInfo *windows.VS_FIXEDFILEINFO
+ fixedInfoLen := uint32(unsafe.Sizeof(*fixedInfo))
+ err = windows.VerQueryValue(unsafe.Pointer(&versionInfo[0]), `\`, (unsafe.Pointer)(&fixedInfo), &fixedInfoLen)
+ if err != nil {
+ log.Println("VerQueryValue failed", err)
+ return
+ }
+ // fmt.Printf("%s: v%d.%d.%d.%d\n", windows.UTF16ToString(me32.Module[:]),
+ // (fixedInfo.FileVersionMS>>16)&0xff,
+ // (fixedInfo.FileVersionMS>>0)&0xff,
+ // (fixedInfo.FileVersionLS>>16)&0xff,
+ // (fixedInfo.FileVersionLS>>0)&0xff)
+
+ info.Version = fmt.Sprintf("%d.%d.%d.%d",
+ (fixedInfo.FileVersionMS>>16)&0xff,
+ (fixedInfo.FileVersionMS>>0)&0xff,
+ (fixedInfo.FileVersionLS>>16)&0xff,
+ (fixedInfo.FileVersionLS>>0)&0xff)
+ break
+ }
+ }
+ }
+ }
+
+ if !found {
+ rerr = errors.New("not found process")
+ }
+
+ return
+}
+
+func Is64BitProcess(pid uint32) (bool, error) {
+ is64Bit := false
+ handle, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, false, pid)
+ if err != nil {
+ log.Println("Error opening process:", err)
+ return is64Bit, errors.New("OpenProcess failed")
+ }
+ defer windows.CloseHandle(handle)
+
+ err = windows.IsWow64Process(handle, &is64Bit)
+ if err != nil {
+ log.Println("Error IsWow64Process:", err)
+ }
+ return !is64Bit, err
+}
+
+func GetWeChatKey(info *WeChatInfo) string {
+ handle, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION|windows.PROCESS_VM_READ, false, uint32(info.ProcessID))
+ if err != nil {
+ log.Println("Error opening process:", err)
+ return ""
+ }
+ defer windows.CloseHandle(handle)
+
+ buffer := make([]byte, info.DllBaseSize)
+ err = windows.ReadProcessMemory(handle, uintptr(info.DllBaseAddr), &buffer[0], uintptr(len(buffer)), nil)
+ if err != nil {
+ log.Println("Error ReadProcessMemory:", err)
+ return ""
+ }
+
+ offset := 0
+ // searchStr := []byte(info.AcountName)
+ for {
+ index := hasDeviceSybmol(buffer[offset:])
+ if index == -1 {
+ fmt.Println("hasDeviceSybmolxxxx")
+ break
+ }
+ fmt.Printf("hasDeviceSybmol: 0x%X\n", index)
+ keys := findDBKeyPtr(buffer[offset:index], info.Is64Bits)
+ // fmt.Println("keys:", keys)
+
+ key, err := findDBkey(handle, info.FilePath+"\\Msg\\Media.db", keys)
+ if err == nil {
+ // fmt.Println("key:", key)
+ return key
+ }
+
+ offset += (index + 20)
+ }
+
+ return ""
+}
+
+func hasDeviceSybmol(buffer []byte) int {
+ sybmols := [...][]byte{
+ {'a', 'n', 'd', 'r', 'o', 'i', 'd', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00},
+ {'i', 'p', 'h', 'o', 'n', 'e', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00},
+ {'i', 'p', 'a', 'd', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00},
+ }
+ for _, syb := range sybmols {
+ if index := bytes.Index(buffer, syb); index != -1 {
+ return index
+ }
+ }
+
+ return -1
+}
+
+func findDBKeyPtr(buffer []byte, is64Bits bool) [][]byte {
+ keys := make([][]byte, 0)
+ step := 8
+ keyLen := []byte{0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+ if !is64Bits {
+ keyLen = keyLen[:4]
+ step = 4
+ }
+
+ offset := len(buffer) - step
+ for {
+ if bytes.Contains(buffer[offset:offset+step], keyLen) {
+ keys = append(keys, buffer[offset-step:offset])
+ }
+
+ offset -= step
+ if offset <= 0 {
+ break
+ }
+ }
+
+ return keys
+}
+
+func findDBkey(handle windows.Handle, path string, keys [][]byte) (string, error) {
+ var keyAddrPtr uint64
+ addrBuffer := make([]byte, 0x08)
+ for _, key := range keys {
+ copy(addrBuffer, key)
+ err := binary.Read(bytes.NewReader(addrBuffer), binary.LittleEndian, &keyAddrPtr)
+ if err != nil {
+ log.Println("binary.Read:", err)
+ continue
+ }
+ if keyAddrPtr == 0x00 {
+ continue
+ }
+ log.Println("keyAddrPtr: 0x%X\n", keyAddrPtr)
+ keyBuffer := make([]byte, 0x20)
+ err = windows.ReadProcessMemory(handle, uintptr(keyAddrPtr), &keyBuffer[0], uintptr(len(keyBuffer)), nil)
+ if err != nil {
+ // fmt.Println("Error ReadProcessMemory:", err)
+ continue
+ }
+ if checkDataBaseKey(path, keyBuffer) {
+ return hex.EncodeToString(keyBuffer), nil
+ }
+ }
+
+ return "", errors.New("not found key")
+}
+
+func checkDataBaseKey(path string, password []byte) bool {
+ fp, err := os.Open(path)
+ if err != nil {
+ return false
+ }
+ defer fp.Close()
+
+ fpReader := bufio.NewReaderSize(fp, defaultPageSize*100)
+
+ buffer := make([]byte, defaultPageSize)
+
+ n, err := fpReader.Read(buffer)
+ if err != nil && n != defaultPageSize {
+ log.Println("read failed:", err, n)
+ return false
+ }
+
+ salt := buffer[:16]
+ key := pbkdf2HMAC(password, salt, defaultIter, keySize)
+
+ page1 := buffer[16:defaultPageSize]
+
+ macSalt := xorBytes(salt, 0x3a)
+ macKey := pbkdf2HMAC(key, macSalt, 2, keySize)
+
+ hashMac := hmac.New(sha1.New, macKey)
+ hashMac.Write(page1[:len(page1)-32])
+ hashMac.Write([]byte{1, 0, 0, 0})
+
+ return hmac.Equal(hashMac.Sum(nil), page1[len(page1)-32:len(page1)-12])
+}
+
+func (info WeChatInfo) String() string {
+ return fmt.Sprintf("PID: %d\nVersion: v%s\nBaseAddr: 0x%08X\nDllSize: %d\nIs 64Bits: %v\nFilePath %s\nAcountName: %s",
+ info.ProcessID, info.Version, info.DllBaseAddr, info.DllBaseSize, info.Is64Bits, info.FilePath, info.AcountName)
+}
+
+func copyFile(src, dst string) (int64, error) {
+ sourceFile, err := os.Open(src)
+ if err != nil {
+ return 0, err
+ }
+ defer sourceFile.Close()
+
+ destFile, err := os.Create(dst)
+ if err != nil {
+ return 0, err
+ }
+ defer destFile.Close()
+
+ bytesWritten, err := io.Copy(destFile, sourceFile)
+ if err != nil {
+ return bytesWritten, err
+ }
+
+ return bytesWritten, nil
+}
+
+func silkToMp3(amrBuf []byte, mp3Path string) error {
+ amrReader := bytes.NewReader(amrBuf)
+
+ var pcmBuffer bytes.Buffer
+ sr := silk.NewWriter(&pcmBuffer)
+ sr.Decoder.SetSampleRate(24000)
+ amrReader.WriteTo(sr)
+ sr.Close()
+
+ if pcmBuffer.Len() == 0 {
+ return errors.New("silk to mp3 failed " + mp3Path)
+ }
+
+ of, err := os.Create(mp3Path)
+ if err != nil {
+ return nil
+ }
+ defer of.Close()
+
+ wr := lame.NewWriter(of)
+ wr.Encoder.SetInSamplerate(24000)
+ wr.Encoder.SetNumChannels(1)
+ wr.Encoder.SetBitrate(16)
+ wr.Encoder.SetQuality(7)
+ // IMPORTANT!
+ wr.Encoder.InitParams()
+
+ pcmBuffer.WriteTo(wr)
+ wr.Close()
+
+ return nil
+}
diff --git a/pkg/wechat/wechatDBDec.go b/pkg/wechat/wechatDBDec.go
new file mode 100644
index 0000000..5c1a708
--- /dev/null
+++ b/pkg/wechat/wechatDBDec.go
@@ -0,0 +1,170 @@
+package wechat
+
+import (
+ "bufio"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/sha1"
+ "fmt"
+ "io"
+ "os"
+)
+
+const (
+ keySize = 32
+ defaultIter = 64000
+ defaultPageSize = 4096
+)
+
+func DecryptDataBase(path string, password []byte, expPath string) error {
+ sqliteFileHeader := []byte("SQLite format 3")
+ sqliteFileHeader = append(sqliteFileHeader, byte(0))
+
+ fp, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+ defer fp.Close()
+
+ fpReader := bufio.NewReaderSize(fp, defaultPageSize*100)
+ // fpReader := bufio.NewReader(fp)
+
+ buffer := make([]byte, defaultPageSize)
+
+ n, err := fpReader.Read(buffer)
+ if err != nil && n != defaultPageSize {
+ return fmt.Errorf("read failed")
+ }
+
+ salt := buffer[:16]
+ key := pbkdf2HMAC(password, salt, defaultIter, keySize)
+
+ page1 := buffer[16:defaultPageSize]
+
+ macSalt := xorBytes(salt, 0x3a)
+ macKey := pbkdf2HMAC(key, macSalt, 2, keySize)
+
+ hashMac := hmac.New(sha1.New, macKey)
+ hashMac.Write(page1[:len(page1)-32])
+ hashMac.Write([]byte{1, 0, 0, 0})
+
+ if !hmac.Equal(hashMac.Sum(nil), page1[len(page1)-32:len(page1)-12]) {
+ return fmt.Errorf("incorrect password")
+ }
+
+ outFilePath := expPath
+ outFile, err := os.Create(outFilePath)
+ if err != nil {
+ return err
+ }
+ defer outFile.Close()
+
+ // Write SQLite file header
+ _, err = outFile.Write(sqliteFileHeader)
+ if err != nil {
+ return err
+ }
+
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return err
+ }
+
+ page1 = buffer[16:defaultPageSize]
+ iv := page1[len(page1)-48 : len(page1)-32]
+ stream := cipher.NewCBCDecrypter(block, iv)
+ decrypted := make([]byte, len(page1)-48)
+ stream.CryptBlocks(decrypted, page1[:len(page1)-48])
+ _, err = outFile.Write(decrypted)
+ if err != nil {
+ return err
+ }
+ _, err = outFile.Write(page1[len(page1)-48:])
+ if err != nil {
+ return err
+ }
+
+ for {
+ n, err = fpReader.Read(buffer)
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ return err
+ } else if n < defaultPageSize {
+ return fmt.Errorf("read data to short %d", n)
+ }
+
+ iv := buffer[len(buffer)-48 : len(buffer)-32]
+ stream := cipher.NewCBCDecrypter(block, iv)
+ decrypted := make([]byte, len(buffer)-48)
+ stream.CryptBlocks(decrypted, buffer[:len(buffer)-48])
+ _, err = outFile.Write(decrypted)
+ if err != nil {
+ return err
+ }
+ _, err = outFile.Write(buffer[len(buffer)-48:])
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func pbkdf2HMAC(password, salt []byte, iter, keyLen int) []byte {
+ dk := make([]byte, keyLen)
+ loop := (keyLen + sha1.Size - 1) / sha1.Size
+ key := make([]byte, 0, len(salt)+4)
+ u := make([]byte, sha1.Size)
+ for i := 1; i <= loop; i++ {
+ key = key[:0]
+ key = append(key, salt...)
+ key = append(key, byte(i>>24), byte(i>>16), byte(i>>8), byte(i))
+ hmac := hmac.New(sha1.New, password)
+ hmac.Write(key)
+ digest := hmac.Sum(nil)
+ copy(u, digest)
+ for j := 2; j <= iter; j++ {
+ hmac.Reset()
+ hmac.Write(digest)
+ digest = hmac.Sum(digest[:0])
+ for k, di := range digest {
+ u[k] ^= di
+ }
+ }
+ copy(dk[(i-1)*sha1.Size:], u)
+ }
+ return dk
+}
+
+func xorBytes(a []byte, b byte) []byte {
+ result := make([]byte, len(a))
+ for i := range a {
+ result[i] = a[i] ^ b
+ }
+ return result
+}
+
+/*
+func main() {
+
+ str := "82b1a210335140a1bc8a57397391186494abe666595b4f408095538b5518f7d5"
+ // 将十六进制字符串解码为字节
+ password, err := hex.DecodeString(str)
+ if err != nil {
+ fmt.Println("解码出错:", err)
+ return
+ }
+
+ fmt.Println(hex.EncodeToString(password))
+
+ err = decryptMsg("Media.db", password)
+ if err != nil {
+ fmt.Println("Error:", err)
+ } else {
+ fmt.Println("Decryption successful!")
+ }
+}
+*/
diff --git a/pkg/wechat/wechatDataProvider.go b/pkg/wechat/wechatDataProvider.go
new file mode 100644
index 0000000..086daf7
--- /dev/null
+++ b/pkg/wechat/wechatDataProvider.go
@@ -0,0 +1,878 @@
+package wechat
+
+import (
+ "database/sql"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "sort"
+ "strconv"
+ "strings"
+ sync "sync"
+ "time"
+
+ "github.com/beevik/etree"
+ _ "github.com/mattn/go-sqlite3"
+ "github.com/pierrec/lz4"
+ "google.golang.org/protobuf/proto"
+)
+
+const (
+ Wechat_Message_Type_Text = 1
+ Wechat_Message_Type_Picture = 3
+ Wechat_Message_Type_Voice = 34
+ Wechat_Message_Type_Video = 43
+ Wechat_Message_Type_Emoji = 47
+ Wechat_Message_Type_Misc = 49
+ Wechat_Message_Type_System = 10000
+)
+
+const (
+ Wechat_Misc_Message_TEXT = 1
+ Wechat_Misc_Message_CardLink = 5
+ Wechat_Misc_Message_File = 6
+ Wechat_Misc_Message_CustomEmoji = 8
+ Wechat_Misc_Message_ForwardMessage = 19
+ Wechat_Misc_Message_Applet = 33
+ Wechat_Misc_Message_Applet2 = 36
+ Wechat_Misc_Message_Refer = 57
+ Wechat_Misc_Message_Live = 63
+ Wechat_Misc_Message_Notice = 87
+ Wechat_Misc_Message_Live2 = 88
+ Wechat_Misc_Message_Transfer = 2000
+ Wechat_Misc_Message_RedPacket = 2003
+)
+
+const (
+ Wechat_System_Message_Notice = 1
+ Wechat_System_Message_Tickle = 4
+ Wechat_System_Message_Notice2 = 8000
+)
+
+type Message_Search_Direction int
+
+const (
+ Message_Search_Forward Message_Search_Direction = iota
+ Message_Search_Backward
+ Message_Search_Both
+)
+
+type WeChatUserInfo struct {
+ UserName string `json:"UserName"`
+ Alias string `json:"Alias"`
+ ReMark string `json:"ReMark"`
+ NickName string `json:"NickName"`
+ SmallHeadImgUrl string `json:"SmallHeadImgUrl"`
+ BigHeadImgUrl string `json:"BigHeadImgUrl"`
+}
+
+type WeChatSession struct {
+ UserName string `json:"UserName"`
+ NickName string `json:"NickName"`
+ Content string `json:"Content"`
+ UserInfo WeChatUserInfo `json:"UserInfo"`
+ Time uint64 `json:"Time"`
+ IsGroup bool `json:IsGroup`
+}
+
+type WeChatSessionList struct {
+ Total int `json:"Total"`
+ Rows []WeChatSession `json:"Rows"`
+}
+
+type FileInfo struct {
+ FileName string `json:"fileName"`
+ FileSize string `json:"fileSize"`
+ FilePath string `json:"filePath"`
+ FileExt string `json:"fileExt"`
+}
+
+type LinkInfo struct {
+ Url string `json:"Url"`
+ Title string `json:"Title"`
+ Description string `json:"Description"`
+ DisPlayName string `json:"DisPlayName"`
+}
+
+type ReferInfo struct {
+ Type int `json:"Type"`
+ SubType int `json:"SubType"`
+ Svrid int64 `json:"Svrid"`
+ Displayname string `json:"Displayname"`
+ Content string `json:"Content"`
+}
+
+type WeChatMessage struct {
+ LocalId int `json:"LocalId"`
+ MsgSvrId int64 `json:"MsgSvrId"`
+ Type int `json:"type"`
+ SubType int `json:"SubType"`
+ IsSender int `json:"IsSender"`
+ CreateTime int64 `json:"createTime"`
+ Talker string `json:"talker"`
+ Content string `json:"content"`
+ ThumbPath string `json:"ThumbPath"`
+ ImagePath string `json:"ImagePath"`
+ VideoPath string `json:"VideoPath"`
+ FileInfo FileInfo `json:"fileInfo"`
+ EmojiPath string `json:"EmojiPath"`
+ VoicePath string `json:"VoicePath"`
+ IsChatRoom bool `json:"isChatRoom"`
+ UserInfo WeChatUserInfo `json:"userInfo"`
+ LinkInfo LinkInfo `json:"LinkInfo"`
+ ReferInfo ReferInfo `json:"ReferInfo"`
+ compressContent []byte
+ bytesExtra []byte
+}
+
+type WeChatMessageList struct {
+ KeyWord string `json:"KeyWord"`
+ Total int `json:"Total"`
+ Rows []WeChatMessage `json:"Rows"`
+}
+
+type WeChatMessageDate struct {
+ Date []string `json:"Date"`
+ Total int `json:"Total"`
+}
+
+type WeChatUserList struct {
+ Users []WeChatUserInfo `json:"Users"`
+ Total int `json:"Total"`
+}
+
+type wechatMsgDB struct {
+ path string
+ db *sql.DB
+ startTime int64
+ endTime int64
+}
+
+type WechatDataProvider struct {
+ resPath string
+ microMsg *sql.DB
+
+ msgDBs []*wechatMsgDB
+ userInfoMap map[string]WeChatUserInfo
+ userInfoMtx sync.Mutex
+
+ SelfInfo *WeChatUserInfo
+}
+
+const (
+ MicroMsgDB = "MicroMsg.db"
+)
+
+type byTime []*wechatMsgDB
+
+func (a byTime) Len() int { return len(a) }
+func (a byTime) Less(i, j int) bool { return a[i].startTime > a[j].startTime }
+func (a byTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+func CreateWechatDataProvider(resPath string) (*WechatDataProvider, error) {
+ provider := &WechatDataProvider{}
+ provider.resPath = resPath
+ provider.msgDBs = make([]*wechatMsgDB, 0)
+ log.Println(resPath)
+ userName := filepath.Base(resPath)
+ MicroMsgDBPath := resPath + "\\Msg\\" + MicroMsgDB
+ microMsg, err := sql.Open("sqlite3", MicroMsgDBPath)
+ if err != nil {
+ log.Printf("open db %s error: %v", MicroMsgDBPath, err)
+ return provider, err
+ }
+
+ index := 0
+ for {
+ msgDBPath := fmt.Sprintf("%s\\Msg\\Multi\\MSG%d.db", provider.resPath, index)
+ if _, err := os.Stat(msgDBPath); err != nil {
+ log.Println("msgDBPath end", msgDBPath)
+ break
+ }
+
+ msgDB, err := wechatOpenMsgDB(msgDBPath)
+ if err != nil {
+ log.Printf("open db %s error: %v", msgDBPath, err)
+ break
+ }
+ provider.msgDBs = append(provider.msgDBs, msgDB)
+ log.Printf("MSG%d.db start %d - %d end\n", index, msgDB.startTime, msgDB.endTime)
+ index += 1
+ }
+ sort.Sort(byTime(provider.msgDBs))
+ for _, db := range provider.msgDBs {
+ log.Printf("%s start %d - %d end\n", db.path, db.startTime, db.endTime)
+ }
+ provider.userInfoMap = make(map[string]WeChatUserInfo)
+ provider.microMsg = microMsg
+ provider.SelfInfo, err = provider.WechatGetUserInfoByName(userName)
+ if err != nil {
+ log.Printf("WechatGetUserInfoByName %s failed: %v", userName, err)
+ return provider, err
+ }
+ provider.userInfoMap[userName] = *provider.SelfInfo
+ log.Println("resPath:", provider.resPath)
+ return provider, nil
+}
+
+func (P *WechatDataProvider) WechatWechatDataProviderClose() {
+ if P.microMsg != nil {
+ P.microMsg.Close()
+ }
+
+ for _, db := range P.msgDBs {
+ db.db.Close()
+ }
+ log.Println("WechatWechatDataProviderClose")
+}
+
+func (P *WechatDataProvider) WechatGetUserInfoByName(name string) (*WeChatUserInfo, error) {
+ info := &WeChatUserInfo{}
+
+ var UserName, Alias, ReMark, NickName string
+ querySql := fmt.Sprintf("select ifnull(UserName,'') as UserName, ifnull(Alias,'') as Alias, ifnull(ReMark,'') as ReMark, ifnull(NickName,'') as NickName from Contact where UserName='%s';", name)
+ // log.Println(querySql)
+ err := P.microMsg.QueryRow(querySql).Scan(&UserName, &Alias, &ReMark, &NickName)
+ if err != nil {
+ log.Println("not found User:", err)
+ return info, err
+ }
+
+ log.Printf("UserName %s, Alias %s, ReMark %s, NickName %s\n", UserName, Alias, ReMark, NickName)
+
+ var smallHeadImgUrl, bigHeadImgUrl string
+ querySql = fmt.Sprintf("select ifnull(smallHeadImgUrl,'') as smallHeadImgUrl, ifnull(bigHeadImgUrl,'') as bigHeadImgUrl from ContactHeadImgUrl where usrName='%s';", UserName)
+ // log.Println(querySql)
+ err = P.microMsg.QueryRow(querySql).Scan(&smallHeadImgUrl, &bigHeadImgUrl)
+ if err != nil {
+ log.Println("not find headimg", err)
+ }
+
+ info.UserName = UserName
+ info.Alias = Alias
+ info.ReMark = ReMark
+ info.NickName = NickName
+ info.SmallHeadImgUrl = smallHeadImgUrl
+ info.BigHeadImgUrl = bigHeadImgUrl
+
+ // log.Println(info)
+ return info, nil
+}
+
+func (P *WechatDataProvider) WeChatGetSessionList(pageIndex int, pageSize int) (*WeChatSessionList, error) {
+ List := &WeChatSessionList{}
+ List.Rows = make([]WeChatSession, 0)
+
+ querySql := fmt.Sprintf("select ifnull(strUsrName,'') as strUsrName,ifnull(strNickName,'') as strNickName,ifnull(strContent,'') as strContent, nTime from Session order by rowid desc limit %d, %d;", pageIndex*pageSize, pageSize)
+ dbRows, err := P.microMsg.Query(querySql)
+ if err != nil {
+ log.Println(err)
+ return List, err
+ }
+ defer dbRows.Close()
+
+ var strUsrName, strNickName, strContent string
+ var nTime uint64
+ for dbRows.Next() {
+ var session WeChatSession
+ err = dbRows.Scan(&strUsrName, &strNickName, &strContent, &nTime)
+ if err != nil {
+ log.Println(err)
+ continue
+ }
+ if len(strContent) == 0 {
+ log.Printf("%s cotent nil\n", strUsrName)
+ continue
+ }
+
+ session.UserName = strUsrName
+ session.NickName = strNickName
+ session.Content = strContent
+ session.Time = nTime
+ session.IsGroup = strings.HasSuffix(strUsrName, "@chatroom")
+ info, err := P.WechatGetUserInfoByName(strUsrName)
+ if err != nil {
+ log.Printf("WechatGetUserInfoByName %s failed\n", strUsrName)
+ continue
+ }
+ session.UserInfo = *info
+ List.Rows = append(List.Rows, session)
+ List.Total += 1
+ }
+
+ return List, nil
+}
+
+func (P *WechatDataProvider) WeChatGetMessageListByTime(userName string, time int64, pageSize int, direction Message_Search_Direction) (*WeChatMessageList, error) {
+
+ List := &WeChatMessageList{}
+ List.Rows = make([]WeChatMessage, 0)
+ selectTime := time
+ selectpageSize := pageSize
+
+ if direction == Message_Search_Both {
+ selectpageSize = pageSize / 2
+ }
+ for direction == Message_Search_Forward || direction == Message_Search_Both {
+ selectList, err := P.weChatGetMessageListByTime(userName, selectTime, selectpageSize, Message_Search_Forward)
+ if err != nil {
+ return List, err
+ }
+
+ if selectList.Total == 0 {
+ break
+ }
+
+ selectTime = selectList.Rows[selectList.Total-1].CreateTime - 1
+ selectpageSize -= selectList.Total
+ List.Total += selectList.Total
+ List.Rows = append(List.Rows, selectList.Rows...)
+ if selectpageSize <= 0 {
+ break
+ }
+ log.Printf("Forward selectTime %d, selectpageSize %d\n", selectTime, selectpageSize)
+ }
+
+ selectTime = time
+ if direction == Message_Search_Both {
+ selectpageSize = pageSize / 2
+ }
+ for direction == Message_Search_Backward || direction == Message_Search_Both {
+ selectList, err := P.weChatGetMessageListByTime(userName, selectTime, selectpageSize, Message_Search_Backward)
+ if err != nil {
+ return List, err
+ }
+
+ if selectList.Total == 0 {
+ break
+ }
+
+ selectTime = selectList.Rows[0].CreateTime + 1
+ selectpageSize -= selectList.Total
+ List.Total += selectList.Total
+ List.Rows = append(selectList.Rows, List.Rows...)
+ if selectpageSize <= 0 {
+ break
+ }
+ log.Printf("Backward selectTime %d, selectpageSize %d\n", selectTime, selectpageSize)
+ }
+
+ return List, nil
+}
+
+func (P *WechatDataProvider) weChatGetMessageListByTime(userName string, time int64, pageSize int, direction Message_Search_Direction) (*WeChatMessageList, error) {
+ List := &WeChatMessageList{}
+ List.Rows = make([]WeChatMessage, 0)
+ index := P.wechatFindDBIndex(userName, time, direction)
+ if index == -1 {
+ log.Printf("Not found %s %d data\n", userName, time)
+ return List, nil
+ }
+
+ sqlFormat := "select localId,MsgSvrID,Type,SubType,IsSender,CreateTime,ifnull(StrTalker,'') as StrTalker, ifnull(StrContent,'') as StrContent,ifnull(CompressContent,'') as CompressContent,ifnull(BytesExtra,'') as BytesExtra from MSG Where StrTalker='%s' And CreateTime<=%d order by CreateTime desc limit %d;"
+ if direction == Message_Search_Backward {
+ sqlFormat = "select localId,MsgSvrID,Type,SubType,IsSender,CreateTime,ifnull(StrTalker,'') as StrTalker, ifnull(StrContent,'') as StrContent,ifnull(CompressContent,'') as CompressContent,ifnull(BytesExtra,'') as BytesExtra from ( select localId, MsgSvrID, Type, SubType, IsSender, CreateTime, StrTalker, StrContent, CompressContent, BytesExtra FROM MSG Where StrTalker='%s' And CreateTime>%d order by CreateTime asc limit %d) AS SubQuery order by CreateTime desc;"
+ }
+ querySql := fmt.Sprintf(sqlFormat, userName, time, pageSize)
+ log.Println(querySql)
+
+ rows, err := P.msgDBs[index].db.Query(querySql)
+ if err != nil {
+ log.Printf("%s failed %v\n", querySql, err)
+ return List, nil
+ }
+ defer rows.Close()
+ var localId, Type, SubType, IsSender int
+ var MsgSvrID, CreateTime int64
+ var StrTalker, StrContent string
+ var CompressContent, BytesExtra []byte
+
+ for rows.Next() {
+ message := WeChatMessage{}
+ err = rows.Scan(&localId, &MsgSvrID, &Type, &SubType, &IsSender, &CreateTime,
+ &StrTalker, &StrContent, &CompressContent, &BytesExtra)
+ if err != nil {
+ log.Println("rows.Scan failed", err)
+ return List, err
+ }
+ message.LocalId = localId
+ message.MsgSvrId = MsgSvrID
+ message.Type = Type
+ message.SubType = SubType
+ message.IsSender = IsSender
+ message.CreateTime = CreateTime
+ message.Talker = StrTalker
+ message.Content = StrContent
+ message.IsChatRoom = strings.HasSuffix(StrTalker, "@chatroom")
+ message.compressContent = make([]byte, len(CompressContent))
+ message.bytesExtra = make([]byte, len(BytesExtra))
+ copy(message.compressContent, CompressContent)
+ copy(message.bytesExtra, BytesExtra)
+ P.wechatMessageExtraHandle(&message)
+ P.wechatMessageGetUserInfo(&message)
+ P.wechatMessageEmojiHandle(&message)
+ P.wechatMessageCompressContentHandle(&message)
+ List.Rows = append(List.Rows, message)
+ List.Total += 1
+ }
+
+ if err := rows.Err(); err != nil {
+ log.Println("rows.Scan failed", err)
+ return List, err
+ }
+
+ return List, nil
+}
+
+func (P *WechatDataProvider) WeChatGetMessageListByKeyWord(userName string, time int64, keyWord string, msgType string, pageSize int) (*WeChatMessageList, error) {
+ List := &WeChatMessageList{}
+ List.Rows = make([]WeChatMessage, 0)
+ List.KeyWord = keyWord
+ _time := time
+ selectPagesize := pageSize
+ if keyWord != "" || msgType != "" {
+ selectPagesize = 600
+ }
+ for {
+ log.Println("time:", _time, keyWord)
+ rawList, err := P.weChatGetMessageListByTime(userName, _time, selectPagesize, Message_Search_Forward)
+ if err != nil {
+ log.Println("weChatGetMessageListByTime failed: ", err)
+ return nil, err
+ }
+ log.Println("rawList.Total:", rawList.Total)
+ if rawList.Total == 0 {
+ if List.Total == 0 {
+ log.Printf("user %s not find [%s]\n", userName, keyWord)
+ }
+ break
+ }
+
+ for i, _ := range rawList.Rows {
+ if weChatMessageTypeFilter(&rawList.Rows[i], msgType) && (len(keyWord) == 0 || weChatMessageContains(&rawList.Rows[i], keyWord)) {
+ List.Rows = append(List.Rows, rawList.Rows[i])
+ List.Total += 1
+ if List.Total >= pageSize {
+ return List, nil
+ }
+ }
+ }
+
+ _time = rawList.Rows[rawList.Total-1].CreateTime - 1
+ }
+
+ return List, nil
+}
+
+func (P *WechatDataProvider) WeChatGetMessageDate(userName string) (*WeChatMessageDate, error) {
+ messageData := &WeChatMessageDate{}
+ messageData.Date = make([]string, 0)
+ messageData.Total = 0
+
+ _time := time.Now().Unix()
+
+ for {
+ index := P.wechatFindDBIndex(userName, _time, Message_Search_Forward)
+ if index == -1 {
+ log.Println("wechat find db end")
+ return messageData, nil
+ }
+
+ sqlFormat := " SELECT DISTINCT strftime('%%Y-%%m-%%d', datetime(CreateTime+28800, 'unixepoch')) FROM MSG WHERE StrTalker='%s' order by CreateTime desc;"
+ querySql := fmt.Sprintf(sqlFormat, userName)
+
+ rows, err := P.msgDBs[index].db.Query(querySql)
+ if err != nil {
+ log.Printf("%s failed %v\n", querySql, err)
+ return messageData, nil
+ }
+ defer rows.Close()
+
+ var date string
+ for rows.Next() {
+ err = rows.Scan(&date)
+ if err != nil {
+ log.Println("rows.Scan failed", err)
+ return messageData, err
+ }
+
+ messageData.Date = append(messageData.Date, date)
+ messageData.Total += 1
+ }
+
+ if err := rows.Err(); err != nil {
+ log.Println("rows.Scan failed", err)
+ return messageData, err
+ }
+
+ _time = P.wechatGetLastMessageCreateTime(userName, index)
+ if -1 == _time {
+ log.Println("wechatGetLastMessageCreateTime failed")
+ return messageData, errors.New("wechatGetLastMessageCreateTime failed")
+ }
+
+ _time -= 1
+ }
+}
+
+func (P *WechatDataProvider) WeChatGetChatRoomUserList(chatroom string) (*WeChatUserList, error) {
+ userList := &WeChatUserList{}
+ userList.Users = make([]WeChatUserInfo, 0)
+ userList.Total = 0
+
+ sqlFormat := "select UserNameList from ChatRoom where ChatRoomName='%s';"
+ querySql := fmt.Sprintf(sqlFormat, chatroom)
+
+ var userNameListStr string
+ err := P.microMsg.QueryRow(querySql).Scan(&userNameListStr)
+ if err != nil {
+ log.Println("Scan: ", err)
+ return nil, err
+ }
+
+ userNameArray := strings.Split(userNameListStr, "^G")
+ log.Println("userNameArray:", userNameArray)
+
+ for _, userName := range userNameArray {
+ pinfo, err := P.WechatGetUserInfoByNameOnCache(userName)
+ if err == nil {
+ userList.Users = append(userList.Users, *pinfo)
+ userList.Total += 1
+ }
+ }
+
+ return userList, nil
+}
+
+func (info WeChatUserInfo) String() string {
+ return fmt.Sprintf("NickName:[%s] Alias:[%s], NickName:[%s], ReMark:[%s], SmallHeadImgUrl:[%s], BigHeadImgUrl[%s]",
+ info.NickName, info.Alias, info.NickName, info.ReMark, info.SmallHeadImgUrl, info.BigHeadImgUrl)
+}
+
+func (P *WechatDataProvider) wechatMessageExtraHandle(msg *WeChatMessage) {
+ var extra MessageBytesExtra
+ err := proto.Unmarshal(msg.bytesExtra, &extra)
+ if err != nil {
+ log.Println("proto.Unmarshal failed", err)
+ return
+ }
+
+ for _, ext := range extra.Message2 {
+ switch ext.Field1 {
+ case 1:
+ if msg.IsChatRoom {
+ msg.Talker = ext.Field2
+ }
+ case 3:
+ if len(ext.Field2) > 0 && (msg.Type == Wechat_Message_Type_Picture || msg.Type == Wechat_Message_Type_Video || msg.Type == Wechat_Message_Type_Misc) {
+ msg.ThumbPath = P.resPath + ext.Field2[len(P.SelfInfo.UserName):]
+ }
+ case 4:
+ if len(ext.Field2) > 0 {
+ if msg.Type == Wechat_Message_Type_Misc && msg.SubType == Wechat_Misc_Message_File {
+ msg.FileInfo.FilePath = P.resPath + ext.Field2[len(P.SelfInfo.UserName):]
+ msg.FileInfo.FileName = filepath.Base(ext.Field2)
+ } else if msg.Type == Wechat_Message_Type_Picture || msg.Type == Wechat_Message_Type_Video || msg.Type == Wechat_Message_Type_Misc {
+ msg.ImagePath = P.resPath + ext.Field2[len(P.SelfInfo.UserName):]
+ msg.VideoPath = P.resPath + ext.Field2[len(P.SelfInfo.UserName):]
+ }
+ }
+ }
+ }
+
+ if msg.Type == Wechat_Message_Type_Voice {
+ msg.VoicePath = fmt.Sprintf("%s\\FileStorage\\Voice\\%d.mp3", P.resPath, msg.MsgSvrId)
+ }
+}
+
+type EmojiMsg struct {
+ XMLName xml.Name `xml:"msg"`
+ Emoji Emoji `xml:"emoji"`
+}
+
+type Emoji struct {
+ XMLName xml.Name `xml:"emoji"`
+ CdnURL string `xml:"cdnurl,attr"`
+ Thumburl string `xml:"thumburl,attr"`
+ Width string `xml:"width,attr"`
+ Height string `xml:"height,attr"`
+}
+
+func (P *WechatDataProvider) wechatMessageEmojiHandle(msg *WeChatMessage) {
+ if msg.Type != Wechat_Message_Type_Emoji {
+ return
+ }
+
+ emojiMsg := EmojiMsg{}
+ err := xml.Unmarshal([]byte(msg.Content), &emojiMsg)
+ if err != nil {
+ log.Println("xml.Unmarshal failed: ", err, msg.Content)
+ return
+ }
+
+ msg.EmojiPath = emojiMsg.Emoji.CdnURL
+}
+
+type xmlDocument struct {
+ *etree.Document
+}
+
+func NewxmlDocument(e *etree.Document) *xmlDocument {
+ return &xmlDocument{e}
+}
+
+func (e *xmlDocument) FindElementValue(path string) string {
+ item := e.FindElement(path)
+ if item != nil {
+ return item.Text()
+ }
+
+ return ""
+}
+
+func (P *WechatDataProvider) wechatMessageCompressContentHandle(msg *WeChatMessage) {
+ if len(msg.compressContent) == 0 {
+ return
+ }
+
+ unCompressContent := make([]byte, len(msg.compressContent)*10)
+ ulen, err := lz4.UncompressBlock(msg.compressContent, unCompressContent)
+ if err != nil {
+ log.Println("UncompressBlock failed:", err, msg.MsgSvrId)
+ return
+ }
+
+ compMsg := etree.NewDocument()
+ if err := compMsg.ReadFromBytes(unCompressContent[:ulen-1]); err != nil {
+ // os.WriteFile("D:\\tmp\\"+string(msg.LocalId)+".xml", unCompressContent[:ulen], 0600)
+ log.Println("ReadFromBytes failed:", err)
+ return
+ }
+
+ root := NewxmlDocument(compMsg)
+ if msg.Type == Wechat_Message_Type_Misc && msg.SubType == Wechat_Misc_Message_CardLink {
+ msg.LinkInfo.Title = root.FindElementValue("/msg/appmsg/title")
+ msg.LinkInfo.Description = root.FindElementValue("/msg/appmsg/des")
+ msg.LinkInfo.Url = root.FindElementValue("/msg/appmsg/url")
+ msg.LinkInfo.DisPlayName = root.FindElementValue("/msg/appmsg/sourcedisplayname")
+ appName := root.FindElementValue("/msg/appinfo/appname")
+ if len(msg.LinkInfo.DisPlayName) == 0 && len(appName) > 0 {
+ msg.LinkInfo.DisPlayName = appName
+ }
+ } else if msg.Type == Wechat_Message_Type_Misc && msg.SubType == Wechat_Misc_Message_Refer {
+ msg.Content = root.FindElementValue("/msg/appmsg/title")
+ msg.ReferInfo.Type, _ = strconv.Atoi(root.FindElementValue("/msg/appmsg/refermsg/type"))
+ msg.ReferInfo.Svrid, _ = strconv.ParseInt(root.FindElementValue("/msg/appmsg/refermsg/svrid"), 10, 64)
+ msg.ReferInfo.Displayname = root.FindElementValue("/msg/appmsg/refermsg/displayname")
+ msg.ReferInfo.Content = root.FindElementValue("/msg/appmsg/refermsg/content")
+
+ if msg.ReferInfo.Type == Wechat_Message_Type_Misc {
+ contentXML := etree.NewDocument()
+ if err := contentXML.ReadFromString(msg.ReferInfo.Content); err != nil {
+ log.Println("ReadFromString failed:", err)
+ return
+ }
+
+ root := NewxmlDocument(contentXML)
+ msg.ReferInfo.Content = root.FindElementValue("/msg/appmsg/title")
+ msg.ReferInfo.SubType, _ = strconv.Atoi(root.FindElementValue("/msg/appmsg/type"))
+ }
+ }
+}
+
+func (P *WechatDataProvider) wechatMessageGetUserInfo(msg *WeChatMessage) {
+ who := msg.Talker
+ if msg.IsSender == 1 {
+ who = P.SelfInfo.UserName
+ }
+
+ pinfo, err := P.WechatGetUserInfoByNameOnCache(who)
+ if err != nil {
+ log.Println("WechatGetUserInfoByNameOnCache:", err)
+ return
+ }
+
+ msg.UserInfo = *pinfo
+}
+
+func (P *WechatDataProvider) wechatFindDBIndex(userName string, time int64, direction Message_Search_Direction) int {
+ if direction == Message_Search_Forward {
+ index := 0
+ for {
+ if index >= len(P.msgDBs) {
+ return -1
+ }
+ msgDB := P.msgDBs[index]
+
+ if msgDB.startTime > time {
+ index += 1
+ continue
+ }
+
+ rowId := 0
+ querySql := fmt.Sprintf("select rowid from Name2ID where UsrName='%s';", userName)
+ err := msgDB.db.QueryRow(querySql).Scan(&rowId)
+ if err != nil {
+ log.Printf("Scan: %v\n", err)
+ index += 1
+ continue
+ }
+
+ querySql = fmt.Sprintf(" select rowid from MSG where StrTalker='%s' AND CreateTime<=%d limit 1;", userName, time)
+ log.Printf("in %s, %s\n", msgDB.path, querySql)
+ err = msgDB.db.QueryRow(querySql).Scan(&rowId)
+ if err != nil {
+ log.Printf("Scan: %v\n", err)
+ index += 1
+ continue
+ }
+
+ log.Printf("Select in %d %s\n", index, msgDB.path)
+ return index
+ }
+ } else {
+ index := len(P.msgDBs) - 1
+ for {
+ if index < 0 {
+ return -1
+ }
+ msgDB := P.msgDBs[index]
+
+ if msgDB.endTime < time {
+ index -= 1
+ continue
+ }
+
+ rowId := 0
+ querySql := fmt.Sprintf("select rowid from Name2ID where UsrName='%s';", userName)
+ err := msgDB.db.QueryRow(querySql).Scan(&rowId)
+ if err != nil {
+ log.Printf("Scan: %v\n", err)
+ index -= 1
+ continue
+ }
+
+ querySql = fmt.Sprintf(" select rowid from MSG where StrTalker='%s' AND CreateTime>%d limit 1;", userName, time)
+ log.Printf("in %s, %s\n", msgDB.path, querySql)
+ err = msgDB.db.QueryRow(querySql).Scan(&rowId)
+ if err != nil {
+ log.Printf("Scan: %v\n", err)
+ index -= 1
+ continue
+ }
+
+ log.Printf("Select in %d %s\n", index, msgDB.path)
+ return index
+ }
+ }
+}
+
+func (P *WechatDataProvider) wechatGetLastMessageCreateTime(userName string, index int) int64 {
+ if index >= len(P.msgDBs) {
+ return -1
+ }
+ sqlFormat := "SELECT CreateTime FROM MSG WHERE StrTalker='%s' order by CreateTime asc limit 1;"
+ querySql := fmt.Sprintf(sqlFormat, userName)
+ var lastTime int64
+ err := P.msgDBs[index].db.QueryRow(querySql).Scan(&lastTime)
+ if err != nil {
+ log.Println("select DB lastTime failed:", index, ":", err)
+ return -1
+ }
+
+ return lastTime
+}
+
+func weChatMessageContains(msg *WeChatMessage, chars string) bool {
+
+ switch msg.Type {
+ case Wechat_Message_Type_Text:
+ return strings.Contains(msg.Content, chars)
+ case Wechat_Message_Type_Misc:
+ switch msg.SubType {
+ case Wechat_Misc_Message_CardLink:
+ return strings.Contains(msg.LinkInfo.Title, chars) || strings.Contains(msg.LinkInfo.Description, chars)
+ case Wechat_Misc_Message_Refer:
+ return strings.Contains(msg.Content, chars)
+ case Wechat_Misc_Message_File:
+ return strings.Contains(msg.FileInfo.FileName, chars)
+ default:
+ return false
+ }
+ default:
+ return false
+ }
+}
+
+func weChatMessageTypeFilter(msg *WeChatMessage, msgType string) bool {
+ switch msgType {
+ case "":
+ return true
+ case "文件":
+ return msg.Type == Wechat_Message_Type_Misc && msg.SubType == Wechat_Misc_Message_File
+ case "图片与视频":
+ return msg.Type == Wechat_Message_Type_Picture || msg.Type == Wechat_Message_Type_Video
+ case "链接":
+ return msg.Type == Wechat_Misc_Message_CardLink || msg.SubType == Wechat_Misc_Message_CardLink
+ default:
+ if strings.HasPrefix(msgType, "群成员") {
+ userName := msgType[len("群成员"):]
+ return msg.UserInfo.UserName == userName
+ }
+
+ return false
+ }
+}
+
+func wechatOpenMsgDB(path string) (*wechatMsgDB, error) {
+ msgDB := wechatMsgDB{}
+
+ db, err := sql.Open("sqlite3", path)
+ if err != nil {
+ log.Printf("open db %s error: %v", path, err)
+ return nil, err
+ }
+ msgDB.db = db
+ msgDB.path = path
+ querySql := "select CreateTime from MSG order by CreateTime asc limit 1;"
+ err = msgDB.db.QueryRow(querySql).Scan(&msgDB.startTime)
+ if err != nil {
+ log.Println("select DB startTime failed:", path, ":", err)
+ return nil, err
+ }
+
+ querySql = "select CreateTime from MSG order by CreateTime desc limit 1;"
+ err = msgDB.db.QueryRow(querySql).Scan(&msgDB.endTime)
+ if err != nil {
+ log.Println("select DB endTime failed:", path, ":", err)
+ return nil, err
+ }
+
+ return &msgDB, nil
+}
+
+func (P *WechatDataProvider) WechatGetUserInfoByNameOnCache(name string) (*WeChatUserInfo, error) {
+
+ // log.Printf("who: %s", who)
+
+ P.userInfoMtx.Lock()
+ defer P.userInfoMtx.Unlock()
+
+ info, ok := P.userInfoMap[name]
+ if ok {
+ return &info, nil
+ }
+
+ pinfo, err := P.WechatGetUserInfoByName(name)
+ if err != nil {
+ log.Printf("WechatGetUserInfoByName %s failed: %v\n", name, err)
+ return nil, err
+ }
+
+ P.userInfoMap[name] = *pinfo
+
+ return pinfo, nil
+}
diff --git a/pkg/wechat/wechatIMGDec.go b/pkg/wechat/wechatIMGDec.go
new file mode 100644
index 0000000..5f246e5
--- /dev/null
+++ b/pkg/wechat/wechatIMGDec.go
@@ -0,0 +1,209 @@
+package wechat
+
+import (
+ "bufio"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "sync"
+ "time"
+)
+
+/*
+ from: https://github.com/liuggchen/wechatDatDecode.git
+*/
+
+var imagePrefixBtsMap = make(map[string][]byte)
+
+func DecryptDatByDir(inDir, outDir string) error {
+
+ startTime := time.Now()
+ f, er := os.Open(inDir)
+ if er != nil {
+ fmt.Println(er.Error())
+ return er
+ }
+ readdir, er := f.Readdir(0)
+ if er != nil {
+ fmt.Println(er.Error())
+ }
+
+ if stat, er := os.Stat(outDir); os.IsNotExist(er) {
+ er := os.MkdirAll(outDir, 0755)
+ if er != nil {
+ return er
+ }
+ } else if !stat.IsDir() {
+ return errors.New(outDir + "is file")
+ }
+
+ var taskChan = make(chan os.FileInfo, 100)
+
+ go func() {
+ for _, info := range readdir {
+ taskChan <- info
+ }
+ close(taskChan)
+ }()
+
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for info := range taskChan {
+ handlerOne(info, inDir, outDir)
+ }
+ }()
+ }
+
+ wg.Wait()
+ t := time.Since(startTime).Seconds()
+ log.Printf("\nfinished time= %v s\n", t)
+
+ return nil
+}
+
+func DecryptDat(inFile string, outFile string) error {
+
+ sourceFile, err := os.Open(inFile)
+ if err != nil {
+ log.Println(err.Error())
+ return err
+ }
+
+ var preTenBts = make([]byte, 10)
+ _, _ = sourceFile.Read(preTenBts)
+ decodeByte, _, er := findDecodeByte(preTenBts)
+ if er != nil {
+ log.Println(er.Error())
+ return err
+ }
+
+ distFile, er := os.Create(outFile)
+ if er != nil {
+ log.Println(er.Error())
+ return err
+ }
+ writer := bufio.NewWriter(distFile)
+ _, _ = sourceFile.Seek(0, 0)
+ var rBts = make([]byte, 1024)
+ for {
+ n, er := sourceFile.Read(rBts)
+ if er != nil {
+ if er == io.EOF {
+ break
+ }
+ log.Println("error: ", er.Error())
+ return err
+ }
+ for i := 0; i < n; i++ {
+ _ = writer.WriteByte(rBts[i] ^ decodeByte)
+ }
+ }
+ _ = writer.Flush()
+ _ = distFile.Close()
+ _ = sourceFile.Close()
+ // fmt.Println("output file:", distFile.Name())
+
+ return nil
+}
+
+func handlerOne(info os.FileInfo, dir string, outputDir string) {
+ if info.IsDir() || filepath.Ext(info.Name()) != ".dat" {
+ return
+ }
+ fmt.Println("find file: ", info.Name())
+ fPath := dir + "/" + info.Name()
+ sourceFile, err := os.Open(fPath)
+ if err != nil {
+ fmt.Println(err.Error())
+ return
+ }
+
+ var preTenBts = make([]byte, 10)
+ _, _ = sourceFile.Read(preTenBts)
+ decodeByte, _, er := findDecodeByte(preTenBts)
+ if er != nil {
+ fmt.Println(er.Error())
+ return
+ }
+
+ distFile, er := os.Create(outputDir + "/" + info.Name())
+ if er != nil {
+ fmt.Println(er.Error())
+ return
+ }
+ writer := bufio.NewWriter(distFile)
+ _, _ = sourceFile.Seek(0, 0)
+ var rBts = make([]byte, 1024)
+ for {
+ n, er := sourceFile.Read(rBts)
+ if er != nil {
+ if er == io.EOF {
+ break
+ }
+ fmt.Println("error: ", er.Error())
+ return
+ }
+ for i := 0; i < n; i++ {
+ _ = writer.WriteByte(rBts[i] ^ decodeByte)
+ }
+ }
+ _ = writer.Flush()
+ _ = distFile.Close()
+
+ fmt.Println("output file:", distFile.Name())
+}
+
+func init() {
+ //JPEG (jpg),文件头:FFD8FF
+ //PNG (png),文件头:89504E47
+ //GIF (gif),文件头:47494638
+ //TIFF (tif),文件头:49492A00
+ //Windows Bitmap (bmp),文件头:424D
+ const (
+ Jpeg = "FFD8FF"
+ Png = "89504E47"
+ Gif = "47494638"
+ Tif = "49492A00"
+ Bmp = "424D"
+ )
+ JpegPrefixBytes, _ := hex.DecodeString(Jpeg)
+ PngPrefixBytes, _ := hex.DecodeString(Png)
+ GifPrefixBytes, _ := hex.DecodeString(Gif)
+ TifPrefixBytes, _ := hex.DecodeString(Tif)
+ BmpPrefixBytes, _ := hex.DecodeString(Bmp)
+
+ imagePrefixBtsMap = map[string][]byte{
+ ".jpeg": JpegPrefixBytes,
+ ".png": PngPrefixBytes,
+ ".gif": GifPrefixBytes,
+ ".tif": TifPrefixBytes,
+ ".bmp": BmpPrefixBytes,
+ }
+}
+
+func findDecodeByte(bts []byte) (byte, string, error) {
+ for ext, prefixBytes := range imagePrefixBtsMap {
+ deCodeByte, err := testPrefix(prefixBytes, bts)
+ if err == nil {
+ return deCodeByte, ext, err
+ }
+ }
+ return 0, "", errors.New("decode fail")
+}
+
+func testPrefix(prefixBytes []byte, bts []byte) (deCodeByte byte, error error) {
+ var initDecodeByte = prefixBytes[0] ^ bts[0]
+ for i, prefixByte := range prefixBytes {
+ if b := prefixByte ^ bts[i]; b != initDecodeByte {
+ return 0, errors.New("no")
+ }
+ }
+ return initDecodeByte, nil
+}
diff --git a/res/result.png b/res/result.png
new file mode 100644
index 0000000..3044ff3
Binary files /dev/null and b/res/result.png differ
diff --git a/res/tips.png b/res/tips.png
new file mode 100644
index 0000000..a774247
Binary files /dev/null and b/res/tips.png differ
diff --git a/wails.json b/wails.json
new file mode 100644
index 0000000..52d9021
--- /dev/null
+++ b/wails.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://wails.io/schemas/config.v2.json",
+ "name": "wechatDataBackup",
+ "outputfilename": "wechatDataBackup",
+ "frontend:install": "",
+ "frontend:build": "",
+ "frontend:dev:watcher": "",
+ "frontend:dev:serverUrl": "",
+ "author": {
+ "name": "hal",
+ "email": "1174221722@qq.com"
+ }
+}