LoginSignup
0
0

More than 5 years have passed since last update.

LPCによってAR係数を取得後ホワイトノイズで駆動させてみた.
いい感じに声がロボット(?)っぽくなった気がする.
あと,駆動するノイズを変更すればまた違った声質になるはず.

lpc.py
#!/usr/bin/env python

import sys
import wave
import urllib2
import getopt
import scipy as sp
import matplotlib.pyplot as plt
from scipy import linalg, signal
from scikits.talkbox.linpred.levinson_lpc import lpc

if __name__ == "__main__":
    optlist, argv = getopt.getopt( sys.argv[1:], 's:l:o:w:')

    frameLength = 512
    stepWidth = 256
    lpcOrder = 32
    chunk = 44100 * 5
    for opt, val in optlist:
        if( opt == '-s' ):
            chunk = int( val )
        elif( opt == '-w' ):
            stepWidth = int( val )
        elif( opt == '-l'):
            frameLength = int( val )
        elif( opt == '-o' ):
            lpcOrder = int( val )

    argc = len( argv )
    if( 0 < argc ):
        if( argc == 2 ):
            inFileName, outFileName = argv
        elif( argc == 1 ):
            inFileName = argv[0]
            outFileName = 'out.wav'
        wo = wave.open( inFileName, 'rb' )
    else:
        outFileName = 'out.wav'
        url = 'http://www.it.ice.uec.ac.jp/SRV-DB/archive/HENSHU00_PF00/HENSHU00_PF00_0951.wav'
        wo = wave.openfp( urllib2.urlopen( url ).fp,  'rb' )

    data = sp.fromstring( wo.readframes( chunk ), sp.int16 )
    blockData = sp.linalg.toeplitz( data[ frameLength:], data[:frameLength] )[::stepWidth, :]

    lpcCoef, lpcError, k = lpc( blockData,  lpcOrder )
    excitationSignal = sp.random.randn( frameLength )

    rows, cols = lpcCoef.shape
    responseSignal = sp.zeros( ( rows,  frameLength ) )
    synthesisSignal = sp.array( [0] * ( rows  * stepWidth + frameLength ) )
    weight = sp.sin( 2 * sp.pi * sp.r_[0:frameLength] / frameLength )
    for i in range( rows ):
        G = sp.sqrt( lpcError[ i ] )
        responseSignal[i, :] = sp.signal.lfilter( [G], lpcCoef[ i, :], excitationSignal )
        synthesisSignal[ i * stepWidth:i * stepWidth + frameLength ] +=  weight * responseSignal[ i, :]

    outputSignal = sp.int16( synthesisSignal ).tostring()
    wo = wave.open( outFileName, 'wb')
    params = ( 1, 2, 44100, len( synthesisSignal),'NONE','none')
    wo.setparams( params )
    wo.writeframes( outputSignal )
    wo.close()
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0