Skip to content

Instantly share code, notes, and snippets.

@mwv
Created August 30, 2014 10:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mwv/6535497d043859dfb6d3 to your computer and use it in GitHub Desktop.
Save mwv/6535497d043859dfb6d3 to your computer and use it in GitHub Desktop.
# read shorten (shn) files into numpy arrays
from __future__ import division
import os.path as path
import os
from subprocess import call
import struct
import tempfile
def shnread(shnfile):
"""Read shorten audio file, such as used by NIST, TIMIT and WSJ databases
into numpy array. Assumes that `shorten` is in the PATH.
Shorten can be found here: http://etree.org/shnutils/shorten/
Arguments:
:param shnfile: filename
:return sig, fs:
signal and sample rate
"""
tmp = path.join(tempfile.mkdtemp(),
path.splitext(path.basename(sph_file))[0] + '.wav')
with open(sph_file, 'rb') as f:
f.read(8) # NIST_1A
headerlen = int(f.read(8).strip())
header = f.read(headerlen - 16).strip().split('\n')
header = {e.split(' ')[0]: e.split(' ')[2] for e in header[:-1]}
fs = int(header['sample_rate'])
endianness = '<' if int(header['sample_byte_format']) == 1 else '>'
bytes_per_sample = int(header['sample_n_bytes'])
bit_depth = int(header['sample_sig_bits'])
call(['shorten', '-x', '-d', str(headerlen), sph_file, tmp])
with open(tmp, 'rb') as f:
f.read(headerlen) # skip header
bytes = f.read()
format_map = {1: 'b', 2: 'h', 4: 'i', 8: 'q'}
sig = np.fromiter((struct.unpack('{0}{1}'.format(endianness,
format_map[bytes_per_sample]),
bytes[i:i+bytes_per_sample])[0]
for i in xrange(0, len(bytes), bytes_per_sample)),
dtype='int{}'.format(bit_depth))
sig = sig / max(abs(sig))
os.unlink(tmp)
return sig, fs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment