Skip to content

Commit

Permalink
added display to use the mel-scale approximation on the stochastic an…
Browse files Browse the repository at this point in the history
…alysis, thus supporting both linear frequency and mel-scale approximations
  • Loading branch information
xserra committed Sep 25, 2023
1 parent 7c36fa6 commit c8776d2
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 27 deletions.
28 changes: 24 additions & 4 deletions software/models_interface/stochasticModel_GUI_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,33 @@ def initUI(self):
self.stocf.delete(0, END)
self.stocf.insert(0, "0.1")

#MEl SCALE
melScale_label = "Approximation scale (0: linear, 1: mel):"
Label(self.parent, text=melScale_label).grid(row=5, column=0, sticky=W, padx=5, pady=(10,2))
self.melScale = Entry(self.parent, justify=CENTER)
self.melScale["width"] = 5
self.melScale.grid(row=5, column=0, sticky=W, padx=(285,5), pady=(10,2))
self.melScale.delete(0, END)
self.melScale.insert(0, "1")

#NORMALIZATION
normalization_label = "Amplitude normalization (0: no, 1: yes):"
Label(self.parent, text=normalization_label).grid(row=6, column=0, sticky=W, padx=5, pady=(10,2))
self.normalization = Entry(self.parent, justify=CENTER)
self.normalization["width"] = 5
self.normalization.grid(row=6, column=0, sticky=W, padx=(285,5), pady=(10,2))
self.normalization.delete(0, END)
self.normalization.insert(0, "1")

#BUTTON TO COMPUTE EVERYTHING
self.compute = Button(self.parent, text="Compute", command=self.compute_model)
self.compute.grid(row=5, column=0, padx=5, pady=(10,2), sticky=W)
self.compute.grid(row=7, column=0, padx=5, pady=(10,2), sticky=W)

#BUTTON TO PLAY OUTPUT
output_label = "Stochastic:"
Label(self.parent, text=output_label).grid(row=6, column=0, sticky=W, padx=5, pady=(10,15))
Label(self.parent, text=output_label).grid(row=8, column=0, sticky=W, padx=5, pady=(10,15))
self.output = Button(self.parent, text=">", command=lambda:UF.wavplay('output_sounds/' + os.path.basename(self.filelocation.get())[:-4] + '_stochasticModel.wav'))
self.output.grid(row=6, column=0, padx=(80,5), pady=(10,15), sticky=W)
self.output.grid(row=8, column=0, padx=(80,5), pady=(10,15), sticky=W)

# define options for opening file
self.file_opt = options = {}
Expand All @@ -97,8 +115,10 @@ def compute_model(self):
H = int(self.H.get())
N = int(self.N.get())
stocf = float(self.stocf.get())
melScale = int(self.melScale.get())
normalization = int(self.normalization.get())

stochasticModel_function.main(inputFile, H, N, stocf)
stochasticModel_function.main(inputFile, H, N, stocf, melScale, normalization)

except ValueError as errorMessage:
messagebox.showerror("Input values error", errorMessage)
53 changes: 30 additions & 23 deletions software/models_interface/stochasticModel_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,32 @@
import numpy as np
import matplotlib.pyplot as plt
import os, sys
from scipy.signal import get_window
from scipy.signal.windows import hann
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../models/'))
import utilFunctions as UF
import stochasticModel as STM
import stft as STFT

def main(inputFile='../../sounds/ocean.wav', H=256, N=512, stocf=.1):
def main(inputFile='../../sounds/ocean.wav', H=256, N=512, stocf=.1, melScale=1, normalization=1):
"""
inputFile: input sound file (monophonic with sampling rate of 44100)
H: hop size, N: fft size
stocf: decimation factor used for the stochastic approximation (bigger than 0, maximum 1)
melScale: frequency approximation scale (0: linear approximation, 1: mel frequency approximation)
normalization: amplitude normalization of output (0: no normalization, 1: normalization to input amplitude)
"""

# read input sound
(fs, x) = UF.wavread(inputFile)

# compute stochastic model
stocEnv = STM.stochasticModelAnal(x, H, N, stocf)
stocEnv = STM.stochasticModelAnal(x, H, N, stocf, fs, melScale)

# synthesize sound from stochastic model
y = STM.stochasticModelSynth(stocEnv, H, N)
y = STM.stochasticModelSynth(stocEnv, H, N, fs, melScale)

if (normalization==1):
y = y * max(x)/max(y)

outputFile = 'output_sounds/' + os.path.basename(inputFile)[:-4] + '_stochasticModel.wav'

Expand All @@ -32,31 +38,32 @@ def main(inputFile='../../sounds/ocean.wav', H=256, N=512, stocf=.1):
# create figure to plot
plt.figure(figsize=(9, 6))

# plot the input sound
plt.subplot(3,1,1)
plt.plot(np.arange(x.size)/float(fs), x)
plt.axis([0, x.size/float(fs), min(x), max(x)])
plt.ylabel('amplitude')
plt.xlabel('time (sec)')
plt.title('input sound: x')
# frequency range to plot
maxplotfreq = 10000.0

# plot stochastic representation
plt.subplot(3,1,2)
numFrames = int(stocEnv[:,0].size)
frmTime = H*np.arange(numFrames)/float(fs)
binFreq = np.arange(int(stocf*(N/2+1)))*float(fs)/(stocf*N)
plt.pcolormesh(frmTime, binFreq, np.transpose(stocEnv), shading='auto')
plt.autoscale(tight=True)
# plot input spectrogram
plt.subplot(2,1,1)
mX, pX = STFT.stftAnal(x, hann(N), N, H)
numFrames = int(mX[:,0].size)
frmTime = H*np.arange(numFrames)/float(fs)
binFreq = fs*np.arange(N*maxplotfreq/fs)/N
plt.pcolormesh(frmTime, binFreq, np.transpose(mX[:,:int(N*maxplotfreq/fs+1)]))
plt.xlabel('time (sec)')
plt.ylabel('frequency (Hz)')
plt.title('stochastic approximation')
plt.title('input magnitude spectrogram')
plt.autoscale(tight=True)

# plot the output sound
plt.subplot(3,1,3)
plt.plot(np.arange(y.size)/float(fs), y)
plt.axis([0, y.size/float(fs), min(y), max(y)])
plt.ylabel('amplitude')
plt.subplot(2,1,2)
mY, pY = STFT.stftAnal(y, hann(N), N, H)
numFrames = int(mY[:,0].size)
frmTime = H*np.arange(numFrames)/float(fs)
binFreq = fs*np.arange(N*maxplotfreq/fs)/N
plt.pcolormesh(frmTime, binFreq, np.transpose(mY[:,:int(N*maxplotfreq/fs+1)]))
plt.xlabel('time (sec)')
plt.ylabel('frequency (Hz)')
plt.title('input magnitude spectrogram')
plt.autoscale(tight=True)

plt.tight_layout()
plt.ion()
Expand Down

0 comments on commit c8776d2

Please sign in to comment.