开发者

Find maximum signed short integer in python

How do I get the maximum signed short integer in Python (i.e. SHRT_MAX in C's limits.h)?

I want to normalize samples from a single channel of a *.wav file, so instead of a bunch of 16-bit signed integers, I want a bunch of floats between 1 and -1. Here's what I've got (the pertinent code is in the normalized_samples() function):

def samples(clip, chan_no = 0):
    # *.wav files generally come in 8-bit unsigned ints or 16-bit signed ints
    # python's wave module gives sample width in bytes, so STRUCT_FMT
    # basically converts the wave.samplewidth into a struct fmt string
    STRUCT_FMT = {  1 : 'B',
                    2 : 'h' }

    for i in range(clip.getnframes()):
        yield struct.unpack(STRUCT_FMT[clip.getsampwidth()] * clip.getnchannels(), 
                clip.readframes(1))[chan_no]

def normalized_samples开发者_JS百科(clip, chan_no = 0):
    for sample in samples(clip, chan_no):
        yield float(sample) / float(32767) ### THIS IS WHERE I NEED HELP


GregS is right, this is not the right way to solve the problem. If your samples are known 8 or 16 bit, you don't want to be dividing them by a number that varies by platform.

You may be running into trouble because a signed 16-bit int actually ranges from -32768 to 32767. Dividing by 32767 is going to give you < -1 in the extreme negative case.

Try this:

yield float(sample + 2**15) / 2**15 - 1.0


Here is a way using cython

getlimit.py

import pyximport; pyximport.install()
import limits

print limits.shrt_max

limits.pyx

import cython
cdef extern from "limits.h":
    cdef int SHRT_MAX

shrt_max = SHRT_MAX


in module sys, sys.maxint. Though I'm not sure that is the correct way to solve your problem.


I can't imagine circumstances on a modern computer (i.e. one that uses 2's complement integers) where this would fail:

assert -32768 <= signed_16_bit_integer <= 32767

To do exactly what you asked for:

if signed_16_bit_integer >= 0:
    afloat = signed_16_bit_integer / 32767.0
else:
    afloat = signed_16_bit_integer / -32768.0

Having read your code a bit more closely: you have sample_width_in_bytes so just divide by 255 or 256 if it's B and by 32768 if it's h


#!/usr/bin/env python2

# maximums.py

####################################333#########################

B16_MAX = (1 << 16) - 1
B15_MAX = (1 << 15) - 1
B08_MAX = (1 <<  8) - 1
B07_MAX = (1 <<  7) - 1

print
print "hex(B16_MAX) =",hex(B16_MAX) # 0xffff
print "hex(B15_MAX) =",hex(B15_MAX) # 0x7fff
print "hex(B08_MAX) =",hex(B08_MAX) #   0xff
print "hex(B07_MAX) =",hex(B07_MAX) #   0x7f
print

####################################333#########################

UBYTE2_MAX = B16_MAX
SBYTE2_MAX = B15_MAX
UBYTE1_MAX = B08_MAX
SBYTE1_MAX = B07_MAX

print
print "UBYTE2_MAX =",UBYTE2_MAX # 65535
print "SBYTE2_MAX =",SBYTE2_MAX # 32767
print "UBYTE1_MAX =",UBYTE1_MAX #   255
print "SBYTE1_MAX =",SBYTE1_MAX #   127
print

####################################333#########################

USHRT_MAX = UBYTE2_MAX
SHRT_MAX  = SBYTE2_MAX
CHAR_MAX  = UBYTE1_MAX
BYTE_MAX  = SBYTE1_MAX

print
print "USHRT_MAX =",USHRT_MAX # 65535
print " SHRT_MAX =", SHRT_MAX # 32767
print " CHAR_MAX =", CHAR_MAX #   255
print " BYTE_MAX =", BYTE_MAX #   127
print

####################################333#########################
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜