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