mirror of
https://github.com/markqvist/LXST.git
synced 2026-04-27 14:20:39 +00:00
62 lines
No EOL
2 KiB
Python
62 lines
No EOL
2 KiB
Python
import numpy as np
|
|
from .libs.pydub import AudioSegment
|
|
|
|
TYPE_MAP_FACTOR = np.iinfo("int16").max
|
|
|
|
class Codec():
|
|
preferred_samplerate = None
|
|
frame_quanta_ms = None
|
|
frame_max_ms = None
|
|
valid_frame_ms = None
|
|
source = None
|
|
sink = None
|
|
|
|
class CodecError(Exception):
|
|
pass
|
|
|
|
class Null(Codec):
|
|
def __init__(self):
|
|
pass
|
|
|
|
def encode(self, frame):
|
|
return frame
|
|
|
|
def decode(self, frame):
|
|
return frame
|
|
|
|
def resample_bytes(sample_bytes, bitdepth, channels, input_rate, output_rate, normalize=False):
|
|
sample_width = bitdepth//8
|
|
audio = AudioSegment(
|
|
sample_bytes,
|
|
frame_rate=input_rate,
|
|
sample_width=sample_width,
|
|
channels=channels)
|
|
|
|
if normalize:
|
|
audio = audio.apply_gain(-audio.max_dBFS)
|
|
|
|
resampled_audio = audio.set_frame_rate(output_rate)
|
|
resampled_bytes = resampled_audio.get_array_of_samples().tobytes()
|
|
|
|
# rate_factor = input_rate/output_rate
|
|
# input_samples = int(len(sample_bytes)/channels/sample_width)
|
|
# output_samples = int(len(resampled_bytes)/channels/sample_width)
|
|
# target_samples = int(input_samples/rate_factor)
|
|
# if output_samples < target_samples:
|
|
# print("Mismatch")
|
|
# add_samples = int(target_samples-output_samples)
|
|
# fill = resampled_bytes[-sample_width:]*add_samples
|
|
# resampled_bytes += fill
|
|
|
|
return resampled_bytes
|
|
|
|
def resample(input_samples, bitdepth, channels, input_rate, output_rate, normalize=False):
|
|
sample_width = bitdepth//8
|
|
input_samples = input_samples*TYPE_MAP_FACTOR
|
|
input_samples = input_samples.astype(np.int16)
|
|
resampled_bytes = resample_bytes(input_samples.tobytes(), bitdepth, channels, input_rate, output_rate, normalize)
|
|
output_samples = np.frombuffer(resampled_bytes, dtype=np.int16)/TYPE_MAP_FACTOR
|
|
output_samples = output_samples.reshape(output_samples.shape[0]//channels, channels)
|
|
output_samples = output_samples.astype(np.float32)
|
|
|
|
return output_samples |