mirror of
https://github.com/ankitects/anki.git
synced 2025-11-11 07:07:13 -05:00
add pyaudio recorder, remove external recorder
This commit is contained in:
parent
97359df499
commit
d4ac87bc19
1 changed files with 77 additions and 24 deletions
101
anki/sound.py
101
anki/sound.py
|
|
@ -23,7 +23,6 @@ def stripSounds(text):
|
||||||
def hasSound(text):
|
def hasSound(text):
|
||||||
return re.search("\[sound:.*?\]", text) is not None
|
return re.search("\[sound:.*?\]", text) is not None
|
||||||
|
|
||||||
# External audio
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
# the amount of noise to cancel
|
# the amount of noise to cancel
|
||||||
|
|
@ -54,14 +53,20 @@ queue = []
|
||||||
manager = None
|
manager = None
|
||||||
|
|
||||||
if sys.platform.startswith("win32"):
|
if sys.platform.startswith("win32"):
|
||||||
base = os.path.join(os.path.dirname(sys.argv[0]), "mplayer.exe")
|
externalPlayer = ["mplayer.exe", "-ao", "win32", "-really-quiet"]
|
||||||
#base = "C:\mplayer.exe"
|
# bug in sox means we need tmp on the same drive
|
||||||
externalPlayer = [base, "-ao", "win32", "-really-quiet"]
|
try:
|
||||||
externalRecorder = ["rec", processingSrc]
|
p = os.path.join(os.path.splitdrive(
|
||||||
|
os.path.abspath(""))[0], "\\tmp")
|
||||||
|
os.mkdir(p)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||||
|
os.environ['PATH'] += ";" + dir
|
||||||
|
os.environ['PATH'] += ";" + dir + "\\..\\dist" # for testing
|
||||||
|
print os.environ['PATH']
|
||||||
else:
|
else:
|
||||||
externalPlayer = ["mplayer", "-really-quiet"]
|
externalPlayer = ["mplayer", "-really-quiet"]
|
||||||
externalRecorder = ["ecasound", "-x", "-f:16,1,44100", "-i",
|
|
||||||
"alsahw,1,0", "-o", processingSrc]
|
|
||||||
|
|
||||||
# don't show box on windows
|
# don't show box on windows
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
|
|
@ -70,14 +75,20 @@ if sys.platform == "win32":
|
||||||
else:
|
else:
|
||||||
si = None
|
si = None
|
||||||
|
|
||||||
# noise profiles
|
# Noise profiles
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def checkForNoiseProfile():
|
def checkForNoiseProfile():
|
||||||
cmd = ["sox", processingSrc, "tmp2.wav"]
|
global processingChain
|
||||||
if os.path.exists(noiseProfile):
|
if sys.platform.startswith("darwin"):
|
||||||
cmd = cmd + ["noisered", noiseProfile, NOISE_AMOUNT]
|
# not currently supported
|
||||||
processingChain[0] = cmd
|
processingChain = [
|
||||||
|
["lame", "tmp.wav", "tmp.mp3", "--noreplaygain"]]
|
||||||
|
else:
|
||||||
|
cmd = ["sox", processingSrc, "tmp2.wav"]
|
||||||
|
if os.path.exists(noiseProfile):
|
||||||
|
cmd = cmd + ["noisered", noiseProfile, NOISE_AMOUNT]
|
||||||
|
processingChain[0] = cmd
|
||||||
|
|
||||||
def generateNoiseProfile(file):
|
def generateNoiseProfile(file):
|
||||||
try:
|
try:
|
||||||
|
|
@ -118,18 +129,63 @@ def clearQueueExternal():
|
||||||
global queue
|
global queue
|
||||||
queue = []
|
queue = []
|
||||||
|
|
||||||
# External recording
|
# PyAudio recording
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pyaudio
|
||||||
|
import wave
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
class _Recorder(object):
|
class _Recorder(object):
|
||||||
|
|
||||||
def postprocess(self):
|
def postprocess(self):
|
||||||
for c in processingChain:
|
for c in processingChain:
|
||||||
print c
|
print c
|
||||||
if subprocess.Popen(c, startupinfo=si).wait():
|
p = subprocess.Popen(c, startupinfo=si)
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
ret = p.wait()
|
||||||
|
break
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
if ret:
|
||||||
raise Exception("problem with" + str(c))
|
raise Exception("problem with" + str(c))
|
||||||
|
|
||||||
class ExternalUnixRecorder(_Recorder):
|
class PyAudioThreadedRecorder(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
self.finish = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
chunk = 1024
|
||||||
|
FORMAT = pyaudio.paInt16
|
||||||
|
CHANNELS = 1
|
||||||
|
RATE = 44100
|
||||||
|
p = pyaudio.PyAudio()
|
||||||
|
stream = p.open(format = FORMAT,
|
||||||
|
channels = CHANNELS,
|
||||||
|
rate = RATE,
|
||||||
|
input = True,
|
||||||
|
input_device_index = 0,
|
||||||
|
frames_per_buffer = chunk)
|
||||||
|
all = []
|
||||||
|
while not self.finish:
|
||||||
|
data = stream.read(chunk)
|
||||||
|
all.append(data)
|
||||||
|
stream.close()
|
||||||
|
p.terminate()
|
||||||
|
data = ''.join(all)
|
||||||
|
wf = wave.open(processingSrc, 'wb')
|
||||||
|
wf.setnchannels(CHANNELS)
|
||||||
|
wf.setsampwidth(p.get_sample_size(FORMAT))
|
||||||
|
wf.setframerate(RATE)
|
||||||
|
wf.writeframes(data)
|
||||||
|
wf.close()
|
||||||
|
|
||||||
|
class PyAudioRecorder(_Recorder):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
for t in tmpFiles + [processingSrc, processingDst]:
|
for t in tmpFiles + [processingSrc, processingDst]:
|
||||||
|
|
@ -139,12 +195,12 @@ class ExternalUnixRecorder(_Recorder):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.proc = subprocess.Popen(
|
self.thread = PyAudioThreadedRecorder()
|
||||||
externalRecorder, startupinfo=si)
|
self.thread.start()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
os.kill(self.proc.pid, signal.SIGINT)
|
self.thread.finish = True
|
||||||
self.proc.wait()
|
self.thread.join()
|
||||||
|
|
||||||
def file(self):
|
def file(self):
|
||||||
return processingDst
|
return processingDst
|
||||||
|
|
@ -205,11 +261,8 @@ except ImportError:
|
||||||
if sys.platform.startswith("darwin"):
|
if sys.platform.startswith("darwin"):
|
||||||
play = playOSX
|
play = playOSX
|
||||||
clearAudioQueue = clearQueueOSX
|
clearAudioQueue = clearQueueOSX
|
||||||
Recorder = None
|
|
||||||
else:
|
else:
|
||||||
play = playExternal
|
play = playExternal
|
||||||
clearAudioQueue = clearQueueExternal
|
clearAudioQueue = clearQueueExternal
|
||||||
if sys.platform.startswith("win32"):
|
|
||||||
Recorder = None
|
Recorder = PyAudioRecorder
|
||||||
else:
|
|
||||||
Recorder = ExternalUnixRecorder
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue