#!/usr/bin/env python import sys import os import yaml import empty import cmd_ut import thr import dbg def data_new(name_mp3): (name, mp3) = os.path.splitext(name_mp3) def make_wav(): if os.path.exists( name + '.wav' ): return if not os.path.exists( name_mp3 ): dbg.err_exit( 'not found {}'.format(name_mp3) ) cmd = 'lame --decode {} > /dev/null 2>&1'.format( name_mp3 ) cmd_ut.call(cmd) def raw_opt_new(): cmd = 'sox --info {}.wav'.format(name) s = cmd_ut.call(cmd) d = yaml.load(s) r = float( d.get('Sample Rate', 44100) ) b = 16 s = d.get('Precision') if s.endswith('-bit'): b = int( s[:-len('-bit')] ) c = int( d.get('Channels', 2) ) e = 'signed-integer' s = d.get('Sample Encoding', 'Signed') if 'Signed' not in s: e = 'unsigned-interger' get_raw_opt = lambda r_rate=1.0: '-t raw -r {} -b {} -c {} -e {}'.format(r*r_rate, b, c, e) byte_per_smp = c * (b//8) smp_sec = lambda sec: int( sec * r ) smp_to_sec = lambda m: m / r byte_sec = lambda sec: smp_sec(sec) * byte_per_smp byte_to_sec = lambda n: smp_to_sec( n // byte_per_smp ) return empty.new( locals() ) def make_raw(): if os.path.exists( name + '.raw' ): return cmd = 'sox {}.wav {}.raw'.format(name, name) cmd_ut.call(cmd) make_wav() opt = raw_opt_new() make_raw() dat = bytes([]) with open( '{}.raw'.format(name), 'rb' ) as f: dat = f.read() n = opt.byte_per_smp m = len(dat) // n smp_lst = list( map( lambda i: dat[i*n:i*n+n], range(m) ) ) smp_rlst = smp_lst[::-1] def get_smp_sec(sec, reverse): m = opt.smp_sec(sec) return smp_rlst[-m:] if reverse else smp_lst[m:] def get_dat_sec(sec, reverse, shift=0): lst = get_smp_sec(sec, reverse) if shift > 0: lst = lst[:: 2**shift ] return b''.join(lst) last_sec = opt.byte_to_sec( len(dat) ) return empty.new( locals() ) if __name__ == "__main__": if not sys.argv[1:]: dbg.err_exit( 'Usage: {} filename_mp3'.format( sys.argv[0] ) ) data = data_new( sys.argv[1] ) dbg.out( 'last_sec={}'.format( data.last_sec ) ) # EOF