"""Small explicit MFCC-style recipe: own DFT, HTK mel grid, peak triangles,
10log10 power ref=1 floor1e-10, no top-dB clipping, orthonormal DCT-II.
No librosa, speech recognizer or voice-identification model runs here.
"""
import cmath,math,json
RATE=8000;N=64;HOP=32;BANDS=6;COEFFS=3
def hzmel(f):return 2595*math.log10(1+f/700)
def melhz(m):return 700*(10**(m/2595)-1)
def recipe(samples):
    edges=[melhz(hzmel(RATE/2)*i/(BANDS+1)) for i in range(BANDS+2)]
    freq=[RATE*k/N for k in range(N//2+1)]
    bank=[[max(0.,min((f-a)/(b-a),(c-f)/(c-b))) for f in freq] for a,b,c in zip(edges,edges[1:],edges[2:])]
    assert all(sum(row)>0 for row in bank)
    out=[];traces=[]
    for start in range(0,len(samples)-N+1,HOP):
        x=[samples[start+t]*(.5-.5*math.cos(2*math.pi*t/(N-1))) for t in range(N)]
        spec=[sum(v*cmath.exp(-2j*math.pi*k*t/N) for t,v in enumerate(x)) for k in range(N//2+1)]
        power=[abs(z)**2 for z in spec];mel=[sum(w*p for w,p in zip(row,power)) for row in bank]
        log=[10*math.log10(max(v,1e-10)) for v in mel]
        coeff=[math.sqrt((1 if k==0 else 2)/BANDS)*sum(v*math.cos(math.pi*k*(m+.5)/BANDS) for m,v in enumerate(log)) for k in range(COEFFS)]
        assert all(math.isfinite(v) for v in coeff)
        out.append(coeff);traces.append({'start_sample':start,'mel_power':mel,'log_power_db_ref1':log,'coefficients':coeff})
    return {'edges_hz':edges,'mel_filter_matrix_shape':[BANDS,N//2+1],'frame_major_shape':[len(out),COEFFS],'coeff_major_shape':[COEFFS,len(out)],'frames':traces}
def demo():
    x=[math.sin(2*math.pi*500*t/RATE)+.25*math.sin(2*math.pi*1500*t/RATE) for t in range(128)]
    result=recipe(x);silent=recipe([0.]*128)
    assert result['frame_major_shape']==[3,3] and [r['start_sample'] for r in result['frames']]==[0,32,64]
    assert all(v==-100. for r in silent['frames'] for v in r['log_power_db_ref1'])
    assert abs(silent['frames'][0]['coefficients'][0]+100*math.sqrt(6))<1e-10
    return {'input':'128 owned synthetic samples, not speech','rate_hz':RATE,'window_samples':N,'hop_samples':HOP,'center_padding':False,'window':'symmetric Hann N-1','mel_scale':'HTK','triangle_area_normalization':False,'power_db_floor':1e-10,'top_db_clipping':None,'DCT_type':2,'DCT_norm':'ortho','recipe':result,'silence':silent,'librosa_executed':False,'text_or_speaker_identity_decoded':False}
if __name__=='__main__':print(json.dumps(demo(),ensure_ascii=False,indent=2))
