Slicing Audio

From Devipedia

Jump to: navigation, search

This is a crude wavebreaker I put together. It's one of my first attempts and considering my limited knowledge of DSP, I was almost surprised it worked. But it does. I'm sure I'll be back soon with improvements and tweaks.

#!/usr/bin/python

import pyaudio
import wave
import sys, os 
from datetime import datetime
import time
import math
import argparse
import scipy
from numpy import *
from pylab import *
from scipy import *
from scipy.fftpack import fftshift

def nextpow2(i):
    n = 2
    while n < i: n = n * 2
    return n

def itemone(mx):
    return mx[0]

def main(args):
    
    chunk = 1024
    wf = wave.open(args.file, 'rb')
    p = pyaudio.PyAudio()

    # make output dir
    ds = datetime.now().strftime('%m-%d-%y:%s')

    os.mkdir(ds)
    os.chdir(ds)
    
    # read data
    data = wf.readframes(chunk)

    mx = []
    out = []
    # play stream
    while data != '':
 
        #stream.write(data)
        
        dt = bytearray(data)
        y = abs(fftshift(fft(dt)))
        mx.append((max(y), wf.tell()))

        data = wf.readframes(chunk)

    lastpos = mx.pop()[1]

    maximum = max(mx, key=itemone)
    minimum = min(mx, key=itemone)
    print "max %d" % maximum[0]
    print "min %d" % minimum[0]
    diff = maximum[0] - minimum[0]
    startpt = maximum[0] - diff / args.sensitivity 
    print "startpt %d" % startpt 

    sections = []
    sections.append(0)

    crossed = False 

    for i in mx:
        if i[0] > startpt and not crossed:
            crossed = True 
            sections.append(i[1])
        elif i[0] < startpt:
            crossed = False 
    
    sections.append(lastpos)    
           
    print sections 
    # open stream
    stream = p.open(format =
                    p.get_format_from_width(wf.getsampwidth()),
                    channels = wf.getnchannels(),
                    rate = wf.getframerate(),
                    output = True)


    for s in range(0, len(sections) - 1):
        chunk = sections[s+1] - sections[s]
        wf.setpos(sections[s]) 
        stream.write(data)
        write_chunk(wf, sections[s], data)
        data = wf.readframes(chunk)
     
    stream.close()
    p.terminate()


def write_chunk(wf, name, out):

    data = ''.join(out)
    filename = '%s.wav' % name
    wo = wave.open(filename, 'wb')
    wo.setnchannels(wf.getnchannels())
    wo.setsampwidth(wf.getsampwidth())
    wo.setframerate(wf.getframerate())
    wo.writeframes(data)
    wo.close()

if __name__=="__main__":
    parser = argparse.ArgumentParser(description='Bust up a wav file.')
    parser.add_argument('file',   
                   help='Name of a wave file: example.wav')
    parser.add_argument('-s', dest='sensitivity', action='store', default=10, 
                        type=int,
                        help='Level of sensitivity. Defaults to 10. Increase for decreased sensitivity. (1,n)')

    args = parser.parse_args()
    
    main(args)

Personal tools