Python u-Law (MULAW) wave decompression to raw wave signal

u-law codec
u-law format
u law and a law companding ques10
python wave
mu-law companding example
using wave in python
convert ulaw to pcm
audio compression in python

I googled this issue for last 2 weeks and wasn't able to find an algorithm or solution. I have some short .wav file but it has MULAW compression and python doesn't seem to have function inside wave.py that can successfully decompresses it. So I've taken upon myself to build a decoder in python.

I've found some info about MULAW in basic elements:

  1. Wikipedia
  2. A-law u-Law comparison
  3. Some c-esc codec library

So I need some guidance, since I don't know how to approach getting from signed short integer to a full wave signal. This is my initial thought from what I've gathered so far:


So from wiki I've got a equation for u-law compression and decompression :

compression :

decompression :

So judging by compression equation, it looks like the output is limited to a float range of -1 to +1 , and with signed short integer from –32,768 to 32,767 so it looks like I would need to convert it from short int to float in specific range.

Now, to be honest, I've heard of quantisation before, but I am not sure if I should first try and dequantize and then decompress or in the other way, or even if in this case it is the same thing... the tutorials/documentation can be a bit of tricky with terminology.

The wave file I am working with is supposed to contain 'A' sound like for speech synthesis, I could probably verify success by comparing 2 waveforms in some audio software and custom wave analyzer but I would really like to diminish trial and error section of this process.

So what I've had in mind:

u = 0xff
data_chunk = b'\xe7\xe7' # -6169
data_to_r1 = unpack('h',data_chunk)[0]/0xffff # I suspect this is wrong,
#                                             # but I don't know what else

u_law = ( -1 if data_chunk<0 else 1 )*( pow( 1+u, abs(data_to_r1)) -1 )/u   

So is there some sort of algorithm or crucial steps I would need to take in form of first: decompression, second: quantisation : third ? Since everything I find on google is how to read a .wav PCM-modulated file type, not how to manage it if wild compression arises.

So, after scouring the google the solution was found in github ( go figure ). I've searched for many many algorithms and found 1 that is within bounds of error for lossy compression. Which is for u law for positive values from 30 -> 1 and for negative values from -32 -> -1

To be honest i think this solution is adequate but not quite per equation per say, but it is best solution for now. This code is transcribed to python directly from gcc9108 audio codec

def uLaw_d(i8bit):
    bias = 33
    sign = pos = 0
    decoded = 0

    i8bit = ~i8bit
    if i8bit&0x80:
        i8bit &= ~(1<<7)
        sign = -1

    pos = ( (i8bit&0xf0) >> 4 ) + 5
    decoded = ((1 << pos) | ((i8bit & 0x0F) << (pos - 4)) | (1 << (pos - 5))) - bias
    return decoded if sign else ~decoded

def uLaw_e(i16bit):
    MAX = 0x1fff
    BIAS = 33
    mask = 0x1000
    sign = lsb = 0
    pos = 12 

    if i16bit < 0:
        i16bit = -i16bit
        sign = 0x80

    i16bit += BIAS

    if ( i16bit>MAX ): i16bit = MAX 

    for x in reversed(range(pos)):
        if i16bit&mask != mask and pos>=5:
            pos = x
            break

    lsb = ( i16bit>>(pos-4) )&0xf
    return ( ~( sign | ( pos<<4 ) | lsb ) )

With test:

print( 'normal :\t{0}\t|\t{0:2X}\t:\t{0:016b}'.format(0xff) )
print( 'encoded:\t{0}\t|\t{0:2X}\t:\t{0:016b}'.format(uLaw_e(0xff)) )
print( 'decoded:\t{0}\t|\t{0:2X}\t:\t{0:016b}'.format(uLaw_d(uLaw_e(0xff))) )

and output:

normal :    255     |   FF  :   0000000011111111
encoded:    -179    |   -B3 :   -000000010110011
decoded:    263     |   107 :   0000000100000111

And as you can see 263-255 = 8 which is within bounds. When i tried to implement seeemmmm method described in G.711 ,that kind user Oliver Charlesworth suggested that i look in to , the decoded value for maximum in data was -8036 which is close to the maximum of uLaw spec, but i couldn't reverse engineer decoding function to get binary equivalent of function from wikipedia.

Lastly, i must say that i am currently disappointed that python library doesn't support all kind of compression algorithms since it is not just a tool that people use, it is also a resource python consumers learn from since most of data for further dive into code isn't readily available or understandable.


EDIT

After decoding the data and writing wav file via wave.py i've successfully succeeded to write a new raw linear PCM file. This works... even though i was sceptical at first.


EDIT 2: ::> you can find real solution oncompressions.py


Newest 'pcm+python' Questions, Python u-Law (MULAW) wave decompression to raw wave signal. I googled this issue for last 2 weeks and wasn't able to find an algorithm or solution. Mu-law (also “u-law”) encoding is a form of logarithmic quantization or companding. It’s based on the observation that many signals are statistically more likely to be near a low signal level than a high signal level. Therefore, it makes more sense to have more quantization points near a low level than a high level.

Python actually supports decoding u-Law out of the box:

audioop.ulaw2lin(fragment, width)

Convert sound fragments in u-LAW encoding to linearly encoded sound fragments. u-LAW encoding always uses 8 bits samples, so width refers only to the sample width of the output fragment here.

https://docs.python.org/3/library/audioop.html#audioop.ulaw2lin

Introduction to audio encoding, Digital audio encoding is a complex topic, and you generally don't need to Note: Speech-to-Text supports WAV files with LINEAR16 or MULAW encoded audio. twice the highest frequency of any sound wave you wish to capture digitally. bit LINEAR16 (uncompressed PCM) is still far superior to 8 bit uLaw compressed  Extracting raw audio/waveform from an MP3. Python library to modify MP3 audio without transcoding. 12. Python u-Law (MULAW) wave decompression to raw wave

I find this helpful for converting to/from ulaw with numpy arrays.

import audioop

def numpy_audioop_helper(x, xdtype, func, width, ydtype):
    '''helper function for using audioop buffer conversion in numpy'''
    xi = np.asanyarray(x).astype(xdtype)
    if np.any(x != xi):
        xinfo = np.iinfo(xdtype)
        raise ValueError("input must be %s [%d..%d]" % (xdtype, xinfo.min, xinfo.max))
    y = np.frombuffer(func(xi.tobytes(), width), dtype=ydtype)
    return y.reshape(xi.shape)

def audioop_ulaw_compress(x):
    return numpy_audioop_helper(x, np.int16, audioop.lin2ulaw, 2, np.uint8)

def audioop_ulaw_expand(x):
    return numpy_audioop_helper(x, np.uint8, audioop.ulaw2lin, 2, np.int16)

μ-law algorithm, The μ-law algorithm is a companding algorithm, primarily used in 8-bit PCM digital Companding algorithms reduce the dynamic range of an audio signal. of implementation; A-Law and mu-Law Companding Implementations Using the TMS320C54x By using this site, you agree to the Terms of Use and Privacy Policy. 3 Python - UnboundLocalError: local variable “ID” referenced before assignment Apr 20 '18 2 Python u-Law (MULAW) wave decompression to raw wave signal May 2 '18 2 Keyword arguments aliases in python Jan 21 '17

audioop — Manipulate raw audio data, This module provides support for a-LAW, u-LAW and Intel/DVI ADPCM encodings. Convert sound fragments in a-LAW encoding to linearly encoded sound fragments. a-LAW encoding This is a measure of the power in an audio signal. Python u-law issues: unknown format: 7 python , numpy , format , fft , wav From the documentation (emphasis mine): The wave module provides a convenient interface to the WAV sound format.

Convert wav to pcm python, Signed 16 bit Little Endian, Rate 44100Hz, Stereo The canonical WAVE format That's why it's a good idea to decompress your FLAC files and save them in a more your audio file for Cisco Phone Systems to a CCITT 8khz 8 bit mono u-​law. Here an example using SoX to convert a RAW G711A file to PCM ALAW WAV  21.1. audioop — Manipulate raw audio data¶. The audioop module contains some useful operations on sound fragments. It operates on sound fragments consisting of signed integer samples 8, 16 or 32 bits wide, stored in Python strings. This is the same format as used by the al and sunaudiodev modules.

How is it possible to convert sound as a binary wave and then again , It can be compressed by A or u law to 8 bit per sample. This if you To make a sound to the binary form, you have to quantify the sound signal form. The more  > > Can any one tell me the wave header for > > mu-law and A-law. I have a wave file which is mu-law > > 8-bit mono which has 56 bytes as header. I want to > > know in what format are these bytes arranged. The > > following 56 byte header is provided for reference. > > > > 52 49 46 46 6C 17 00 00 57 41 56 45 66 6D 74 20

Comments
  • Take a look at G.711 for a practical example of a codec that's based on this.
  • What are lseg, linbuf, logbuf ?
  • it does but only if file you would like to read has a simple compression flag. I got mp3 file with compression flag for mulaw, but python wouldn't recognize it. So it doesn't work on everything.
  • to be honest. Never used numpy or pycharm or anything that is extending python. The reason why i needed to do this isn't the conversion or data handling. It is mp3/wav compression ( among other ) flag recognition. Python has some bugs with limited flags, if the file is written with generic, standard and wide used flags python has no issue loading it, but if the file is written with other it raises an error...so you would need to read binary structure and decompress ulaw by yourself then.