2010-02-22 24 views
5

¿Cómo llego al máximo firmado entero corto en Python (es decir SHRT_MAX en limits.h de C) ?máximo número entero corto con signo en Python

Quiero normalizar muestras de un solo canal de un archivo *.wav, así que en lugar de un montón de enteros con signo de 16 bits, quiero un conjunto de flotantes entre 1 y -1. Esto es lo que tengo (el código pertinente es en la función normalized_samples()):

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(clip, chan_no = 0): 
    for sample in samples(clip, chan_no): 
     yield float(sample)/float(32767) ### THIS IS WHERE I NEED HELP 
+2

Si son muestras de 16 bits, entonces las divide por 32768, sin importar el tamaño del entero más grande. python tiene solo dos tipos de enteros hasta la versión 3, un int de tamaño limitado "regular" y un binint ilimitado. No hay un tipo corto de int. –

Respuesta

1

en módulo sys, sys.maxint. Aunque no estoy seguro de que sea la forma correcta de resolver tu problema.

+0

¿Lo dividirías por sys.maxint ???? –

2

GregS tiene razón, esta no es la manera correcta de resolver el problema. Si sus muestras son conocidas de 8 o 16 bits, no desea dividirlas por un número que varía según la plataforma.

Es posible que tenga problemas porque un int. Firmado de 16 bits en realidad va de -32768 a 32767. Dividir por 32767 le dará < -1 en el caso extremo negativo.

Prueba esto:

flotador rendimiento (muestra + 2 ** 15)/2 ** 15-1,0

1

Aquí está una manera utilizando 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 
1

No puedo imaginar las circunstancias en una computadora moderna (es decir uno que utiliza de 2 enteros del complemento) donde esto sería un fracaso:

assert -32768 <= signed_16_bit_integer <= 32767 

para hacer exactamente lo que pidieron:

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

Después de leer el código de un poco más de cerca: usted tiene sample_width_in_bytes por lo que sólo se dividen por 255 o 256 si es B y 32768 si es h

Cuestiones relacionadas