Найдите максимальное короткое целое со знаком в Python

Как я получаю максимальное короткое целое со знаком в Python (т.е. SHRT_MAX в C limits.h)?

Я хочу нормализовать образцы от одного канала a *.wav файл, таким образом, вместо набора 16-разрядных целых чисел со знаком, я хочу набор плаваний между 1 и-1. Вот то, что я имею (подходящий код находится в 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
5
задан aaronstacy 22 February 2010 в 01:12
поделиться

4 ответа

в модуле sys, sys.maxint. Хотя я не уверен, что это правильный способ решения вашей проблемы.

1
ответ дан 14 December 2019 в 13:34
поделиться

GregS прав, это не тот способ решения проблемы. Если ваши выборки известны в 8 или 16 бит, вы не хотите делить их на число, которое зависит от платформы.

Вы можете столкнуться с проблемой, потому что знаковое 16-битное число int на самом деле находится в диапазоне от -32768 до 32767. Деление на 32767 даст < -1 в крайнем отрицательном случае.

Попробуйте так:

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

2
ответ дан 14 December 2019 в 13:34
поделиться

Вот способ, использующий 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
2
ответ дан 14 December 2019 в 13:34
поделиться

Я не могу представить себе обстоятельства на современном компьютере (т.е. который использует 2's complement integers), где бы это не сработало:

assert -32768 <= signed_16_bit_integer <= 32767

Чтобы сделать именно то, что вы просили:

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

Прочитав ваш код немного внимательнее: у вас есть sample_width_in_bytes, поэтому просто разделите на 255 или 256, если это B и на 32768, если это h

1
ответ дан 14 December 2019 в 13:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: