9
9
__docformat__ = 'restructuredtext'
11
import re, sys, threading, time, subprocess, os, signal
11
import re, sys, threading, time, subprocess, os, signal, atexit, errno
12
from anki.hooks import addHook, runHook
14
15
##########################################################################
49
50
["lame", "tmp3.wav", processingDst, "--noreplaygain", "--quiet"],
55
if sys.platform.startswith("win32"):
56
externalPlayer = ["mplayer.exe", "-ao", "win32", "-really-quiet", "-noconsolecontrols"]
57
dir = os.path.dirname(os.path.abspath(sys.argv[0]))
58
os.environ['PATH'] += ";" + dir
59
os.environ['PATH'] += ";" + dir + "\\..\\dist" # for testing
61
externalPlayer = ["mplayer", "-really-quiet", "-noconsolecontrols"]
63
53
# don't show box on windows
64
54
if sys.platform == "win32":
65
55
si = subprocess.STARTUPINFO()
111
101
processingChain[0] = ["sox", processingSrc, "tmp2.wav",
112
102
"noisered", noiseProfile, NOISE_AMOUNT]
115
##########################################################################
117
class QueueMonitor(threading.Thread):
125
retryWait(subprocess.Popen(
126
externalPlayer + [path], startupinfo=si))
128
raise Exception("Audio player not found")
132
def playExternal(path):
105
##########################################################################
107
if sys.platform.startswith("win32"):
108
mplayerCmd = ["mplayer.exe", "-ao", "win32", "-really-quiet"]
109
dir = os.path.dirname(os.path.abspath(sys.argv[0]))
110
os.environ['PATH'] += ";" + dir
111
os.environ['PATH'] += ";" + dir + "\\..\\dist" # for testing
113
mplayerCmd = ["mplayer", "-really-quiet"]
115
# Mplayer in slave mode
116
##########################################################################
119
mplayerManager = None
121
mplayerCond = threading.Condition()
123
class MplayerReader(threading.Thread):
124
"Read any debugging info to prevent mplayer from blocking."
128
mplayerCond.acquire()
130
mplayerCond.release()
132
mplayerManager.mplayer.stdout.read()
136
class MplayerMonitor(threading.Thread):
141
mplayerCond.acquire()
142
while not mplayerQueue:
148
if self.mplayer != -1 and self.mplayer.poll() is not None:
153
item = mplayerQueue.pop(0)
162
cmd = 'loadfile "%s"%s\n' % (item, extra)
163
self.mplayer.stdin.write(cmd)
164
mplayerCond.release()
166
def startProcess(self):
168
cmd = mplayerCmd + ["-slave", "-idle"]
169
self.mplayer = subprocess.Popen(
170
cmd, startupinfo=si, stdin=subprocess.PIPE,
171
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
173
mplayerCond.release()
174
raise Exception("Audio player not found")
176
def queueMplayer(path):
177
ensureMplayerThreads()
134
178
path = path.encode(sys.getfilesystemencoding())
136
if not manager or not manager.isAlive():
137
manager = QueueMonitor()
140
def clearQueueExternal():
179
mplayerCond.acquire()
180
mplayerQueue.append(path)
181
mplayerCond.notifyAll()
182
mplayerCond.release()
183
runHook("soundQueued")
185
def clearMplayerQueue():
186
mplayerCond.acquire()
187
mplayerQueue.append(None)
188
mplayerCond.release()
190
def ensureMplayerThreads():
191
global mplayerManager, mplayerReader
192
if not mplayerManager:
193
mplayerManager = MplayerMonitor()
194
mplayerManager.daemon = True
195
mplayerManager.start()
196
mplayerReader = MplayerReader()
197
mplayerReader.daemon = True
198
mplayerReader.start()
199
atexit.register(stopMplayer)
201
def stopMplayer(restart=False):
202
if not mplayerManager:
204
mplayerCond.acquire()
205
if mplayerManager.mplayer:
208
mplayerManager.mplayer.stdin.write("quit\n")
211
if e.errno != errno.EINTR:
212
# osx throws interrupt errors regularly, but we want to
213
# ignore other errors on shutdown
222
mplayerManager.mplayer = -1
223
mplayerCond.notifyAll()
224
mplayerCond.release()
226
def stopMplayerOnce():
227
stopMplayer(restart=True)
229
addHook("deckClosed", stopMplayerOnce)
144
231
# PyAudio recording
145
232
##########################################################################