"""Small PCMU/PCMA mapping exercise. No audioop import, RTP parser or ASR."""
import struct,json
def ulaw(v):
    u=v^255;mag=(((u&15)<<3)+132)<<((u>>4)&7);mag-=132
    return -mag if u&128 else mag
def alaw(v):
    a=v^85;segment=(a>>4)&7
    magnitude=((a&15)<<4)+(8 if segment==0 else 264)
    if segment>1:magnitude<<=segment-1
    return magnitude if a&128 else -magnitude
def decode(raw,codec,rate=8000,channels=1):
    if not isinstance(raw,bytes) or not raw:raise ValueError('nonempty authored raw bytes required')
    if codec not in ('PCMU','PCMA') or type(rate) is not int or rate!=8000 or type(channels) is not int or channels!=1:raise ValueError('explicit PCMU/PCMA, 8000 Hz, mono required')
    values=[(ulaw if codec=='PCMU' else alaw)(v) for v in raw]
    return values,b''.join(struct.pack('<h',v) for v in values)
if __name__=='__main__':
    known_u={0: -32124,127:0,128:32124,255:0}
    known_a={0:-5504,127:-848,128:5504,255:848,213:8,85:-8,170:32256,42:-32256}
    assert all(ulaw(k)==v for k,v in known_u.items()) and all(alaw(k)==v for k,v in known_a.items())
    assert all(-32768<=f(x)<=32767 for f in (ulaw,alaw) for x in range(256))
    raw=bytes([0,127,128,255]);u,upcm=decode(raw,'PCMU');a,apcm=decode(raw,'PCMA')
    assert struct.unpack('<4h',upcm)==tuple(u) and u!=a
    silence,pcm=decode(bytes([255])*160,'PCMU');assert len(silence)==160 and len(pcm)==320 and set(silence)=={0}
    for args in [('PCM16',8000,1),('PCMU',16000,1),('PCMA',8000,2)]:
        try:decode(raw,*args)
        except ValueError:pass
        else:raise AssertionError('unsupported format accepted')
    print(json.dumps({'authored_raw_hex':raw.hex(),'PCMU_PCM16_values':u,'PCMA_PCM16_values':a,'PCM16_output_byteorder':'little','known_answer_checks':12,'range_checks':512,'twenty_ms_input_octets':160,'twenty_ms_decoded_PCM16_bytes':320,'decoded_frames':160,'duration_seconds':160/8000,'encoded_bitrate_bits_per_second':8000*8,'input_silence_tested_as_numbers_not_listened':True,'audioop_imported':False,'RTP_or_ASR_run':False},indent=2))
