78 lines
2.1 KiB
Python
78 lines
2.1 KiB
Python
import scipy.io.wavfile
|
|
import scipy.signal
|
|
import numpy
|
|
import argparse
|
|
import logging
|
|
|
|
LOG_LEVELS = [logging.WARNING, logging.INFO, logging.DEBUG]
|
|
LOGGER=logging.getLogger(__name__)
|
|
|
|
|
|
def parse_args(*args):
|
|
""" get the CLI args """
|
|
|
|
parser = argparse.ArgumentParser(prog="granule",
|
|
description="Extract granules from a wav file")
|
|
parser.add_argument('input', nargs='*', help="Input filename")
|
|
parser.add_argument('-p', '--playlist', help="Input playlist")
|
|
parser.add_argument('-o', '--output', help="Output filename")
|
|
parser.add_argument("-v", "--verbosity", action="count",
|
|
help="increase output verbosity",
|
|
default=0)
|
|
|
|
return parser.parse_args(*args)
|
|
|
|
def normalize(buffer):
|
|
amplitude = max(numpy.max(buffer), -numpy.min(buffer))
|
|
return buffer/amplitude;
|
|
|
|
def accumulate(filename, buffer):
|
|
""" Accumulates a song into the accumulation buffer """
|
|
LOGGER.info("Reading %s", filename)
|
|
rate, data = scipy.io.wavfile.read(filename)
|
|
|
|
if len(data.shape) > 1:
|
|
data = numpy.mean(data, axis=1)
|
|
|
|
data = normalize(data)
|
|
|
|
if rate != 44100:
|
|
data = scipy.signal.resample(data, len(data)*44100 // rate)
|
|
|
|
if buffer is None:
|
|
return data
|
|
|
|
out_len = max(len(buffer), len(data))
|
|
if len(buffer) < out_len:
|
|
buffer.resize(out_len, refcheck=False)
|
|
if len(data) < out_len:
|
|
data.resize(out_len, refcheck=False)
|
|
|
|
buffer += data
|
|
return buffer
|
|
|
|
def main():
|
|
args = parse_args()
|
|
logging.basicConfig(level=LOG_LEVELS[min(
|
|
args.verbosity, len(LOG_LEVELS) - 1)])
|
|
|
|
if args.playlist:
|
|
with open(args.playlist) as file:
|
|
for line in file:
|
|
args.input.append(line.strip())
|
|
|
|
output = None
|
|
|
|
total = len(args.input)
|
|
for num, infile in enumerate(args.input):
|
|
output = accumulate(infile, output)
|
|
|
|
output = normalize(output)
|
|
|
|
LOGGER.info("Output file: %d samples (%.2f seconds)", len(output), len(output)/44100)
|
|
if (args.output):
|
|
scipy.io.wavfile.write(args.output, 44100, output)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|