mirror of
https://github.com/xiph/opus.git
synced 2025-05-17 17:08:29 +00:00
initial commit
This commit is contained in:
commit
c41afe41f0
4 changed files with 162 additions and 0 deletions
23
dnn/lpcnet.py
Normal file
23
dnn/lpcnet.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import math
|
||||
from keras.models import Model
|
||||
from keras.layers import Input, LSTM, CuDNNGRU, Dense, Embedding, Reshape, Concatenate, Lambda, Conv1D, Multiply, Bidirectional, MaxPooling1D, Activation
|
||||
from keras import backend as K
|
||||
from mdense import MDense
|
||||
import numpy as np
|
||||
import h5py
|
||||
import sys
|
||||
|
||||
rnn_units=256
|
||||
pcm_bits = 8
|
||||
pcm_levels = 1+2**pcm_bits
|
||||
|
||||
def new_wavernn_model():
|
||||
pcm = Input(shape=(None, 1))
|
||||
rnn = CuDNNGRU(rnn_units, return_sequences=True)
|
||||
md = MDense(pcm_levels, activation='softmax')
|
||||
ulaw_prob = md(rnn(pcm))
|
||||
|
||||
model = Model(pcm, ulaw_prob)
|
||||
return model
|
94
dnn/mdense.py
Normal file
94
dnn/mdense.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
from keras import backend as K
|
||||
from keras.engine.topology import Layer
|
||||
from keras.layers import activations, initializers, regularizers, constraints, InputSpec
|
||||
import numpy as np
|
||||
import math
|
||||
|
||||
class MDense(Layer):
|
||||
|
||||
def __init__(self, outputs,
|
||||
channels=2,
|
||||
activation=None,
|
||||
use_bias=True,
|
||||
kernel_initializer='glorot_uniform',
|
||||
bias_initializer='zeros',
|
||||
kernel_regularizer=None,
|
||||
bias_regularizer=None,
|
||||
activity_regularizer=None,
|
||||
kernel_constraint=None,
|
||||
bias_constraint=None,
|
||||
**kwargs):
|
||||
if 'input_shape' not in kwargs and 'input_dim' in kwargs:
|
||||
kwargs['input_shape'] = (kwargs.pop('input_dim'),)
|
||||
super(MDense, self).__init__(**kwargs)
|
||||
self.units = outputs
|
||||
self.channels = channels
|
||||
self.activation = activations.get(activation)
|
||||
self.use_bias = use_bias
|
||||
self.kernel_initializer = initializers.get(kernel_initializer)
|
||||
self.bias_initializer = initializers.get(bias_initializer)
|
||||
self.kernel_regularizer = regularizers.get(kernel_regularizer)
|
||||
self.bias_regularizer = regularizers.get(bias_regularizer)
|
||||
self.activity_regularizer = regularizers.get(activity_regularizer)
|
||||
self.kernel_constraint = constraints.get(kernel_constraint)
|
||||
self.bias_constraint = constraints.get(bias_constraint)
|
||||
self.input_spec = InputSpec(min_ndim=2)
|
||||
self.supports_masking = True
|
||||
|
||||
def build(self, input_shape):
|
||||
assert len(input_shape) >= 2
|
||||
input_dim = input_shape[-1]
|
||||
|
||||
self.kernel = self.add_weight(shape=(self.units, input_dim, self.channels),
|
||||
initializer=self.kernel_initializer,
|
||||
name='kernel',
|
||||
regularizer=self.kernel_regularizer,
|
||||
constraint=self.kernel_constraint)
|
||||
if self.use_bias:
|
||||
self.bias = self.add_weight(shape=(self.units, self.channels),
|
||||
initializer=self.bias_initializer,
|
||||
name='bias',
|
||||
regularizer=self.bias_regularizer,
|
||||
constraint=self.bias_constraint)
|
||||
else:
|
||||
self.bias = None
|
||||
self.factor = self.add_weight(shape=(self.units, self.channels),
|
||||
initializer='ones',
|
||||
name='factor',
|
||||
regularizer=self.bias_regularizer,
|
||||
constraint=self.bias_constraint)
|
||||
self.input_spec = InputSpec(min_ndim=2, axes={-1: input_dim})
|
||||
self.built = True
|
||||
|
||||
def call(self, inputs):
|
||||
output = K.dot(inputs, self.kernel)
|
||||
if self.use_bias:
|
||||
output = output + self.bias
|
||||
output = K.tanh(output) * self.factor
|
||||
output = K.sum(output, axis=-1)
|
||||
if self.activation is not None:
|
||||
output = self.activation(output)
|
||||
return output
|
||||
|
||||
def compute_output_shape(self, input_shape):
|
||||
assert input_shape and len(input_shape) >= 2
|
||||
assert input_shape[-1]
|
||||
output_shape = list(input_shape)
|
||||
output_shape[-1] = self.units
|
||||
return tuple(output_shape)
|
||||
|
||||
def get_config(self):
|
||||
config = {
|
||||
'units': self.units,
|
||||
'activation': activations.serialize(self.activation),
|
||||
'use_bias': self.use_bias,
|
||||
'kernel_initializer': initializers.serialize(self.kernel_initializer),
|
||||
'bias_initializer': initializers.serialize(self.bias_initializer),
|
||||
'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
|
||||
'bias_regularizer': regularizers.serialize(self.bias_regularizer),
|
||||
'activity_regularizer': regularizers.serialize(self.activity_regularizer),
|
||||
'kernel_constraint': constraints.serialize(self.kernel_constraint),
|
||||
'bias_constraint': constraints.serialize(self.bias_constraint)
|
||||
}
|
||||
base_config = super(MDense, self).get_config()
|
||||
return dict(list(base_config.items()) + list(config.items()))
|
31
dnn/train_lpcnet.py
Executable file
31
dnn/train_lpcnet.py
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import lpcnet
|
||||
import sys
|
||||
import numpy as np
|
||||
from keras.optimizers import Adam
|
||||
from ulaw import ulaw2lin, lin2ulaw
|
||||
|
||||
nb_epochs = 10
|
||||
batch_size = 32
|
||||
|
||||
model = lpcnet.new_wavernn_model()
|
||||
model.compile(optimizer=Adam(0.001), loss='sparse_categorical_crossentropy', metrics=['sparse_categorical_accuracy'])
|
||||
model.summary()
|
||||
|
||||
pcmfile = sys.argv[1]
|
||||
chunk_size = int(sys.argv[2])
|
||||
|
||||
data = np.fromfile(pcmfile, dtype='int16')
|
||||
#data = data[:100000000]
|
||||
data = data/32768
|
||||
nb_frames = (len(data)-1)//chunk_size
|
||||
|
||||
in_data = data[:nb_frames*chunk_size]
|
||||
#out_data = data[1:1+nb_frames*chunk_size]//256 + 128
|
||||
out_data = lin2ulaw(data[1:1+nb_frames*chunk_size]) + 128
|
||||
|
||||
in_data = np.reshape(in_data, (nb_frames, chunk_size, 1))
|
||||
out_data = np.reshape(out_data, (nb_frames, chunk_size, 1))
|
||||
|
||||
model.fit(in_data, out_data, batch_size=batch_size, epochs=nb_epochs, validation_split=0.2)
|
14
dnn/ulaw.py
Normal file
14
dnn/ulaw.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
import numpy as np
|
||||
import math
|
||||
|
||||
def ulaw2lin(u):
|
||||
return (math.exp(u/128*math.log(256))-1)/255
|
||||
|
||||
|
||||
def lin2ulaw(x):
|
||||
s = np.sign(x)
|
||||
x = np.abs(x)
|
||||
u = (s*(128*np.log(1+255*x)/math.log(256)))
|
||||
u = np.round(u)
|
||||
return u.astype('int16')
|
Loading…
Add table
Add a link
Reference in a new issue