You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.8 KiB
Python
100 lines
2.8 KiB
Python
5 years ago
|
import logging
|
||
|
import shlex
|
||
|
import wave
|
||
|
from subprocess import PIPE, Popen
|
||
|
|
||
|
import numpy as np
|
||
|
|
||
|
ENCODINGS_MAPPING = {
|
||
|
np.int16: 's16',
|
||
|
np.float32: 'f32',
|
||
|
np.float64: 'f64',
|
||
|
}
|
||
|
|
||
|
PIPE_CHAR = '-'
|
||
|
|
||
|
logger = logging.getLogger('pysndfx')
|
||
|
|
||
|
|
||
|
class SoxInput(object):
|
||
|
pipe = '-'
|
||
|
|
||
|
def __init__(self):
|
||
|
self.cmd_prefix = None
|
||
|
|
||
|
|
||
|
class FilePathInput(SoxInput):
|
||
|
def __init__(self, filepath):
|
||
|
super(FilePathInput, self).__init__()
|
||
|
info_cmd = 'sox --i -c ' + filepath
|
||
|
logger.debug("Running info command : %s" % info_cmd)
|
||
|
stdout, stderr = Popen(shlex.split(info_cmd, posix=False), stdout=PIPE, stderr=PIPE).communicate()
|
||
|
self.channels = int(stdout)
|
||
|
self.cmd_prefix = filepath
|
||
|
|
||
|
|
||
|
class FileBufferInput(SoxInput):
|
||
|
def __init__(self, fp):
|
||
|
super(FileBufferInput, self).__init__()
|
||
|
wave_file = wave.open(fp, mode='rb') # wave.open() seems to support only 16bit encodings
|
||
|
self.channels = wave_file.getnchannels()
|
||
|
self.data = np.frombuffer(wave_file.readframes(wave_file.getnframes()), dtype=np.int16)
|
||
|
self.cmd_prefix = ' '.join([
|
||
|
'-t s16', # int16 encoding by default
|
||
|
'-r ' + str(wave_file.getframerate()),
|
||
|
'-c ' + str(self.channels),
|
||
|
PIPE_CHAR,
|
||
|
])
|
||
|
|
||
|
|
||
|
class NumpyArrayInput(SoxInput):
|
||
|
def __init__(self, snd_array, rate):
|
||
|
super(NumpyArrayInput, self).__init__()
|
||
|
self.channels = snd_array.ndim
|
||
|
self.cmd_prefix = ' '.join([
|
||
|
'-t ' + ENCODINGS_MAPPING[snd_array.dtype.type],
|
||
|
'-r ' + str(rate),
|
||
|
'-c ' + str(self.channels),
|
||
|
PIPE_CHAR,
|
||
|
])
|
||
|
|
||
|
|
||
|
class SoxOutput(object):
|
||
|
def __init__(self):
|
||
|
self.cmd_suffix = None
|
||
|
|
||
|
|
||
|
class FilePathOutput(SoxOutput):
|
||
|
def __init__(self, filepath, samplerate, channels):
|
||
|
super(FilePathOutput, self).__init__()
|
||
|
self.cmd_suffix = ' '.join(['-r ' + str(samplerate), '-c ' + str(channels), filepath])
|
||
|
|
||
|
|
||
|
class FileBufferOutput(SoxOutput):
|
||
|
def __init__(self, fp, samplerate, channels):
|
||
|
super(FileBufferOutput, self).__init__()
|
||
|
self.writer = wave.open(fp, mode='wb')
|
||
|
self.writer.setnchannels(channels)
|
||
|
self.writer.setframerate(samplerate)
|
||
|
self.writer.setsampwidth(2)
|
||
|
self.cmd_suffix = ' '.join([
|
||
|
'-t ' + ENCODINGS_MAPPING[np.int16],
|
||
|
'-r ' + str(samplerate),
|
||
|
'-c ' + str(channels),
|
||
|
PIPE_CHAR,
|
||
|
])
|
||
|
|
||
|
def write(self, data):
|
||
|
self.writer.writeframesraw(data)
|
||
|
|
||
|
|
||
|
class NumpyArrayOutput(SoxOutput):
|
||
|
def __init__(self, encoding, samplerate, channels):
|
||
|
super(NumpyArrayOutput, self).__init__()
|
||
|
self.cmd_suffix = ' '.join([
|
||
|
'-t ' + ENCODINGS_MAPPING[encoding],
|
||
|
'-r ' + str(samplerate),
|
||
|
'-c ' + str(channels),
|
||
|
PIPE_CHAR,
|
||
|
])
|