Skip to content

Instantly share code, notes, and snippets.

@lefirea
Created October 8, 2018 03:20
Show Gist options
  • Save lefirea/8f3683a1ecd8809619f5332d0bc64c9e to your computer and use it in GitHub Desktop.
Save lefirea/8f3683a1ecd8809619f5332d0bc64c9e to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
import wx
import numpy as np
import pyaudio
import pyworld as pw
import threading
import datetime
from pynput.keyboard import Key, Controller, Listener
from scipy.io import wavfile
class MyApp(wx.Frame):
f0ChangeFlag=False
spChangeFlag=False
def __init__(self, *args, **kw):
super(MyApp, self).__init__(*args, **kw)
self.initUI()
def initUI(self):
font=wx.Font(20,
wx.FONTFAMILY_DEFAULT,
wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_NORMAL)
self.SetTitle('test')
self.SetBackgroundColour((255, 200, 150))
self.SetPosition((200, 100))
self.SetSize((300, 300))
self.Show()
#self.frame=wx.Frame()
self.Bind(wx.EVT_CLOSE, self.PushedCloseButton)
#f0のON,OFFを切り替える
self.f0label=wx.StaticText(self, wx.ID_ANY, 'f0変換してないよ', pos=(50,50))
self.f0label.SetFont(font)
self.f0CoefBox=wx.TextCtrl(self, -1, pos=(50, 80), size=(50,-1))
self.f0CoefBox.SetLabel(str(f0ChangeCoef))
self.Button1=wx.Button(self, -1, 'OFF', pos=(50,110), size=(50,20))
self.Button1.Bind(wx.EVT_BUTTON, self.f0Button_clicked)
#spのON,OFFを切り替える
self.splabel=wx.StaticText(self, wx.ID_ANY, 'sp変換してないよ', pos=(50,150))
self.splabel.SetFont(font)
self.spCoefBox=wx.TextCtrl(self, -1, pos=(50, 180), size=(50,-1))
self.spCoefBox.SetLabel(str(spChangeCoef))
self.spButton=wx.Button(self, -1, 'OFF', pos=(50,210), size=(50,20))
self.spButton.Bind(wx.EVT_BUTTON, self.spButton_clicked)
def f0Button_clicked(self, event):
global f0ChangeCoef
if self.f0ChangeFlag==False:
self.f0ChangeFlag=True
self.Button1.SetLabel('ON')
f0ChangeCoef=float(self.f0CoefBox.GetValue())
if f0ChangeCoef < 0:
f0ChangeCoef=1.0
self.f0CoefBox.SetLabel(str(self.f0ChangeCoef))
self.f0label.SetLabel('f0変換中')
self.f0CoefBox.Disable()
elif self.f0ChangeFlag==True:
self.f0ChangeFlag=False
self.Button1.SetLabel('OFF')
f0ChangeCoef=1.0
self.f0label.SetLabel('f0変換してないよ')
self.f0CoefBox.Enable()
def spButton_clicked(self, event):
global spChangeCoef
if self.spChangeFlag==False:
self.spChangeFlag=True
self.spButton.SetLabel('ON')
spChangeCoef=float(self.spCoefBox.GetValue())
if spChangeCoef<1.0:
spChangeCoef=1.0
self.spCoefBox.SetLabel(str(self.spChangeCoef))
self.splabel.SetLabel('sp変換中')
self.spCoefBox.Disable()
elif self.spChangeFlag==True:
self.spChangeFlag=False
self.spButton.SetLabel('OFF')
spChangeCoef=1.0
self.splabel.SetLabel('sp変換してないよ')
self.spCoefBox.Enable()
def OnPaint(self, event):
dc=wx.PaintDC(self.graphPanel)
dc.SetPen(wx.Pen('blue'))
for i in range(10):
y=20*i
dc.DrawLine(0, y, 200, y)
for i in range(11):
x=20*i
dc.DrawLine(x, 0, x, 200)
dc.SetPen(wx.Pen('red'))
dc.DrawLine(0, 0, 200, 200)
def PushedCloseButton(self, event):
print('push close button')
#listener.join()を誘発
keyboard=Controller()
keyboard.press(Key.esc)
keyboard.release(Key.esc)
KeyLoggerThread.join()
RecordThread.join()
stream.stop_stream()
stream.close()
p.terminate()
self.Destroy()
def on_press(key):
global listener
global QuitKeyPushed
try:
char=key.char
except:
#修飾キー
char=key
finally:
print(char)
if char==Key.esc or char=='q':
print('quit...')
QuitKeyPushed=True
listener.stop()
KeyLoggerThread.join()
stream.stop_stream()
stream.close()
p.terminate()
def on_release(key):
pass
def KeyLogger():
try:
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
except:
pass
def ChangeVoice(data):
data=np.frombuffer(data, dtype=np.int16).astype(np.float)
_f0, t=pw.dio(data, Rate)
f0=pw.stonemask(data, _f0, t, Rate)
sp=pw.cheaptrick(data, f0, t, Rate)
ap=pw.d4c(data, f0, t, Rate)
convert_f0=f0*f0ChangeCoef
if spChangeCoef==1.0:
convert_sp=np.array(sp)
else:
convert_sp=np.zeros_like(sp)
for f in range(convert_sp.shape[1]):
convert_sp[:, f]=sp[:, int(f/spChangeCoef)]
synthe=pw.synthesize(convert_f0, convert_sp, ap, Rate).astype(np.int16)
#"""
#print(round(time.time()-start,5),'[s]')
return synthe.tobytes()
def Recorder():
frames=[]
while stream.is_active():
try:
data=stream.read(Chunk)
#data=stream.read(int(Rate*0.12))
data=ChangeVoice(data)
stream.write(data)
frames.append(data)
if QuitKeyPushed==True:
break;
except:
print('except')
#listener.join()を誘発
keyboard=Controller()
keyboard.press(Key.esc)
keyboard.release(Key.esc)
KeyLoggerThread.join()
break;
finally:
pass
stream.stop_stream()
stream.close()
p.terminate()
print('Stop Streaming...')
Chunk=int(1024*2)
Format=pyaudio.paInt16
Channels=1
Rate=int(17.5*1000)
QuitKeyPushed=False #終了キー入力
f0ChangeCoef=1.0 #f0変換係数
spChangeCoef=1.0 #sp変換係数
#キー入力監視スレッド
KeyLoggerThread=threading.Thread(target=KeyLogger)
KeyLoggerThread.start()
#マイク入力設定
p=pyaudio.PyAudio()
stream=p.open(format=Format,
channels=Channels,
rate=Rate,
input=True,
output=True,
#frames_per_buffer=Chunk
)
#マイク音取得開始
stream.start_stream()
#録音スレッド
RecordThread=threading.Thread(target=Recorder)
RecordThread.start()
#ウィンドウ作成
app=wx.App()
MyApp(None)
app.MainLoop()
del app #app.close()的な感じ。これが無いとエラーが出る
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment