bugfix
This commit is contained in:
parent
ac8ff8b36e
commit
66d0a18bcd
44
kivyblocks/audiorecorder.py
Normal file
44
kivyblocks/audiorecorder.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
import tempfile
|
||||||
|
import pyaudio
|
||||||
|
import wave
|
||||||
|
from kivy.event import EventDispatcher
|
||||||
|
from kivy.properties import NumericProperty
|
||||||
|
from kivyblocks.baseWidget import HBox
|
||||||
|
from kviyblocks.micphone import Micphone
|
||||||
|
|
||||||
|
class AudioRecorder(EventDispatcher):
|
||||||
|
fs = NumericProperty(None)
|
||||||
|
filename = StringProperty(None)
|
||||||
|
voice_src = OjbectProperty(None)
|
||||||
|
def __init__(self, **kw):
|
||||||
|
super(AudioRecorder, self).__init__(**kw)
|
||||||
|
self.saving = False
|
||||||
|
if not self.filename:
|
||||||
|
self.mk_temp_file()
|
||||||
|
|
||||||
|
def mk_temp_file(self):
|
||||||
|
self.filename = tempfile.mktemp(suffix='.wav')
|
||||||
|
|
||||||
|
def on_filename(self, *args):
|
||||||
|
self.wf = wave.open(self.filename, 'wb')
|
||||||
|
|
||||||
|
def on_voice_src(self, *args):
|
||||||
|
audio_profile = self.voice_src.audio_profile()
|
||||||
|
self.wf.setnchannels(audio_profile['channels'])
|
||||||
|
self.wf.setsamplewidth(audio_profile['sample_size'])
|
||||||
|
self.wf.setframerate(audio_profiel['sample_rate'])
|
||||||
|
self.voice_src.bind(on_fps=self.write)
|
||||||
|
|
||||||
|
def write(self, o, d):
|
||||||
|
if self.saving:
|
||||||
|
self.wf.write(''.join(d))
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
if not self.voice_src.recording:
|
||||||
|
self.voice_src.start()
|
||||||
|
self.saving = True
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.saving = False
|
||||||
|
wf.close()
|
@ -572,8 +572,10 @@ class Blocks(EventDispatcher):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
def doit(desc):
|
def doit(desc):
|
||||||
|
if isinstance(desc,DictObject):
|
||||||
|
desc = desc.to_dict()
|
||||||
if not isinstance(desc,dict):
|
if not isinstance(desc,dict):
|
||||||
Logger.info('Block: desc must be a dict object',
|
Logger.info('Block: desc(%s) must be a dict object(%s)',
|
||||||
desc,type(desc))
|
desc,type(desc))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -31,6 +31,14 @@ description file format
|
|||||||
print('size changed')
|
print('size changed')
|
||||||
for c in self._inner.children:
|
for c in self._inner.children:
|
||||||
c.width = self.width
|
c.width = self.width
|
||||||
|
if isinstance(c, Factory.Text):
|
||||||
|
_, h = c.get_wraped_size()
|
||||||
|
clen = CSize(1)
|
||||||
|
if not h or h < clen:
|
||||||
|
c.height = clen
|
||||||
|
else:
|
||||||
|
c.height = h
|
||||||
|
self._inner.do_layout()
|
||||||
|
|
||||||
def load_text(self, *args):
|
def load_text(self, *args):
|
||||||
print('source fired, hahaha', *args)
|
print('source fired, hahaha', *args)
|
||||||
@ -51,14 +59,13 @@ description file format
|
|||||||
l = ''.join([i for i in l if i != '\r'])
|
l = ''.join([i for i in l if i != '\r'])
|
||||||
self.parse_line(l)
|
self.parse_line(l)
|
||||||
|
|
||||||
def parse_title(self,txt, level):
|
def parse_title(self, txt, level):
|
||||||
w = Factory.Blocks().widgetBuild({
|
w = Factory.Blocks().widgetBuild({
|
||||||
"widgettype":f"Title{level}",
|
"widgettype":f"Title{level}",
|
||||||
"options":{
|
"options":{
|
||||||
"text":txt,
|
"text":txt,
|
||||||
"size_hint_x":None,
|
"size_hint_x":None,
|
||||||
"width":self.width,
|
"width":self.width,
|
||||||
"minimum_width":self.width,
|
|
||||||
"size_hint_y":None,
|
"size_hint_y":None,
|
||||||
"markup":True,
|
"markup":True,
|
||||||
"wrap":True,
|
"wrap":True,
|
||||||
@ -66,12 +73,14 @@ description file format
|
|||||||
"valign":"middle"
|
"valign":"middle"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
_,h = w.get_wraped_size()
|
if not w:
|
||||||
|
return
|
||||||
|
w1,h1 = w.get_wraped_size()
|
||||||
clen = CSize(1)
|
clen = CSize(1)
|
||||||
if h is None or h < clen:
|
if h1 is None or h1 < clen:
|
||||||
h = clen
|
h1 = clen
|
||||||
w.height = h
|
w.height = h1
|
||||||
print(w,h,w.height)
|
print(w, w1, h1, w.height)
|
||||||
w.bind(on_ref_press=self.open_new_md)
|
w.bind(on_ref_press=self.open_new_md)
|
||||||
self.add_widget(w)
|
self.add_widget(w)
|
||||||
|
|
||||||
@ -102,12 +111,13 @@ description file format
|
|||||||
"wrap":True,
|
"wrap":True,
|
||||||
"size_hint_x":None,
|
"size_hint_x":None,
|
||||||
"width":self.width,
|
"width":self.width,
|
||||||
"minimum_width":self.width,
|
|
||||||
"markup":True,
|
"markup":True,
|
||||||
"valign":"middle",
|
"valign":"middle",
|
||||||
"halign":"left"
|
"halign":"left"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if not w:
|
||||||
|
return
|
||||||
_,h = w.get_wraped_size()
|
_,h = w.get_wraped_size()
|
||||||
clen = CSize(1)
|
clen = CSize(1)
|
||||||
if h is None or h < clen:
|
if h is None or h < clen:
|
||||||
|
@ -6,13 +6,14 @@ import wave
|
|||||||
CHUNK = 1024
|
CHUNK = 1024
|
||||||
CHANNELS = 2
|
CHANNELS = 2
|
||||||
FORMAT = pyaudio.paInt16
|
FORMAT = pyaudio.paInt16
|
||||||
rate = 48000
|
samplerate = 48000
|
||||||
|
|
||||||
class Micphone:
|
class Micphone(EventDispatcher):
|
||||||
channels = NumericProperty(2)
|
channels = NumericProperty(2)
|
||||||
rate = NumericProperty(48000)
|
samplerate = NumericProperty(48000)
|
||||||
fps = NumericProperty(1/60)
|
fps = NumericProperty(1/60)
|
||||||
def __init__(self, **kw):
|
def __init__(self, **kw):
|
||||||
|
super(Micphone, self).__init__(**kw)
|
||||||
self.chunk = CHUNK
|
self.chunk = CHUNK
|
||||||
self.format = pyaudio.Int16
|
self.format = pyaudio.Int16
|
||||||
self.chunk_buffer = []
|
self.chunk_buffer = []
|
||||||
@ -21,21 +22,29 @@ class Micphone:
|
|||||||
self._audio = puaudio.PyAudio()
|
self._audio = puaudio.PyAudio()
|
||||||
self._mic = p.open(format=self.format,
|
self._mic = p.open(format=self.format,
|
||||||
channels=self.channels,
|
channels=self.channels,
|
||||||
rate=self.rate,
|
rate=self.samplerate,
|
||||||
input=True,
|
input=True,
|
||||||
frames_per_buffer=self.chunk)
|
frames_per_buffer=self.chunk)
|
||||||
self.sampe_size = self.audio.get_sample_size(self.format)
|
self.sampe_size = self.audio.get_sample_size(self.format)
|
||||||
self.register_event_type('on_fps')
|
self.register_event_type('on_fps')
|
||||||
|
self.register_event_type('on_start')
|
||||||
|
self.register_event_type('on_end')
|
||||||
self.fps_task = None
|
self.fps_task = None
|
||||||
|
|
||||||
def on_fps(self, d):
|
def on_fps(self, d):
|
||||||
print('on_fps fired')
|
print('on_fps fired')
|
||||||
|
|
||||||
|
def on_start(self):
|
||||||
|
print('on_start fired')
|
||||||
|
|
||||||
|
def on_end(self):
|
||||||
|
print('on_end fired')
|
||||||
|
|
||||||
def audio_profile(self):
|
def audio_profile(self):
|
||||||
return {
|
return {
|
||||||
'channels':self.channels,
|
'channels':self.channels,
|
||||||
'sample_size':self.sample_size,
|
'sample_size':self.sample_size,
|
||||||
'rate':self.rate
|
'sample_rate':self.samplerate
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_frames(self, *args):
|
def get_frames(self, *args):
|
||||||
@ -52,6 +61,7 @@ class Micphone:
|
|||||||
def start(self, *args):
|
def start(self, *args):
|
||||||
self.recording = True
|
self.recording = True
|
||||||
Background(self._record)
|
Background(self._record)
|
||||||
|
self.dispatch('on_start')
|
||||||
self.fps_task = Clock.schedule_interval(self.get_frames, self.fps)
|
self.fps_task = Clock.schedule_interval(self.get_frames, self.fps)
|
||||||
|
|
||||||
def _record(self):
|
def _record(self):
|
||||||
@ -65,6 +75,7 @@ class Micphone:
|
|||||||
def stop(self, *args):
|
def stop(self, *args):
|
||||||
self.recording = False
|
self.recording = False
|
||||||
self.fps_task.cancel()
|
self.fps_task.cancel()
|
||||||
|
self.dispatch('on_end')
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self._mic.stop_stream()
|
self._mic.stop_stream()
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
import json
|
|
||||||
from functools import partial
|
|
||||||
from kivy.event import EventDispatcher
|
|
||||||
from kivy.clock import Clock
|
|
||||||
from oscpy.server import OSCThreadServer
|
|
||||||
from oscpy.client import send_message, OSCClient
|
|
||||||
|
|
||||||
class OSCServer(EventDispatcher):
|
|
||||||
def __init__(self,addr='0.0.0.0',
|
|
||||||
port=60405,
|
|
||||||
apis=[]):
|
|
||||||
self.port = port
|
|
||||||
self.addr = addr
|
|
||||||
self.clients = []
|
|
||||||
self.osc_server = OSCThreadServer()
|
|
||||||
sock = self.osc_server.listen(self.addr,port=self.port,default=True)
|
|
||||||
EventDispatcher.__init__(self)
|
|
||||||
apis.append('broadcast')
|
|
||||||
for api in apis:
|
|
||||||
event_name = 'on_%s' % api
|
|
||||||
f = partial(self.handle, api)
|
|
||||||
setattr(self, event_name, f)
|
|
||||||
self.register_event_type(event_name)
|
|
||||||
api_f = partial(self.apihandle,api)
|
|
||||||
bstr = '/%s' % api
|
|
||||||
bstr.encode('utf-8')
|
|
||||||
self.osc_server.bind(bstr, api_f, sock)
|
|
||||||
|
|
||||||
def info(self):
|
|
||||||
ip,port = self.osc_server.getaddress()
|
|
||||||
return {
|
|
||||||
"ip":ip,
|
|
||||||
"port":port
|
|
||||||
}
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self.osc_server.stop()
|
|
||||||
|
|
||||||
def handle(self,api,o,*args):
|
|
||||||
print(api, *args)
|
|
||||||
|
|
||||||
def apihandle(self, api, *args):
|
|
||||||
print('OSCServer():apihandle():api=', api, 'args=',args)
|
|
||||||
data = args[0].decode('utf-8')
|
|
||||||
data = json.loads(data)
|
|
||||||
sock, ip_address, response_port = self.osc_server.get_sender()
|
|
||||||
self.dispatch('on_%s' % api, api, data)
|
|
||||||
if api == 'broadcast':
|
|
||||||
return
|
|
||||||
if not address in self.clients:
|
|
||||||
self.clients.append([ip_address, response_port])
|
|
||||||
|
|
||||||
def send_message(self,api, data, addr, port):
|
|
||||||
data = json.dumps(data)
|
|
||||||
data = data.encode('utf-8')
|
|
||||||
bstr = '/%s' % api
|
|
||||||
bstr = bstr.encode('utf-8')
|
|
||||||
print('api=', bstr,
|
|
||||||
'data=', data,
|
|
||||||
'addr=', addr,
|
|
||||||
'port=',port)
|
|
||||||
send_message(bstr, [data], addr, port)
|
|
||||||
|
|
||||||
def broadcast(self, data):
|
|
||||||
for address in self.clients:
|
|
||||||
self.osc_server.send_message('broadcast', data, *address)
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
|||||||
from kivy.event import EventDispatcher
|
|
||||||
from kivy.core.window import Window
|
from kivy.core.window import Window
|
||||||
from kivy.utils import platform
|
from kivy.utils import platform
|
||||||
from kivy.app import App
|
from kivy.app import App
|
||||||
|
@ -16,6 +16,7 @@ from .baseWidget import PressableLabel
|
|||||||
from .color_definitions import getColors
|
from .color_definitions import getColors
|
||||||
from .bgcolorbehavior import BGColorBehavior
|
from .bgcolorbehavior import BGColorBehavior
|
||||||
from .utils import alert,absurl
|
from .utils import alert,absurl
|
||||||
|
from .threadcall import HttpClient
|
||||||
|
|
||||||
class EmptyBox(Label):
|
class EmptyBox(Label):
|
||||||
def __init__(self,size_cnt=1):
|
def __init__(self,size_cnt=1):
|
||||||
@ -323,7 +324,7 @@ class Tree(BGColorBehavior, ScrollWidget):
|
|||||||
self.NodeKlass = klass
|
self.NodeKlass = klass
|
||||||
|
|
||||||
def getUrlData(self,callback,kv=None):
|
def getUrlData(self,callback,kv=None):
|
||||||
hc = App.get_running_app().hc
|
hc = HttpClient()
|
||||||
params = self.options.get('params',{}).copy()
|
params = self.options.get('params',{}).copy()
|
||||||
if not kv is None:
|
if not kv is None:
|
||||||
for k,v in kv.items():
|
for k,v in kv.items():
|
||||||
|
Loading…
Reference in New Issue
Block a user