1*f81fb7c4SAndroid Build Coastguard Worker 2*f81fb7c4SAndroid Build Coastguard Workerfrom __future__ import with_statement 3*f81fb7c4SAndroid Build Coastguard Worker 4*f81fb7c4SAndroid Build Coastguard Workerimport threading 5*f81fb7c4SAndroid Build Coastguard Workerimport logging 6*f81fb7c4SAndroid Build Coastguard Workerimport time 7*f81fb7c4SAndroid Build Coastguard Workerfrom ctypes import * 8*f81fb7c4SAndroid Build Coastguard Workerfrom JetUtils import OsWindows 9*f81fb7c4SAndroid Build Coastguard Worker 10*f81fb7c4SAndroid Build Coastguard Worker 11*f81fb7c4SAndroid Build Coastguard Worker# stream state 12*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_READY = 0 13*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_PLAY = 1 14*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_STOPPING = 2 15*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_PAUSING = 3 16*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_STOPPED = 4 17*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_PAUSED = 5 18*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_OPEN = 6 19*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_ERROR = 7 20*f81fb7c4SAndroid Build Coastguard WorkerEAS_STATE_EMPTY = 8 21*f81fb7c4SAndroid Build Coastguard Worker 22*f81fb7c4SAndroid Build Coastguard Worker# EAS error codes 23*f81fb7c4SAndroid Build Coastguard WorkerEAS_SUCCESS = 0 24*f81fb7c4SAndroid Build Coastguard WorkerEAS_FAILURE = -1 25*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_INVALID_MODULE = -2 26*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_MALLOC_FAILED = -3 27*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_POS = -4 28*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_INVALID_FILE_MODE = -5 29*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_SEEK = -6 30*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_LENGTH = -7 31*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_NOT_IMPLEMENTED = -8 32*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_CLOSE_FAILED = -9 33*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_OPEN_FAILED = -10 34*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_INVALID_HANDLE = -11 35*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_NO_MIX_BUFFER = -12 36*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_PARAMETER_RANGE = -13 37*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_MAX_FILES_OPEN = -14 38*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_UNRECOGNIZED_FORMAT = -15 39*f81fb7c4SAndroid Build Coastguard WorkerEAS_BUFFER_SIZE_MISMATCH = -16 40*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_FORMAT = -17 41*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_SMF_NOT_INITIALIZED = -18 42*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_LOCATE_BEYOND_END = -19 43*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_INVALID_PCM_TYPE = -20 44*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_MAX_PCM_STREAMS = -21 45*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_NO_VOICE_ALLOCATED = -22 46*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_INVALID_CHANNEL = -23 47*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_ALREADY_STOPPED = -24 48*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_READ_FAILED = -25 49*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_HANDLE_INTEGRITY = -26 50*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_MAX_STREAMS_OPEN = -27 51*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_INVALID_PARAMETER = -28 52*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FEATURE_NOT_AVAILABLE = -29 53*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_SOUND_LIBRARY = -30 54*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_NOT_VALID_IN_THIS_STATE = -31 55*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_NO_VIRTUAL_SYNTHESIZER = -32 56*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_ALREADY_OPEN = -33 57*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FILE_ALREADY_CLOSED = -34 58*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_INCOMPATIBLE_VERSION = -35 59*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_QUEUE_IS_FULL = -36 60*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_QUEUE_IS_EMPTY = -37 61*f81fb7c4SAndroid Build Coastguard WorkerEAS_ERROR_FEATURE_ALREADY_ACTIVE = -38 62*f81fb7c4SAndroid Build Coastguard Worker 63*f81fb7c4SAndroid Build Coastguard Worker# special result codes 64*f81fb7c4SAndroid Build Coastguard WorkerEAS_EOF = 3 65*f81fb7c4SAndroid Build Coastguard WorkerEAS_STREAM_BUFFERING = 4 66*f81fb7c4SAndroid Build Coastguard Worker 67*f81fb7c4SAndroid Build Coastguard Worker# buffer full error returned from Render 68*f81fb7c4SAndroid Build Coastguard WorkerEAS_BUFFER_FULL = 5 69*f81fb7c4SAndroid Build Coastguard Worker 70*f81fb7c4SAndroid Build Coastguard Worker# file types 71*f81fb7c4SAndroid Build Coastguard Workerfile_types = ( 72*f81fb7c4SAndroid Build Coastguard Worker 'Unknown', 73*f81fb7c4SAndroid Build Coastguard Worker 'SMF Type 0 (.mid)', 74*f81fb7c4SAndroid Build Coastguard Worker 'SMF Type 1 (.mid)', 75*f81fb7c4SAndroid Build Coastguard Worker 'SMAF - Unknown type (.mmf)', 76*f81fb7c4SAndroid Build Coastguard Worker 'SMAF MA-2 (.mmf)', 77*f81fb7c4SAndroid Build Coastguard Worker 'SMAF MA-3 (.mmf)', 78*f81fb7c4SAndroid Build Coastguard Worker 'SMAF MA-5 (.mmf)', 79*f81fb7c4SAndroid Build Coastguard Worker 'CMX/QualComm (.pmd)', 80*f81fb7c4SAndroid Build Coastguard Worker 'MFi (NTT/DoCoMo i-mode)', 81*f81fb7c4SAndroid Build Coastguard Worker 'OTA/Nokia (.ott)', 82*f81fb7c4SAndroid Build Coastguard Worker 'iMelody (.imy)', 83*f81fb7c4SAndroid Build Coastguard Worker 'RTX/RTTTL (.rtx)', 84*f81fb7c4SAndroid Build Coastguard Worker 'XMF Type 0 (.xmf)', 85*f81fb7c4SAndroid Build Coastguard Worker 'XMF Type 1 (.xmf)', 86*f81fb7c4SAndroid Build Coastguard Worker 'WAVE/PCM (.wav)', 87*f81fb7c4SAndroid Build Coastguard Worker 'WAVE/IMA-ADPCM (.wav)', 88*f81fb7c4SAndroid Build Coastguard Worker 'MMAPI Tone Control (.js)' 89*f81fb7c4SAndroid Build Coastguard Worker) 90*f81fb7c4SAndroid Build Coastguard Worker 91*f81fb7c4SAndroid Build Coastguard Workerstream_states = ( 92*f81fb7c4SAndroid Build Coastguard Worker 'Ready', 93*f81fb7c4SAndroid Build Coastguard Worker 'Play', 94*f81fb7c4SAndroid Build Coastguard Worker 'Stopping', 95*f81fb7c4SAndroid Build Coastguard Worker 'Stopped', 96*f81fb7c4SAndroid Build Coastguard Worker 'Pausing', 97*f81fb7c4SAndroid Build Coastguard Worker 'Paused', 98*f81fb7c4SAndroid Build Coastguard Worker 'Open', 99*f81fb7c4SAndroid Build Coastguard Worker 'Error', 100*f81fb7c4SAndroid Build Coastguard Worker 'Empty' 101*f81fb7c4SAndroid Build Coastguard Worker) 102*f81fb7c4SAndroid Build Coastguard Worker 103*f81fb7c4SAndroid Build Coastguard Worker# iMode play modes 104*f81fb7c4SAndroid Build Coastguard WorkerIMODE_PLAY_ALL = 0 105*f81fb7c4SAndroid Build Coastguard WorkerIMODE_PLAY_PARTIAL = 1 106*f81fb7c4SAndroid Build Coastguard Worker 107*f81fb7c4SAndroid Build Coastguard Worker# callback type for metadata 108*f81fb7c4SAndroid Build Coastguard WorkerEAS_METADATA_CBFUNC = CFUNCTYPE(c_int, c_int, c_char_p, c_ulong) 109*f81fb7c4SAndroid Build Coastguard Worker 110*f81fb7c4SAndroid Build Coastguard Worker# callbacks for external audio 111*f81fb7c4SAndroid Build Coastguard WorkerEAS_EXT_PRG_CHG_FUNC = CFUNCTYPE(c_int, c_void_p, c_void_p) 112*f81fb7c4SAndroid Build Coastguard WorkerEAS_EXT_EVENT_FUNC = CFUNCTYPE(c_int, c_void_p, c_void_p) 113*f81fb7c4SAndroid Build Coastguard Worker 114*f81fb7c4SAndroid Build Coastguard Worker# callback for aux mixer decoder 115*f81fb7c4SAndroid Build Coastguard WorkerEAS_DECODER_FUNC = CFUNCTYPE(c_void_p, c_void_p, c_int, c_int) 116*f81fb7c4SAndroid Build Coastguard Worker 117*f81fb7c4SAndroid Build Coastguard Worker# DLL path 118*f81fb7c4SAndroid Build Coastguard Workerif OsWindows(): 119*f81fb7c4SAndroid Build Coastguard Worker EAS_DLL_PATH = "EASDLL.dll" 120*f81fb7c4SAndroid Build Coastguard Workerelse: 121*f81fb7c4SAndroid Build Coastguard Worker EAS_DLL_PATH = "libEASLIb.dylib" 122*f81fb7c4SAndroid Build Coastguard Worker 123*f81fb7c4SAndroid Build Coastguard Workereas_dll = None 124*f81fb7c4SAndroid Build Coastguard Worker 125*f81fb7c4SAndroid Build Coastguard Worker# logger 126*f81fb7c4SAndroid Build Coastguard Workereas_logger = None 127*f81fb7c4SAndroid Build Coastguard Worker 128*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 129*f81fb7c4SAndroid Build Coastguard Worker# InitEASModule 130*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 131*f81fb7c4SAndroid Build Coastguard Workerdef InitEASModule (dll_path=None): 132*f81fb7c4SAndroid Build Coastguard Worker global eas_dll 133*f81fb7c4SAndroid Build Coastguard Worker global eas_logger 134*f81fb7c4SAndroid Build Coastguard Worker 135*f81fb7c4SAndroid Build Coastguard Worker 136*f81fb7c4SAndroid Build Coastguard Worker # initialize logger 137*f81fb7c4SAndroid Build Coastguard Worker if eas_logger is None: 138*f81fb7c4SAndroid Build Coastguard Worker eas_logger = logging.getLogger('EAS') 139*f81fb7c4SAndroid Build Coastguard Worker 140*f81fb7c4SAndroid Build Coastguard Worker # initialize path to DLL 141*f81fb7c4SAndroid Build Coastguard Worker if dll_path is None: 142*f81fb7c4SAndroid Build Coastguard Worker dll_path=EAS_DLL_PATH 143*f81fb7c4SAndroid Build Coastguard Worker 144*f81fb7c4SAndroid Build Coastguard Worker # intialize DLL 145*f81fb7c4SAndroid Build Coastguard Worker if eas_dll is None: 146*f81fb7c4SAndroid Build Coastguard Worker eas_dll = cdll.LoadLibrary(dll_path) 147*f81fb7c4SAndroid Build Coastguard Worker 148*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 149*f81fb7c4SAndroid Build Coastguard Worker# S_JET_CONFIG 150*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 151*f81fb7c4SAndroid Build Coastguard Workerclass S_JET_CONFIG (Structure): 152*f81fb7c4SAndroid Build Coastguard Worker _fields_ = [('appLowNote', c_ubyte)] 153*f81fb7c4SAndroid Build Coastguard Worker 154*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 155*f81fb7c4SAndroid Build Coastguard Worker# S_EXT_AUDIO_PRG_CHG 156*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 157*f81fb7c4SAndroid Build Coastguard Workerclass S_EXT_AUDIO_PRG_CHG (Structure): 158*f81fb7c4SAndroid Build Coastguard Worker _fields_ = [('bank', c_ushort), 159*f81fb7c4SAndroid Build Coastguard Worker ('program', c_ubyte), 160*f81fb7c4SAndroid Build Coastguard Worker ('channel', c_ubyte)] 161*f81fb7c4SAndroid Build Coastguard Worker 162*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 163*f81fb7c4SAndroid Build Coastguard Worker# S_EXT_AUDIO_EVENT 164*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 165*f81fb7c4SAndroid Build Coastguard Workerclass S_EXT_AUDIO_EVENT (Structure): 166*f81fb7c4SAndroid Build Coastguard Worker _fields_ = [('channel', c_ubyte), 167*f81fb7c4SAndroid Build Coastguard Worker ('note', c_ubyte), 168*f81fb7c4SAndroid Build Coastguard Worker ('velocity', c_ubyte), 169*f81fb7c4SAndroid Build Coastguard Worker ('noteOn', c_ubyte)] 170*f81fb7c4SAndroid Build Coastguard Worker 171*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 172*f81fb7c4SAndroid Build Coastguard Worker# S_MIDI_CONTROLLERS 173*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 174*f81fb7c4SAndroid Build Coastguard Workerclass S_MIDI_CONTROLLERS (Structure): 175*f81fb7c4SAndroid Build Coastguard Worker _fields_ = [('modWheel', c_ubyte), 176*f81fb7c4SAndroid Build Coastguard Worker ('volume', c_ubyte), 177*f81fb7c4SAndroid Build Coastguard Worker ('pan', c_ubyte), 178*f81fb7c4SAndroid Build Coastguard Worker ('expression', c_ubyte), 179*f81fb7c4SAndroid Build Coastguard Worker ('channelPressure', c_ubyte)] 180*f81fb7c4SAndroid Build Coastguard Worker 181*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 182*f81fb7c4SAndroid Build Coastguard Worker# WAVEFORMAT 183*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 184*f81fb7c4SAndroid Build Coastguard Workerclass WAVEFORMAT (Structure): 185*f81fb7c4SAndroid Build Coastguard Worker _fields_ = [('wFormatTag', c_ushort), 186*f81fb7c4SAndroid Build Coastguard Worker ('nChannels', c_ushort), 187*f81fb7c4SAndroid Build Coastguard Worker ('nSamplesPerSec', c_ulong), 188*f81fb7c4SAndroid Build Coastguard Worker ('nAvgBytesPerSec', c_ulong), 189*f81fb7c4SAndroid Build Coastguard Worker ('nBlockAlign', c_ushort), 190*f81fb7c4SAndroid Build Coastguard Worker ('wBitsPerSample', c_ushort)] 191*f81fb7c4SAndroid Build Coastguard Worker 192*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 193*f81fb7c4SAndroid Build Coastguard Worker# EAS_Exception 194*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 195*f81fb7c4SAndroid Build Coastguard Workerclass EAS_Exception (Exception): 196*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, result_code, msg, function=None): 197*f81fb7c4SAndroid Build Coastguard Worker self.msg = msg 198*f81fb7c4SAndroid Build Coastguard Worker self.result_code = result_code 199*f81fb7c4SAndroid Build Coastguard Worker self.function = function 200*f81fb7c4SAndroid Build Coastguard Worker def __str__ (self): 201*f81fb7c4SAndroid Build Coastguard Worker return self.msg 202*f81fb7c4SAndroid Build Coastguard Worker 203*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 204*f81fb7c4SAndroid Build Coastguard Worker# Log callback function 205*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 206*f81fb7c4SAndroid Build Coastguard Worker# map EAS severity levels to the Python logging module 207*f81fb7c4SAndroid Build Coastguard Workerseverity_mapping = (logging.CRITICAL, logging.CRITICAL, logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG) 208*f81fb7c4SAndroid Build Coastguard WorkerLOG_FUNC_TYPE = CFUNCTYPE(c_int, c_int, c_char_p) 209*f81fb7c4SAndroid Build Coastguard Workerdef Log (level, msg): 210*f81fb7c4SAndroid Build Coastguard Worker eas_logger.log(severity_mapping[level], msg) 211*f81fb7c4SAndroid Build Coastguard Worker return level 212*f81fb7c4SAndroid Build Coastguard WorkerLogCallback = LOG_FUNC_TYPE(Log) 213*f81fb7c4SAndroid Build Coastguard Worker 214*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 215*f81fb7c4SAndroid Build Coastguard Worker# EAS_Stream 216*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 217*f81fb7c4SAndroid Build Coastguard Workerclass EAS_Stream (object): 218*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, handle, eas): 219*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_Stream.__init__') 220*f81fb7c4SAndroid Build Coastguard Worker self.handle = handle 221*f81fb7c4SAndroid Build Coastguard Worker self.eas = eas 222*f81fb7c4SAndroid Build Coastguard Worker 223*f81fb7c4SAndroid Build Coastguard Worker def SetVolume (self, volume): 224*f81fb7c4SAndroid Build Coastguard Worker """Set the stream volume""" 225*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetVolume: volume=%d' % volume) 226*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 227*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetVolume(self.eas.handle, self.handle, volume) 228*f81fb7c4SAndroid Build Coastguard Worker if result: 229*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetVolume error %d on file %s' % (result, self.path), 'EAS_SetVolume') 230*f81fb7c4SAndroid Build Coastguard Worker 231*f81fb7c4SAndroid Build Coastguard Worker def GetVolume (self): 232*f81fb7c4SAndroid Build Coastguard Worker """Get the stream volume.""" 233*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetVolume') 234*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 235*f81fb7c4SAndroid Build Coastguard Worker volume = eas_dll.EAS_GetVolume(self.eas.handle, self.handle) 236*f81fb7c4SAndroid Build Coastguard Worker if volume < 0: 237*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(volume, 'EAS_GetVolume error %d on file %s' % (volume, self.path), 'EAS_GetVolume') 238*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_GetVolume: volume=%d' % volume) 239*f81fb7c4SAndroid Build Coastguard Worker return volume 240*f81fb7c4SAndroid Build Coastguard Worker 241*f81fb7c4SAndroid Build Coastguard Worker def SetPriority (self, priority): 242*f81fb7c4SAndroid Build Coastguard Worker """Set the stream priority""" 243*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetPriority: priority=%d' % priority) 244*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 245*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetPriority(self.eas.handle, self.handle, priority) 246*f81fb7c4SAndroid Build Coastguard Worker if result: 247*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetPriority error %d on file %s' % (result, self.path), 'EAS_SetPriority') 248*f81fb7c4SAndroid Build Coastguard Worker 249*f81fb7c4SAndroid Build Coastguard Worker def GetPriority (self): 250*f81fb7c4SAndroid Build Coastguard Worker """Get the stream priority.""" 251*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetPriority') 252*f81fb7c4SAndroid Build Coastguard Worker priority = c_int(0) 253*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 254*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetPriority(self.eas.handle, self.handle, byref(priority)) 255*f81fb7c4SAndroid Build Coastguard Worker if result: 256*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetPriority error %d on file %s' % (result, self.path), 'EAS_GetPriority') 257*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_GetPriority: priority=%d' % priority.value) 258*f81fb7c4SAndroid Build Coastguard Worker return priority.value 259*f81fb7c4SAndroid Build Coastguard Worker 260*f81fb7c4SAndroid Build Coastguard Worker def SetTransposition (self, transposition): 261*f81fb7c4SAndroid Build Coastguard Worker """Set the transposition of a stream.""" 262*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetTransposition: transposition=%d' % transposition) 263*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 264*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetTransposition(self.eas.handle, self.handle, transposition) 265*f81fb7c4SAndroid Build Coastguard Worker if result: 266*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetTransposition error %d on file %s' % (result, self.path), 'EAS_SetTransposition') 267*f81fb7c4SAndroid Build Coastguard Worker 268*f81fb7c4SAndroid Build Coastguard Worker def SetPolyphony (self, polyphony): 269*f81fb7c4SAndroid Build Coastguard Worker """Set the polyphony of a stream.""" 270*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetPolyphony: polyphony=%d' % polyphony) 271*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 272*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetPolyphony(self.eas.handle, self.handle, polyphony) 273*f81fb7c4SAndroid Build Coastguard Worker if result: 274*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetPolyphony error %d on file %s' % (result, self.path), 'EAS_SetPolyphony') 275*f81fb7c4SAndroid Build Coastguard Worker 276*f81fb7c4SAndroid Build Coastguard Worker def GetPolyphony (self): 277*f81fb7c4SAndroid Build Coastguard Worker """Get the polyphony of a stream.""" 278*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetPolyphony') 279*f81fb7c4SAndroid Build Coastguard Worker polyphony = c_int(0) 280*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 281*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetPolyphony(self.eas.handle, self.handle, byref(polyphony)) 282*f81fb7c4SAndroid Build Coastguard Worker if result: 283*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetPolyphony error %d on file %s' % (result, self.path), 'EAS_GetPolyphony') 284*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_SetPolyphony: polyphony=%d' % polyphony.value) 285*f81fb7c4SAndroid Build Coastguard Worker return polyphony.value 286*f81fb7c4SAndroid Build Coastguard Worker 287*f81fb7c4SAndroid Build Coastguard Worker def SelectLib (self, test_lib=False): 288*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SelectLib: test_lib=%s' % test_lib) 289*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 290*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SelectLib(self.eas.handle, self.handle, test_lib) 291*f81fb7c4SAndroid Build Coastguard Worker if result: 292*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SelectLib error %d on file %s' % (result, self.path), 'EAS_SelectLib') 293*f81fb7c4SAndroid Build Coastguard Worker 294*f81fb7c4SAndroid Build Coastguard Worker def LoadDLSCollection (self, path): 295*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_LoadDLSCollection: lib_path=%d' % path) 296*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 297*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_LoadDLSCollection(self.eas.handle, self.handle, path) 298*f81fb7c4SAndroid Build Coastguard Worker if result: 299*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_LoadDLSCollection error %d on file %s lib %s' % (result, self.path, path), 'EAS_LoadDLSCollection') 300*f81fb7c4SAndroid Build Coastguard Worker 301*f81fb7c4SAndroid Build Coastguard Worker def RegExtAudioCallback (self, user_data, prog_chg_func, event_func): 302*f81fb7c4SAndroid Build Coastguard Worker """Register an external audio callback.""" 303*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_RegExtAudioCallback') 304*f81fb7c4SAndroid Build Coastguard Worker if prog_chg_func is not None: 305*f81fb7c4SAndroid Build Coastguard Worker prog_chg_func = EAS_EXT_PRG_CHG_FUNC(prog_chg_func) 306*f81fb7c4SAndroid Build Coastguard Worker else: 307*f81fb7c4SAndroid Build Coastguard Worker prog_chg_func = 0 308*f81fb7c4SAndroid Build Coastguard Worker if event_func is not None: 309*f81fb7c4SAndroid Build Coastguard Worker event_func = EAS_EXT_EVENT_FUNC(event_func) 310*f81fb7c4SAndroid Build Coastguard Worker else: 311*f81fb7c4SAndroid Build Coastguard Worker event_func = 0 312*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 313*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_RegExtAudioCallback(self.eas.handle, self.handle, user_data, prog_chg_func, event_func) 314*f81fb7c4SAndroid Build Coastguard Worker if result: 315*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_RegExtAudioCallback error %d on file %s' % (result, self.path), 'EAS_RegExtAudioCallback') 316*f81fb7c4SAndroid Build Coastguard Worker 317*f81fb7c4SAndroid Build Coastguard Worker def SetPlayMode (self, play_mode): 318*f81fb7c4SAndroid Build Coastguard Worker """Set play mode on a stream.""" 319*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetPlayMode: play_mode=%d' % play_mode) 320*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 321*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetPlayMode(self.eas.handle, self.handle, play_mode) 322*f81fb7c4SAndroid Build Coastguard Worker if result: 323*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetPlayMode error %d on file %s' % (result, self.path), 'EAS_SetPlayMode') 324*f81fb7c4SAndroid Build Coastguard Worker 325*f81fb7c4SAndroid Build Coastguard Worker""" 326*f81fb7c4SAndroid Build Coastguard WorkerEAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl); 327*f81fb7c4SAndroid Build Coastguard Worker""" 328*f81fb7c4SAndroid Build Coastguard Worker 329*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 330*f81fb7c4SAndroid Build Coastguard Worker# EAS_File 331*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 332*f81fb7c4SAndroid Build Coastguard Workerclass EAS_File (EAS_Stream): 333*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, path, handle, eas): 334*f81fb7c4SAndroid Build Coastguard Worker EAS_Stream.__init__(self, handle, eas) 335*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_File.__init__') 336*f81fb7c4SAndroid Build Coastguard Worker self.path = path 337*f81fb7c4SAndroid Build Coastguard Worker self.prepared = False 338*f81fb7c4SAndroid Build Coastguard Worker 339*f81fb7c4SAndroid Build Coastguard Worker def Prepare (self): 340*f81fb7c4SAndroid Build Coastguard Worker """Prepare an audio file for playback""" 341*f81fb7c4SAndroid Build Coastguard Worker if self.prepared: 342*f81fb7c4SAndroid Build Coastguard Worker eas_logger.warning('Prepare already called on file %s' % self.path) 343*f81fb7c4SAndroid Build Coastguard Worker else: 344*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 345*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_Prepare for file: %s' % self.path) 346*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_Prepare(self.eas.handle, self.handle) 347*f81fb7c4SAndroid Build Coastguard Worker if result: 348*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_Prepare error %d on file %s' % (result, self.path), 'EAS_Prepare') 349*f81fb7c4SAndroid Build Coastguard Worker self.prepared = True 350*f81fb7c4SAndroid Build Coastguard Worker 351*f81fb7c4SAndroid Build Coastguard Worker def State (self): 352*f81fb7c4SAndroid Build Coastguard Worker """Get stream state.""" 353*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 354*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_State for file: %s' % self.path) 355*f81fb7c4SAndroid Build Coastguard Worker state = c_long(-1) 356*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_State(self.eas.handle, self.handle, byref(state)) 357*f81fb7c4SAndroid Build Coastguard Worker if result: 358*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_State error %d on file %s' % (result, self.path), 'EAS_State') 359*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_State: file=%s, state=%s' % (self.path, stream_states[state.value])) 360*f81fb7c4SAndroid Build Coastguard Worker return state.value 361*f81fb7c4SAndroid Build Coastguard Worker 362*f81fb7c4SAndroid Build Coastguard Worker def Close (self): 363*f81fb7c4SAndroid Build Coastguard Worker """Close audio file.""" 364*f81fb7c4SAndroid Build Coastguard Worker if hasattr(self, 'handle'): 365*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 366*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_CloseFile for file: %s' % self.path) 367*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_CloseFile(self.eas.handle, self.handle) 368*f81fb7c4SAndroid Build Coastguard Worker if result: 369*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_CloseFile error %d on file %s' % (result, self.path), 'EAS_CloseFile') 370*f81fb7c4SAndroid Build Coastguard Worker 371*f81fb7c4SAndroid Build Coastguard Worker # remove file from the EAS object 372*f81fb7c4SAndroid Build Coastguard Worker self.eas.audio_streams.remove(self) 373*f81fb7c4SAndroid Build Coastguard Worker 374*f81fb7c4SAndroid Build Coastguard Worker # clean up references 375*f81fb7c4SAndroid Build Coastguard Worker del self.handle 376*f81fb7c4SAndroid Build Coastguard Worker del self.eas 377*f81fb7c4SAndroid Build Coastguard Worker del self.path 378*f81fb7c4SAndroid Build Coastguard Worker 379*f81fb7c4SAndroid Build Coastguard Worker def Pause (self): 380*f81fb7c4SAndroid Build Coastguard Worker """Pause a stream.""" 381*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_Pause') 382*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 383*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_Pause(self.eas.handle, self.handle) 384*f81fb7c4SAndroid Build Coastguard Worker if result: 385*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_Pause error %d on file %s' % (result, self.path), 'EAS_Pause') 386*f81fb7c4SAndroid Build Coastguard Worker 387*f81fb7c4SAndroid Build Coastguard Worker def Resume (self): 388*f81fb7c4SAndroid Build Coastguard Worker """Resume a stream.""" 389*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_Resume') 390*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 391*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_Resume(self.eas.handle, self.handle) 392*f81fb7c4SAndroid Build Coastguard Worker if result: 393*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_Resume error %d on file %s' % (result, self.path), 'EAS_Resume') 394*f81fb7c4SAndroid Build Coastguard Worker 395*f81fb7c4SAndroid Build Coastguard Worker def Locate (self, secs, offset=False): 396*f81fb7c4SAndroid Build Coastguard Worker """Set the playback position of a stream in seconds.""" 397*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_Locate: location=%.3f, relative=%s' % (secs, offset)) 398*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 399*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_Locate(self.eas.handle, self.handle, int(secs * 1000 + 0.5), offset) 400*f81fb7c4SAndroid Build Coastguard Worker if result: 401*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_Locate error %d on file %s' % (result, self.path), 'EAS_Locate') 402*f81fb7c4SAndroid Build Coastguard Worker 403*f81fb7c4SAndroid Build Coastguard Worker def GetLocation (self): 404*f81fb7c4SAndroid Build Coastguard Worker """Get the stream location in seconds.""" 405*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetLocation') 406*f81fb7c4SAndroid Build Coastguard Worker msecs = c_int(0) 407*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 408*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetLocation(self.eas.handle, self.handle, byref(msecs)) 409*f81fb7c4SAndroid Build Coastguard Worker if result: 410*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetLocation error %d on file %s' % (result, self.path), 'EAS_GetLocation') 411*f81fb7c4SAndroid Build Coastguard Worker msecs = float(msecs.value) / 1000 412*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_GetLocation: location=%.3f' % msecs) 413*f81fb7c4SAndroid Build Coastguard Worker return msecs 414*f81fb7c4SAndroid Build Coastguard Worker 415*f81fb7c4SAndroid Build Coastguard Worker def GetFileType (self): 416*f81fb7c4SAndroid Build Coastguard Worker """Get the file type.""" 417*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetFileType') 418*f81fb7c4SAndroid Build Coastguard Worker file_type = c_int(0) 419*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 420*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetFileType(self.eas.handle, self.handle, byref(file_type)) 421*f81fb7c4SAndroid Build Coastguard Worker if result: 422*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetFileType error %d on file %s' % (result, self.path), 'EAS_GetFileType') 423*f81fb7c4SAndroid Build Coastguard Worker file_type = file_type.value 424*f81fb7c4SAndroid Build Coastguard Worker if file_type < len(file_types): 425*f81fb7c4SAndroid Build Coastguard Worker file_desc = file_types[file_type] 426*f81fb7c4SAndroid Build Coastguard Worker else: 427*f81fb7c4SAndroid Build Coastguard Worker file_desc = 'Unrecognized type %d' % file_type 428*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_GetFileType: type=%d, desc=%s' % (file_type, file_desc)) 429*f81fb7c4SAndroid Build Coastguard Worker return (file_type, file_desc) 430*f81fb7c4SAndroid Build Coastguard Worker 431*f81fb7c4SAndroid Build Coastguard Worker def SetRepeat (self, count): 432*f81fb7c4SAndroid Build Coastguard Worker """Set the repeat count of a stream.""" 433*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetRepeat: count=%d' % count) 434*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 435*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetRepeat(self.eas.handle, self.handle, count) 436*f81fb7c4SAndroid Build Coastguard Worker if result: 437*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetRepeat error %d on file %s' % (result, self.path), 'EAS_SetRepeat') 438*f81fb7c4SAndroid Build Coastguard Worker 439*f81fb7c4SAndroid Build Coastguard Worker def GetRepeat (self): 440*f81fb7c4SAndroid Build Coastguard Worker """Get the repeat count of a stream.""" 441*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetRepeat') 442*f81fb7c4SAndroid Build Coastguard Worker count = c_int(0) 443*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 444*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetRepeat(self.eas.handle, self.handle, byref(count)) 445*f81fb7c4SAndroid Build Coastguard Worker if result: 446*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetRepeat error %d on file %s' % (result, self.path), 'EAS_GetRepeat') 447*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_GetRepeat: count=%d' % count.value) 448*f81fb7c4SAndroid Build Coastguard Worker return count.value 449*f81fb7c4SAndroid Build Coastguard Worker 450*f81fb7c4SAndroid Build Coastguard Worker def SetPlaybackRate (self, rate): 451*f81fb7c4SAndroid Build Coastguard Worker """Set the playback rate of a stream.""" 452*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetPlaybackRate') 453*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 454*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetPlaybackRate(self.eas.handle, self.handle, rate) 455*f81fb7c4SAndroid Build Coastguard Worker if result: 456*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetPlaybackRate error %d on file %s' % (result, self.path), 'EAS_SetPlaybackRate') 457*f81fb7c4SAndroid Build Coastguard Worker 458*f81fb7c4SAndroid Build Coastguard Worker def ParseMetaData (self): 459*f81fb7c4SAndroid Build Coastguard Worker """Parse the metadata in a file.""" 460*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_ParseMetaData') 461*f81fb7c4SAndroid Build Coastguard Worker length = c_int(0) 462*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 463*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_ParseMetaData(self.eas.handle, self.handle, byref(length)) 464*f81fb7c4SAndroid Build Coastguard Worker if result: 465*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_ParseMetaData error %d on file %s' % (result, self.path), 'EAS_ParseMetaData') 466*f81fb7c4SAndroid Build Coastguard Worker return float(length.value) / 1000.0 467*f81fb7c4SAndroid Build Coastguard Worker 468*f81fb7c4SAndroid Build Coastguard Worker def RegisterMetaDataCallback (self, func, buf, buf_size, user_data): 469*f81fb7c4SAndroid Build Coastguard Worker """Register a metadata callback.""" 470*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_RegisterMetaDataCallback') 471*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 472*f81fb7c4SAndroid Build Coastguard Worker if func is not None: 473*f81fb7c4SAndroid Build Coastguard Worker callback = EAS_METADATA_CBFUNC(func) 474*f81fb7c4SAndroid Build Coastguard Worker else: 475*f81fb7c4SAndroid Build Coastguard Worker callback = 0 476*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_RegisterMetaDataCallback(self.eas.handle, self.handle, callback, buf, buf_size, user_data) 477*f81fb7c4SAndroid Build Coastguard Worker if result: 478*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_RegisterMetaDataCallback error %d on file %s' % (result, self.path), 'EAS_RegisterMetaDataCallback') 479*f81fb7c4SAndroid Build Coastguard Worker 480*f81fb7c4SAndroid Build Coastguard Worker def GetWaveFmtChunk (self): 481*f81fb7c4SAndroid Build Coastguard Worker """Get the file type.""" 482*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetWaveFmtChunk') 483*f81fb7c4SAndroid Build Coastguard Worker wave_fmt_chunk = c_void_p(0) 484*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 485*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetWaveFmtChunk(self.eas.handle, self.handle, byref(wave_fmt_chunk)) 486*f81fb7c4SAndroid Build Coastguard Worker if result: 487*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetWaveFmtChunk error %d on file %s' % (result, self.path), 'EAS_GetWaveFmtChunk') 488*f81fb7c4SAndroid Build Coastguard Worker return cast(wave_fmt_chunk, POINTER(WAVEFORMAT)).contents 489*f81fb7c4SAndroid Build Coastguard Worker 490*f81fb7c4SAndroid Build Coastguard Worker def Play (self, max_time=None): 491*f81fb7c4SAndroid Build Coastguard Worker """Plays the file to the end or max_time.""" 492*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_File.Play') 493*f81fb7c4SAndroid Build Coastguard Worker if not self.prepared: 494*f81fb7c4SAndroid Build Coastguard Worker self.Prepare() 495*f81fb7c4SAndroid Build Coastguard Worker if max_time is not None: 496*f81fb7c4SAndroid Build Coastguard Worker max_time += self.eas.GetRenderTime() 497*f81fb7c4SAndroid Build Coastguard Worker while self.State() not in (EAS_STATE_STOPPED, EAS_STATE_ERROR, EAS_STATE_EMPTY): 498*f81fb7c4SAndroid Build Coastguard Worker self.eas.Render() 499*f81fb7c4SAndroid Build Coastguard Worker if max_time is not None: 500*f81fb7c4SAndroid Build Coastguard Worker if self.eas.GetRenderTime() >= max_time: 501*f81fb7c4SAndroid Build Coastguard Worker eas_logger.info('Max render time exceeded - stopping playback') 502*f81fb7c4SAndroid Build Coastguard Worker self.Pause() 503*f81fb7c4SAndroid Build Coastguard Worker self.eas.Render() 504*f81fb7c4SAndroid Build Coastguard Worker break 505*f81fb7c4SAndroid Build Coastguard Worker 506*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 507*f81fb7c4SAndroid Build Coastguard Worker# EAS_MIDIStream 508*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 509*f81fb7c4SAndroid Build Coastguard Workerclass EAS_MIDIStream (EAS_Stream): 510*f81fb7c4SAndroid Build Coastguard Worker def Write(self, data): 511*f81fb7c4SAndroid Build Coastguard Worker """Write data to MIDI stream.""" 512*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 513*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_WriteMIDIStream(self.eas.handle, self.handle, data, len(data)) 514*f81fb7c4SAndroid Build Coastguard Worker if result: 515*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_WriteMIDIStream error %d' % result, 'EAS_WriteMIDIStream') 516*f81fb7c4SAndroid Build Coastguard Worker 517*f81fb7c4SAndroid Build Coastguard Worker def Close (self): 518*f81fb7c4SAndroid Build Coastguard Worker """Close MIDI stream.""" 519*f81fb7c4SAndroid Build Coastguard Worker if hasattr(self, 'handle'): 520*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 521*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_CloseMIDIStream') 522*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_CloseMIDIStream(self.eas.handle, self.handle) 523*f81fb7c4SAndroid Build Coastguard Worker if result: 524*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_CloseFile error %d' % result, 'EAS_CloseMIDIStream') 525*f81fb7c4SAndroid Build Coastguard Worker 526*f81fb7c4SAndroid Build Coastguard Worker # remove file from the EAS object 527*f81fb7c4SAndroid Build Coastguard Worker self.eas.audio_streams.remove(self) 528*f81fb7c4SAndroid Build Coastguard Worker 529*f81fb7c4SAndroid Build Coastguard Worker # clean up references 530*f81fb7c4SAndroid Build Coastguard Worker del self.handle 531*f81fb7c4SAndroid Build Coastguard Worker del self.eas 532*f81fb7c4SAndroid Build Coastguard Worker 533*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 534*f81fb7c4SAndroid Build Coastguard Worker# EAS_Config 535*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 536*f81fb7c4SAndroid Build Coastguard Workerclass EAS_Config (Structure): 537*f81fb7c4SAndroid Build Coastguard Worker _fields_ = [('libVersion', c_ulong), 538*f81fb7c4SAndroid Build Coastguard Worker ('checkedVersion', c_int), 539*f81fb7c4SAndroid Build Coastguard Worker ('maxVoices', c_long), 540*f81fb7c4SAndroid Build Coastguard Worker ('numChannels', c_long), 541*f81fb7c4SAndroid Build Coastguard Worker ('sampleRate', c_long), 542*f81fb7c4SAndroid Build Coastguard Worker ('mixBufferSize', c_long), 543*f81fb7c4SAndroid Build Coastguard Worker ('filterEnabled', c_int), 544*f81fb7c4SAndroid Build Coastguard Worker ('buildTimeStamp', c_ulong), 545*f81fb7c4SAndroid Build Coastguard Worker ('buildGUID', c_char_p)] 546*f81fb7c4SAndroid Build Coastguard Worker 547*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 548*f81fb7c4SAndroid Build Coastguard Worker# EAS 549*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 550*f81fb7c4SAndroid Build Coastguard Workerclass EAS (object): 551*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, handle=None, dll_path=None, log_file=None): 552*f81fb7c4SAndroid Build Coastguard Worker if eas_dll is None: 553*f81fb7c4SAndroid Build Coastguard Worker InitEASModule(dll_path) 554*f81fb7c4SAndroid Build Coastguard Worker if log_file is not None: 555*f81fb7c4SAndroid Build Coastguard Worker eas_logger.addHandler(log_file) 556*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS.__init__') 557*f81fb7c4SAndroid Build Coastguard Worker self.Init(handle) 558*f81fb7c4SAndroid Build Coastguard Worker 559*f81fb7c4SAndroid Build Coastguard Worker def __del__ (self): 560*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS.__del__') 561*f81fb7c4SAndroid Build Coastguard Worker self.Shutdown() 562*f81fb7c4SAndroid Build Coastguard Worker 563*f81fb7c4SAndroid Build Coastguard Worker def Init (self, handle=None): 564*f81fb7c4SAndroid Build Coastguard Worker """Initializes the EAS Library.""" 565*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS.Init') 566*f81fb7c4SAndroid Build Coastguard Worker 567*f81fb7c4SAndroid Build Coastguard Worker # if we are already initialized, shutdown first 568*f81fb7c4SAndroid Build Coastguard Worker if hasattr(self, 'handle'): 569*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS.Init called with library already initalized') 570*f81fb7c4SAndroid Build Coastguard Worker self.ShutDown() 571*f81fb7c4SAndroid Build Coastguard Worker 572*f81fb7c4SAndroid Build Coastguard Worker # setup the logging function 573*f81fb7c4SAndroid Build Coastguard Worker eas_dll.SetLogCallback(LogCallback) 574*f81fb7c4SAndroid Build Coastguard Worker 575*f81fb7c4SAndroid Build Coastguard Worker # create some members 576*f81fb7c4SAndroid Build Coastguard Worker self.handle = c_void_p(0) 577*f81fb7c4SAndroid Build Coastguard Worker self.audio_streams = [] 578*f81fb7c4SAndroid Build Coastguard Worker self.output_streams = [] 579*f81fb7c4SAndroid Build Coastguard Worker self.aux_mixer = None 580*f81fb7c4SAndroid Build Coastguard Worker 581*f81fb7c4SAndroid Build Coastguard Worker # create a sync lock 582*f81fb7c4SAndroid Build Coastguard Worker self.lock = threading.RLock() 583*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 584*f81fb7c4SAndroid Build Coastguard Worker # set log callback 585*f81fb7c4SAndroid Build Coastguard Worker 586*f81fb7c4SAndroid Build Coastguard Worker # get library configuration 587*f81fb7c4SAndroid Build Coastguard Worker self.Config() 588*f81fb7c4SAndroid Build Coastguard Worker 589*f81fb7c4SAndroid Build Coastguard Worker # initialize library 590*f81fb7c4SAndroid Build Coastguard Worker if handle is None: 591*f81fb7c4SAndroid Build Coastguard Worker self.do_shutdown = True 592*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_Init') 593*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_Init(byref(self.handle)) 594*f81fb7c4SAndroid Build Coastguard Worker if result: 595*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_Init error %d' % result, 'EAS_Init') 596*f81fb7c4SAndroid Build Coastguard Worker else: 597*f81fb7c4SAndroid Build Coastguard Worker self.do_shutdown = False 598*f81fb7c4SAndroid Build Coastguard Worker self.handle = handle 599*f81fb7c4SAndroid Build Coastguard Worker 600*f81fb7c4SAndroid Build Coastguard Worker # allocate audio buffer for rendering 601*f81fb7c4SAndroid Build Coastguard Worker AudioBufferType = c_ubyte * (2 * self.config.mixBufferSize * self.config.numChannels) 602*f81fb7c4SAndroid Build Coastguard Worker self.audio_buffer = AudioBufferType() 603*f81fb7c4SAndroid Build Coastguard Worker self.buf_size = self.config.mixBufferSize 604*f81fb7c4SAndroid Build Coastguard Worker 605*f81fb7c4SAndroid Build Coastguard Worker def Config (self): 606*f81fb7c4SAndroid Build Coastguard Worker """Retrieves the EAS library configuration""" 607*f81fb7c4SAndroid Build Coastguard Worker if not hasattr(self, 'config'): 608*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_Config') 609*f81fb7c4SAndroid Build Coastguard Worker eas_dll.EAS_Config.restype = POINTER(EAS_Config) 610*f81fb7c4SAndroid Build Coastguard Worker self.config = eas_dll.EAS_Config()[0] 611*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug("libVersion=%08x, maxVoices=%d, numChannels=%d, sampleRate = %d, mixBufferSize=%d" % 612*f81fb7c4SAndroid Build Coastguard Worker (self.config.libVersion, self.config.maxVoices, self.config.numChannels, self.config.sampleRate, self.config.mixBufferSize)) 613*f81fb7c4SAndroid Build Coastguard Worker 614*f81fb7c4SAndroid Build Coastguard Worker def Shutdown (self): 615*f81fb7c4SAndroid Build Coastguard Worker """Shuts down the EAS library""" 616*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS.Shutdown') 617*f81fb7c4SAndroid Build Coastguard Worker if hasattr(self, 'handle'): 618*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 619*f81fb7c4SAndroid Build Coastguard Worker # close audio streams 620*f81fb7c4SAndroid Build Coastguard Worker audio_streams = self.audio_streams 621*f81fb7c4SAndroid Build Coastguard Worker for f in audio_streams: 622*f81fb7c4SAndroid Build Coastguard Worker eas_logger.warning('Stream was not closed before EAS_Shutdown') 623*f81fb7c4SAndroid Build Coastguard Worker f.Close() 624*f81fb7c4SAndroid Build Coastguard Worker 625*f81fb7c4SAndroid Build Coastguard Worker # close output streams 626*f81fb7c4SAndroid Build Coastguard Worker output_streams = self.output_streams 627*f81fb7c4SAndroid Build Coastguard Worker for s in output_streams: 628*f81fb7c4SAndroid Build Coastguard Worker s.close() 629*f81fb7c4SAndroid Build Coastguard Worker 630*f81fb7c4SAndroid Build Coastguard Worker # shutdown library 631*f81fb7c4SAndroid Build Coastguard Worker if self.do_shutdown: 632*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_Shutdown') 633*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_Shutdown(self.handle) 634*f81fb7c4SAndroid Build Coastguard Worker if result: 635*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_Shutdown error %d' % result, 'EAS_Shutdown') 636*f81fb7c4SAndroid Build Coastguard Worker del self.handle 637*f81fb7c4SAndroid Build Coastguard Worker 638*f81fb7c4SAndroid Build Coastguard Worker def OpenFile (self, path): 639*f81fb7c4SAndroid Build Coastguard Worker """Opens an audio file to be played by the EAS library and 640*f81fb7c4SAndroid Build Coastguard Worker returns an EAS_File object 641*f81fb7c4SAndroid Build Coastguard Worker 642*f81fb7c4SAndroid Build Coastguard Worker Arguments: 643*f81fb7c4SAndroid Build Coastguard Worker path - path to audio file 644*f81fb7c4SAndroid Build Coastguard Worker 645*f81fb7c4SAndroid Build Coastguard Worker Returns: 646*f81fb7c4SAndroid Build Coastguard Worker EAS_File 647*f81fb7c4SAndroid Build Coastguard Worker 648*f81fb7c4SAndroid Build Coastguard Worker """ 649*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 650*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_OpenFile for file: %s' % path) 651*f81fb7c4SAndroid Build Coastguard Worker stream_handle = c_void_p(0) 652*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_OpenFile(self.handle, path, byref(stream_handle)) 653*f81fb7c4SAndroid Build Coastguard Worker if result: 654*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_OpenFile error %d on file %s' % (result, path), 'EAS_OpenFile') 655*f81fb7c4SAndroid Build Coastguard Worker 656*f81fb7c4SAndroid Build Coastguard Worker # create file object and save in list 657*f81fb7c4SAndroid Build Coastguard Worker stream = EAS_File(path, stream_handle, self) 658*f81fb7c4SAndroid Build Coastguard Worker self.audio_streams.append(stream) 659*f81fb7c4SAndroid Build Coastguard Worker return stream 660*f81fb7c4SAndroid Build Coastguard Worker 661*f81fb7c4SAndroid Build Coastguard Worker def OpenMIDIStream (self, stream=None): 662*f81fb7c4SAndroid Build Coastguard Worker """Opens a MIDI stream. 663*f81fb7c4SAndroid Build Coastguard Worker 664*f81fb7c4SAndroid Build Coastguard Worker Arguments: 665*f81fb7c4SAndroid Build Coastguard Worker stream - open stream object. If None, a new synth 666*f81fb7c4SAndroid Build Coastguard Worker is created. 667*f81fb7c4SAndroid Build Coastguard Worker 668*f81fb7c4SAndroid Build Coastguard Worker Returns: 669*f81fb7c4SAndroid Build Coastguard Worker EAS_MIDIStream 670*f81fb7c4SAndroid Build Coastguard Worker 671*f81fb7c4SAndroid Build Coastguard Worker """ 672*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 673*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_OpenMIDIStream') 674*f81fb7c4SAndroid Build Coastguard Worker stream_handle = c_void_p(0) 675*f81fb7c4SAndroid Build Coastguard Worker if stream.handle is not None: 676*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_OpenMIDIStream(self.handle, byref(stream_handle), stream.handle) 677*f81fb7c4SAndroid Build Coastguard Worker else: 678*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_OpenMIDIStream(self.handle, byref(stream_handle), 0) 679*f81fb7c4SAndroid Build Coastguard Worker if result: 680*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_OpenMIDIStream error %d' % result, 'EAS_OpenMIDIStream') 681*f81fb7c4SAndroid Build Coastguard Worker 682*f81fb7c4SAndroid Build Coastguard Worker # create stream object and save in list 683*f81fb7c4SAndroid Build Coastguard Worker stream = EAS_MIDIStream(stream_handle, self) 684*f81fb7c4SAndroid Build Coastguard Worker self.audio_streams.append(stream) 685*f81fb7c4SAndroid Build Coastguard Worker return stream 686*f81fb7c4SAndroid Build Coastguard Worker 687*f81fb7c4SAndroid Build Coastguard Worker def OpenToneControlStream (self, path): 688*f81fb7c4SAndroid Build Coastguard Worker """Opens an MMAPI tone control file to be played by the EAS 689*f81fb7c4SAndroid Build Coastguard Worker library and returns an EAS_File object 690*f81fb7c4SAndroid Build Coastguard Worker 691*f81fb7c4SAndroid Build Coastguard Worker Arguments: 692*f81fb7c4SAndroid Build Coastguard Worker path - path to audio file 693*f81fb7c4SAndroid Build Coastguard Worker 694*f81fb7c4SAndroid Build Coastguard Worker Returns: 695*f81fb7c4SAndroid Build Coastguard Worker EAS_File 696*f81fb7c4SAndroid Build Coastguard Worker 697*f81fb7c4SAndroid Build Coastguard Worker """ 698*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 699*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_MMAPIToneControl for file: %s' % path) 700*f81fb7c4SAndroid Build Coastguard Worker stream_handle = c_void_p(0) 701*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_MMAPIToneControl(self.handle, path, byref(stream_handle)) 702*f81fb7c4SAndroid Build Coastguard Worker if result: 703*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_MMAPIToneControl error %d on file %s' % (result, path), 'EAS_OpenToneControlStream') 704*f81fb7c4SAndroid Build Coastguard Worker 705*f81fb7c4SAndroid Build Coastguard Worker # create file object and save in list 706*f81fb7c4SAndroid Build Coastguard Worker stream = EAS_File(path, stream_handle, self) 707*f81fb7c4SAndroid Build Coastguard Worker self.audio_streams.append(stream) 708*f81fb7c4SAndroid Build Coastguard Worker return stream 709*f81fb7c4SAndroid Build Coastguard Worker 710*f81fb7c4SAndroid Build Coastguard Worker def Attach (self, stream): 711*f81fb7c4SAndroid Build Coastguard Worker """Attach a file or output device to the EAS output. 712*f81fb7c4SAndroid Build Coastguard Worker 713*f81fb7c4SAndroid Build Coastguard Worker The stream object must support the following methods as 714*f81fb7c4SAndroid Build Coastguard Worker defined in the Python wave module: 715*f81fb7c4SAndroid Build Coastguard Worker close() 716*f81fb7c4SAndroid Build Coastguard Worker setparams() 717*f81fb7c4SAndroid Build Coastguard Worker writeframesraw() 718*f81fb7c4SAndroid Build Coastguard Worker 719*f81fb7c4SAndroid Build Coastguard Worker Arguments: 720*f81fb7c4SAndroid Build Coastguard Worker stream - open wave object 721*f81fb7c4SAndroid Build Coastguard Worker 722*f81fb7c4SAndroid Build Coastguard Worker """ 723*f81fb7c4SAndroid Build Coastguard Worker self.output_streams.append(stream) 724*f81fb7c4SAndroid Build Coastguard Worker stream.setparams((self.config.numChannels, 2, self.config.sampleRate, 0, 'NONE', None)) 725*f81fb7c4SAndroid Build Coastguard Worker 726*f81fb7c4SAndroid Build Coastguard Worker def Detach (self, stream): 727*f81fb7c4SAndroid Build Coastguard Worker """Detach a file or output device from the EAS output. See 728*f81fb7c4SAndroid Build Coastguard Worker EAS.Attach for more details. It is the responsibility of 729*f81fb7c4SAndroid Build Coastguard Worker the caller to close the wave file or stream. 730*f81fb7c4SAndroid Build Coastguard Worker 731*f81fb7c4SAndroid Build Coastguard Worker Arguments: 732*f81fb7c4SAndroid Build Coastguard Worker stream - open and attached wave object 733*f81fb7c4SAndroid Build Coastguard Worker """ 734*f81fb7c4SAndroid Build Coastguard Worker self.output_streams.remove(stream) 735*f81fb7c4SAndroid Build Coastguard Worker 736*f81fb7c4SAndroid Build Coastguard Worker def StartWave (self, dev_num=0, sampleRate=None, maxBufSize=None): 737*f81fb7c4SAndroid Build Coastguard Worker """Route the audio output to the indicated wave device. Note 738*f81fb7c4SAndroid Build Coastguard Worker that this can cause EASDLL.EAS_RenderWaveOut to return an 739*f81fb7c4SAndroid Build Coastguard Worker error code if all the output buffers are full. In this case, 740*f81fb7c4SAndroid Build Coastguard Worker the render thread should sleep a bit and try again. 741*f81fb7c4SAndroid Build Coastguard Worker Unfortunately, due to the nature of the MMSYSTEM interface, 742*f81fb7c4SAndroid Build Coastguard Worker there is no simple way to suspend the render thread. 743*f81fb7c4SAndroid Build Coastguard Worker 744*f81fb7c4SAndroid Build Coastguard Worker """ 745*f81fb7c4SAndroid Build Coastguard Worker if sampleRate == None: 746*f81fb7c4SAndroid Build Coastguard Worker sampleRate = self.config.sampleRate 747*f81fb7c4SAndroid Build Coastguard Worker if maxBufSize == None: 748*f81fb7c4SAndroid Build Coastguard Worker maxBufSize = self.config.mixBufferSize 749*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 750*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.OpenWaveOutDevice(dev_num, sampleRate, maxBufSize) 751*f81fb7c4SAndroid Build Coastguard Worker if result: 752*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'OpenWaveOutDevice error %d' % result, 'OpenWaveOutDevice') 753*f81fb7c4SAndroid Build Coastguard Worker 754*f81fb7c4SAndroid Build Coastguard Worker def StopWave (self): 755*f81fb7c4SAndroid Build Coastguard Worker """Stop routing audio output to the audio device.""" 756*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 757*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.CloseWaveOutDevice() 758*f81fb7c4SAndroid Build Coastguard Worker if result: 759*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'CloseWaveOutDevice error %d' % result, 'CloseWaveOutDevice') 760*f81fb7c4SAndroid Build Coastguard Worker 761*f81fb7c4SAndroid Build Coastguard Worker def Render (self, count=None, secs=None): 762*f81fb7c4SAndroid Build Coastguard Worker """Calls EAS_Render to render audio. 763*f81fb7c4SAndroid Build Coastguard Worker 764*f81fb7c4SAndroid Build Coastguard Worker Arguments 765*f81fb7c4SAndroid Build Coastguard Worker count - number of buffers to render 766*f81fb7c4SAndroid Build Coastguard Worker secs - number of seconds to render 767*f81fb7c4SAndroid Build Coastguard Worker 768*f81fb7c4SAndroid Build Coastguard Worker If both count and secs are None, render a single buffer. 769*f81fb7c4SAndroid Build Coastguard Worker 770*f81fb7c4SAndroid Build Coastguard Worker """ 771*f81fb7c4SAndroid Build Coastguard Worker 772*f81fb7c4SAndroid Build Coastguard Worker # determine number of buffers to render 773*f81fb7c4SAndroid Build Coastguard Worker if count is None: 774*f81fb7c4SAndroid Build Coastguard Worker if secs is not None: 775*f81fb7c4SAndroid Build Coastguard Worker count = int(secs * float(self.config.sampleRate) / float(self.buf_size) + 0.5) 776*f81fb7c4SAndroid Build Coastguard Worker else: 777*f81fb7c4SAndroid Build Coastguard Worker count = 1 778*f81fb7c4SAndroid Build Coastguard Worker 779*f81fb7c4SAndroid Build Coastguard Worker # render buffers 780*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('rendering %d buffers' % count) 781*f81fb7c4SAndroid Build Coastguard Worker samplesRendered = c_long(0) 782*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 783*f81fb7c4SAndroid Build Coastguard Worker for c in range(count): 784*f81fb7c4SAndroid Build Coastguard Worker # render a buffer of audio 785*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('rendering buffer') 786*f81fb7c4SAndroid Build Coastguard Worker while 1: 787*f81fb7c4SAndroid Build Coastguard Worker if self.aux_mixer is None: 788*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_RenderWaveOut(self.handle, byref(self.audio_buffer), self.buf_size, byref(samplesRendered)) 789*f81fb7c4SAndroid Build Coastguard Worker else: 790*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_RenderAuxMixer(self.handle, byref(self.audio_buffer), byref(samplesRendered)) 791*f81fb7c4SAndroid Build Coastguard Worker 792*f81fb7c4SAndroid Build Coastguard Worker if result == 0: 793*f81fb7c4SAndroid Build Coastguard Worker break; 794*f81fb7c4SAndroid Build Coastguard Worker if result == EAS_BUFFER_FULL: 795*f81fb7c4SAndroid Build Coastguard Worker time.sleep(0.01) 796*f81fb7c4SAndroid Build Coastguard Worker else: 797*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_Render error %d' % result, 'EAS_Render') 798*f81fb7c4SAndroid Build Coastguard Worker 799*f81fb7c4SAndroid Build Coastguard Worker # output to attached streams 800*f81fb7c4SAndroid Build Coastguard Worker for s in self.output_streams: 801*f81fb7c4SAndroid Build Coastguard Worker s.writeframesraw(self.audio_buffer) 802*f81fb7c4SAndroid Build Coastguard Worker 803*f81fb7c4SAndroid Build Coastguard Worker def GetRenderTime (self): 804*f81fb7c4SAndroid Build Coastguard Worker """Get the render time in seconds.""" 805*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetRenderTime') 806*f81fb7c4SAndroid Build Coastguard Worker msecs = c_int(0) 807*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 808*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetRenderTime(self.handle, byref(msecs)) 809*f81fb7c4SAndroid Build Coastguard Worker if result: 810*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetRenderTime error %d' % result, 'EAS_GetRenderTime') 811*f81fb7c4SAndroid Build Coastguard Worker msecs = float(msecs.value) / 1000 812*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_GetRenderTime: time=%.3f' % msecs) 813*f81fb7c4SAndroid Build Coastguard Worker return msecs 814*f81fb7c4SAndroid Build Coastguard Worker 815*f81fb7c4SAndroid Build Coastguard Worker def SetVolume (self, volume): 816*f81fb7c4SAndroid Build Coastguard Worker """Set the master volume""" 817*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetVolume: volume=%d' % volume) 818*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 819*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetVolume(self.handle, 0, volume) 820*f81fb7c4SAndroid Build Coastguard Worker if result: 821*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetVolume error %d' % result, 'EAS_SetVolume') 822*f81fb7c4SAndroid Build Coastguard Worker 823*f81fb7c4SAndroid Build Coastguard Worker def GetVolume (self): 824*f81fb7c4SAndroid Build Coastguard Worker """Get the stream volume.""" 825*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetVolume') 826*f81fb7c4SAndroid Build Coastguard Worker volume = c_int(0) 827*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 828*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetVolume(self.handle, 0, byref(volume)) 829*f81fb7c4SAndroid Build Coastguard Worker if result: 830*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetVolume error %d' % result, 'EAS_GetVolume') 831*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EAS_GetVolume: volume=%d' % volume.value) 832*f81fb7c4SAndroid Build Coastguard Worker return volume.value 833*f81fb7c4SAndroid Build Coastguard Worker 834*f81fb7c4SAndroid Build Coastguard Worker def SetPolyphony (self, polyphony, synth_num=0): 835*f81fb7c4SAndroid Build Coastguard Worker """Set the polyphony of a synth.""" 836*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetSynthPolyphony: synth_num=%d, polyphony=%d' % (synth_num, polyphony)) 837*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 838*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetSynthPolyphony(self.handle, synth_num, polyphony) 839*f81fb7c4SAndroid Build Coastguard Worker if result: 840*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetSynthPolyphony error %d on synth %d' % (result, synth_num), 'EAS_SetPolyphony') 841*f81fb7c4SAndroid Build Coastguard Worker 842*f81fb7c4SAndroid Build Coastguard Worker def GetPolyphony (self, synth_num=0): 843*f81fb7c4SAndroid Build Coastguard Worker """Get the polyphony of a synth.""" 844*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetSynthPolyphony: synth_num=%d' % synth_num) 845*f81fb7c4SAndroid Build Coastguard Worker polyphony = c_int(0) 846*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 847*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetSynthPolyphony(self.handle, synth_num, byref(polyphony)) 848*f81fb7c4SAndroid Build Coastguard Worker if result: 849*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_GetSynthPolyphony error %d on synth %d' % (result, synth_num), 'EAS_GetPolyphony') 850*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetSynthPolyphony: synth_num=%d, polyphony=%d' % (synth_num, polyphony.value)) 851*f81fb7c4SAndroid Build Coastguard Worker return polyphony.value 852*f81fb7c4SAndroid Build Coastguard Worker 853*f81fb7c4SAndroid Build Coastguard Worker def SetMaxLoad (self, max_load): 854*f81fb7c4SAndroid Build Coastguard Worker """Set the maximum parser load.""" 855*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetMaxLoad: max_load=%d' % max_load) 856*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 857*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetMaxLoad(self.handle, max_load) 858*f81fb7c4SAndroid Build Coastguard Worker if result: 859*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetMaxLoad error %d' % result, 'EAS_SetMaxLoad') 860*f81fb7c4SAndroid Build Coastguard Worker 861*f81fb7c4SAndroid Build Coastguard Worker def SetParameter (self, module, param, value): 862*f81fb7c4SAndroid Build Coastguard Worker """Set a module parameter.""" 863*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetParameter: module=%d, param=%d, value=%d' % (module, param, value)) 864*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 865*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SetParameter(self.handle, module, param, value) 866*f81fb7c4SAndroid Build Coastguard Worker if result: 867*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetParameter error %d (param=%d, value=%d)' % (result, param, value), 'EAS_SetParameter') 868*f81fb7c4SAndroid Build Coastguard Worker 869*f81fb7c4SAndroid Build Coastguard Worker def GetParameter (self, module, param): 870*f81fb7c4SAndroid Build Coastguard Worker """Get the polyphony of a synth.""" 871*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_GetParameter: module=%d, param=%d' % (module, param)) 872*f81fb7c4SAndroid Build Coastguard Worker value = c_int(0) 873*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 874*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_GetParameter(self.handle, module, param, byref(value)) 875*f81fb7c4SAndroid Build Coastguard Worker if result: 876*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SetParameter error %d (param=%d)' % (result, param), 'EAS_GetParameter') 877*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetParameter: module=%d, param=%d, value=%d' % (module, param, value.value)) 878*f81fb7c4SAndroid Build Coastguard Worker return value.value 879*f81fb7c4SAndroid Build Coastguard Worker 880*f81fb7c4SAndroid Build Coastguard Worker def SelectLib (self, test_lib=False): 881*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SelectLib: test_lib=%s' % test_lib) 882*f81fb7c4SAndroid Build Coastguard Worker easdll = cdll.LoadLibrary('EASDLL') 883*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 884*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_SelectLib(self.handle, 0, test_lib) 885*f81fb7c4SAndroid Build Coastguard Worker if result: 886*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_SelectLib error %d' % result, 'EAS_SelectLib') 887*f81fb7c4SAndroid Build Coastguard Worker 888*f81fb7c4SAndroid Build Coastguard Worker def LoadDLSCollection (self, path): 889*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_LoadDLSCollection: lib_path=%s' % path) 890*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 891*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_LoadDLSCollection(self.handle, 0, path) 892*f81fb7c4SAndroid Build Coastguard Worker if result: 893*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_LoadDLSCollection error %d lib %s' % (result, path), 'EAS_LoadDLSCollection') 894*f81fb7c4SAndroid Build Coastguard Worker 895*f81fb7c4SAndroid Build Coastguard Worker def SetAuxMixerHook (self, aux_mixer): 896*f81fb7c4SAndroid Build Coastguard Worker 897*f81fb7c4SAndroid Build Coastguard Worker # if aux mixer has bigger buffer, re-allocate buffer 898*f81fb7c4SAndroid Build Coastguard Worker if (aux_mixer is not None) and (aux_mixer.buf_size > self.config.mixBufferSize): 899*f81fb7c4SAndroid Build Coastguard Worker buf_size = aux_mixer.buf_size 900*f81fb7c4SAndroid Build Coastguard Worker else: 901*f81fb7c4SAndroid Build Coastguard Worker buf_size = self.config.mixBufferSize 902*f81fb7c4SAndroid Build Coastguard Worker 903*f81fb7c4SAndroid Build Coastguard Worker # allocate audio buffer for rendering 904*f81fb7c4SAndroid Build Coastguard Worker AudioBufferType = c_ubyte * (2 * buf_size * self.config.numChannels) 905*f81fb7c4SAndroid Build Coastguard Worker self.audio_buffer = AudioBufferType() 906*f81fb7c4SAndroid Build Coastguard Worker self.buf_size = buf_size 907*f81fb7c4SAndroid Build Coastguard Worker self.aux_mixer = aux_mixer 908*f81fb7c4SAndroid Build Coastguard Worker 909*f81fb7c4SAndroid Build Coastguard Worker def SetDebugLevel (self, level=3): 910*f81fb7c4SAndroid Build Coastguard Worker """Sets the EAS debug level.""" 911*f81fb7c4SAndroid Build Coastguard Worker with self.lock: 912*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_SetDebugLevel') 913*f81fb7c4SAndroid Build Coastguard Worker eas_dll.EAS_DLLSetDebugLevel(self.handle, level) 914*f81fb7c4SAndroid Build Coastguard Worker 915*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 916*f81fb7c4SAndroid Build Coastguard Worker# EASAuxMixer 917*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 918*f81fb7c4SAndroid Build Coastguard Workerclass EASAuxMixer (object): 919*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, eas=None, num_streams=3, sample_rate=44100, max_sample_rate=44100): 920*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EASAuxMixer.__init__') 921*f81fb7c4SAndroid Build Coastguard Worker self.Init(eas, num_streams, sample_rate, max_sample_rate) 922*f81fb7c4SAndroid Build Coastguard Worker 923*f81fb7c4SAndroid Build Coastguard Worker def __del__ (self): 924*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EASAuxMixer.__del__') 925*f81fb7c4SAndroid Build Coastguard Worker self.Shutdown() 926*f81fb7c4SAndroid Build Coastguard Worker 927*f81fb7c4SAndroid Build Coastguard Worker def Init (self, eas=None, num_streams=3, sample_rate=44100, max_sample_rate=44100): 928*f81fb7c4SAndroid Build Coastguard Worker """Initializes the EAS Auxilliary Mixer.""" 929*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EASAuxMixer.Init') 930*f81fb7c4SAndroid Build Coastguard Worker 931*f81fb7c4SAndroid Build Coastguard Worker if hasattr(self, 'eas'): 932*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(-1, 'EASAuxMixer already initialized', 'EASAuxMixer.Init') 933*f81fb7c4SAndroid Build Coastguard Worker 934*f81fb7c4SAndroid Build Coastguard Worker # initialize EAS, if necessary 935*f81fb7c4SAndroid Build Coastguard Worker if eas is None: 936*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('No EAS handle --- initializing EAS') 937*f81fb7c4SAndroid Build Coastguard Worker eas = EAS() 938*f81fb7c4SAndroid Build Coastguard Worker self.alloc_eas = True 939*f81fb7c4SAndroid Build Coastguard Worker else: 940*f81fb7c4SAndroid Build Coastguard Worker self.alloc_eas = False 941*f81fb7c4SAndroid Build Coastguard Worker self.eas = eas 942*f81fb7c4SAndroid Build Coastguard Worker 943*f81fb7c4SAndroid Build Coastguard Worker # initialize library 944*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_InitAuxMixer') 945*f81fb7c4SAndroid Build Coastguard Worker buf_size = c_int(0) 946*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_InitAuxMixer(eas.handle, num_streams, sample_rate, max_sample_rate, byref(buf_size)) 947*f81fb7c4SAndroid Build Coastguard Worker if result: 948*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_InitAuxMixer error %d' % result, 'EAS_InitAuxMixer') 949*f81fb7c4SAndroid Build Coastguard Worker self.buf_size = buf_size.value 950*f81fb7c4SAndroid Build Coastguard Worker self.streams = [] 951*f81fb7c4SAndroid Build Coastguard Worker eas.SetAuxMixerHook(self) 952*f81fb7c4SAndroid Build Coastguard Worker 953*f81fb7c4SAndroid Build Coastguard Worker def Shutdown (self): 954*f81fb7c4SAndroid Build Coastguard Worker """Shuts down the EAS Auxilliary Mixer""" 955*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('EASAuxMixer.Shutdown') 956*f81fb7c4SAndroid Build Coastguard Worker if not hasattr(self, 'eas'): 957*f81fb7c4SAndroid Build Coastguard Worker return 958*f81fb7c4SAndroid Build Coastguard Worker 959*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 960*f81fb7c4SAndroid Build Coastguard Worker if len(self.streams): 961*f81fb7c4SAndroid Build Coastguard Worker eas_logger.warning('Stream was not closed before EAS_ShutdownAuxMixer') 962*f81fb7c4SAndroid Build Coastguard Worker for stream in self.streams: 963*f81fb7c4SAndroid Build Coastguard Worker self.CloseStream(stream) 964*f81fb7c4SAndroid Build Coastguard Worker 965*f81fb7c4SAndroid Build Coastguard Worker self.eas.SetAuxMixerHook(None) 966*f81fb7c4SAndroid Build Coastguard Worker 967*f81fb7c4SAndroid Build Coastguard Worker # shutdown library 968*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_ShutdownAuxMixer') 969*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_ShutdownAuxMixer(self.eas.handle) 970*f81fb7c4SAndroid Build Coastguard Worker if result: 971*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_ShutdownAuxMixer error %d' % result, 'EAS_ShutdownAuxMixer') 972*f81fb7c4SAndroid Build Coastguard Worker 973*f81fb7c4SAndroid Build Coastguard Worker # if we created the EAS reference here, shut it down 974*f81fb7c4SAndroid Build Coastguard Worker if self.alloc_eas: 975*f81fb7c4SAndroid Build Coastguard Worker self.eas.Shutdown() 976*f81fb7c4SAndroid Build Coastguard Worker self.alloc_eas = False 977*f81fb7c4SAndroid Build Coastguard Worker del self.eas 978*f81fb7c4SAndroid Build Coastguard Worker 979*f81fb7c4SAndroid Build Coastguard Worker def OpenStream (self, decoder_func, inst_data, sample_rate, num_channels): 980*f81fb7c4SAndroid Build Coastguard Worker """Opens an audio file to be played by the JET library and 981*f81fb7c4SAndroid Build Coastguard Worker returns a JET_File object 982*f81fb7c4SAndroid Build Coastguard Worker 983*f81fb7c4SAndroid Build Coastguard Worker Arguments: 984*f81fb7c4SAndroid Build Coastguard Worker callback - callback function to decode more audio 985*f81fb7c4SAndroid Build Coastguard Worker 986*f81fb7c4SAndroid Build Coastguard Worker """ 987*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 988*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_OpenAudioStream') 989*f81fb7c4SAndroid Build Coastguard Worker decoder_func = EAS_DECODER_FUNC(decoder_func) 990*f81fb7c4SAndroid Build Coastguard Worker stream_handle = c_void_p(0) 991*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.EAS_OpenAudioStream(self.eas.handle, decoder_func, inst_data, sample_rate, num_channels, stream_handle) 992*f81fb7c4SAndroid Build Coastguard Worker if result: 993*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_OpenAudioStream error %d on file %s' % (result, path), 'EAS_OpenAudioStream') 994*f81fb7c4SAndroid Build Coastguard Worker self.streams.add(stream_handle) 995*f81fb7c4SAndroid Build Coastguard Worker return stream_handle 996*f81fb7c4SAndroid Build Coastguard Worker 997*f81fb7c4SAndroid Build Coastguard Worker def CloseStream (self, stream_handle): 998*f81fb7c4SAndroid Build Coastguard Worker """Closes an open audio stream.""" 999*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1000*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call EAS_CloseAudioStream') 1001*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_CloseFile(self.eas.handle, stream_handle) 1002*f81fb7c4SAndroid Build Coastguard Worker if result: 1003*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'EAS_CloseAudioStream error %d' % result, 'EAS_CloseAudioStream') 1004*f81fb7c4SAndroid Build Coastguard Worker 1005*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 1006*f81fb7c4SAndroid Build Coastguard Worker# JET_Status 1007*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 1008*f81fb7c4SAndroid Build Coastguard Workerclass JET_Status (Structure): 1009*f81fb7c4SAndroid Build Coastguard Worker _fields_ = [('currentUserID', c_int), 1010*f81fb7c4SAndroid Build Coastguard Worker ('segmentRepeatCount', c_int), 1011*f81fb7c4SAndroid Build Coastguard Worker ('numQueuedSegments', c_int), 1012*f81fb7c4SAndroid Build Coastguard Worker ('paused', c_int), 1013*f81fb7c4SAndroid Build Coastguard Worker ('location', c_long), 1014*f81fb7c4SAndroid Build Coastguard Worker ('currentPlayingSegment', c_int), 1015*f81fb7c4SAndroid Build Coastguard Worker ('currentQueuedSegment', c_int), 1016*f81fb7c4SAndroid Build Coastguard Worker ] 1017*f81fb7c4SAndroid Build Coastguard Worker 1018*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 1019*f81fb7c4SAndroid Build Coastguard Worker# JET_File 1020*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 1021*f81fb7c4SAndroid Build Coastguard Workerclass JET_File (object): 1022*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, handle, jet): 1023*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('JET_File.__init__') 1024*f81fb7c4SAndroid Build Coastguard Worker self.handle = handle 1025*f81fb7c4SAndroid Build Coastguard Worker self.jet = jet 1026*f81fb7c4SAndroid Build Coastguard Worker 1027*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 1028*f81fb7c4SAndroid Build Coastguard Worker# JET 1029*f81fb7c4SAndroid Build Coastguard Worker#--------------------------------------------------------------- 1030*f81fb7c4SAndroid Build Coastguard Workerclass JET (object): 1031*f81fb7c4SAndroid Build Coastguard Worker def __init__ (self, eas=None): 1032*f81fb7c4SAndroid Build Coastguard Worker # eas_logger.debug('JET.__init__') 1033*f81fb7c4SAndroid Build Coastguard Worker self.Init(eas) 1034*f81fb7c4SAndroid Build Coastguard Worker 1035*f81fb7c4SAndroid Build Coastguard Worker def __del__ (self): 1036*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('JET.__del__') 1037*f81fb7c4SAndroid Build Coastguard Worker self.Shutdown() 1038*f81fb7c4SAndroid Build Coastguard Worker 1039*f81fb7c4SAndroid Build Coastguard Worker def Init (self, eas=None, config=None): 1040*f81fb7c4SAndroid Build Coastguard Worker """Initializes the JET Library.""" 1041*f81fb7c4SAndroid Build Coastguard Worker # eas_logger.debug('JET.Init') 1042*f81fb7c4SAndroid Build Coastguard Worker 1043*f81fb7c4SAndroid Build Coastguard Worker if hasattr(self, 'eas'): 1044*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(-1, 'JET library already initialized', 'Jet.Init') 1045*f81fb7c4SAndroid Build Coastguard Worker 1046*f81fb7c4SAndroid Build Coastguard Worker # create some members 1047*f81fb7c4SAndroid Build Coastguard Worker if eas is None: 1048*f81fb7c4SAndroid Build Coastguard Worker # eas_logger.debug('No EAS handle --- initializing EAS') 1049*f81fb7c4SAndroid Build Coastguard Worker eas = EAS() 1050*f81fb7c4SAndroid Build Coastguard Worker self.alloc_eas = True 1051*f81fb7c4SAndroid Build Coastguard Worker else: 1052*f81fb7c4SAndroid Build Coastguard Worker self.alloc_eas = False 1053*f81fb7c4SAndroid Build Coastguard Worker self.eas = eas 1054*f81fb7c4SAndroid Build Coastguard Worker self.fileOpen = False 1055*f81fb7c4SAndroid Build Coastguard Worker 1056*f81fb7c4SAndroid Build Coastguard Worker # handle configuration 1057*f81fb7c4SAndroid Build Coastguard Worker if config is None: 1058*f81fb7c4SAndroid Build Coastguard Worker config_handle = c_void_p(0) 1059*f81fb7c4SAndroid Build Coastguard Worker config_size = 0 1060*f81fb7c4SAndroid Build Coastguard Worker else: 1061*f81fb7c4SAndroid Build Coastguard Worker jet_config = S_JET_CONFIG() 1062*f81fb7c4SAndroid Build Coastguard Worker jet_config.appLowNote = config.appLowNote 1063*f81fb7c4SAndroid Build Coastguard Worker config_handle = c_void_p(jet_config) 1064*f81fb7c4SAndroid Build Coastguard Worker config_size = jet_config.sizeof() 1065*f81fb7c4SAndroid Build Coastguard Worker 1066*f81fb7c4SAndroid Build Coastguard Worker # initialize library 1067*f81fb7c4SAndroid Build Coastguard Worker # eas_logger.debug('Call JET_Init') 1068*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_Init(eas.handle, config_handle, config_size) 1069*f81fb7c4SAndroid Build Coastguard Worker if result: 1070*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_Init error %d' % result, 'JET_Init') 1071*f81fb7c4SAndroid Build Coastguard Worker 1072*f81fb7c4SAndroid Build Coastguard Worker def Shutdown (self): 1073*f81fb7c4SAndroid Build Coastguard Worker """Shuts down the JET library""" 1074*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('JET.Shutdown') 1075*f81fb7c4SAndroid Build Coastguard Worker if not hasattr(self, 'eas'): 1076*f81fb7c4SAndroid Build Coastguard Worker return 1077*f81fb7c4SAndroid Build Coastguard Worker 1078*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1079*f81fb7c4SAndroid Build Coastguard Worker if self.fileOpen: 1080*f81fb7c4SAndroid Build Coastguard Worker eas_logger.warning('Stream was not closed before JET_Shutdown') 1081*f81fb7c4SAndroid Build Coastguard Worker self.CloseFile() 1082*f81fb7c4SAndroid Build Coastguard Worker 1083*f81fb7c4SAndroid Build Coastguard Worker # shutdown library 1084*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_Shutdown') 1085*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_Shutdown(self.eas.handle) 1086*f81fb7c4SAndroid Build Coastguard Worker if result: 1087*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_Shutdown error %d' % result, 'JET_Shutdown') 1088*f81fb7c4SAndroid Build Coastguard Worker 1089*f81fb7c4SAndroid Build Coastguard Worker # if we created the EAS reference here, shut it down 1090*f81fb7c4SAndroid Build Coastguard Worker if self.alloc_eas: 1091*f81fb7c4SAndroid Build Coastguard Worker self.eas.Shutdown() 1092*f81fb7c4SAndroid Build Coastguard Worker self.alloc_eas = False 1093*f81fb7c4SAndroid Build Coastguard Worker del self.eas 1094*f81fb7c4SAndroid Build Coastguard Worker 1095*f81fb7c4SAndroid Build Coastguard Worker def OpenFile (self, path): 1096*f81fb7c4SAndroid Build Coastguard Worker """Opens an audio file to be played by the JET library and 1097*f81fb7c4SAndroid Build Coastguard Worker returns a JET_File object 1098*f81fb7c4SAndroid Build Coastguard Worker 1099*f81fb7c4SAndroid Build Coastguard Worker Arguments: 1100*f81fb7c4SAndroid Build Coastguard Worker path - path to audio file 1101*f81fb7c4SAndroid Build Coastguard Worker 1102*f81fb7c4SAndroid Build Coastguard Worker """ 1103*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1104*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_OpenFile for file: %s' % path) 1105*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_OpenFile(self.eas.handle, path) 1106*f81fb7c4SAndroid Build Coastguard Worker if result: 1107*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_OpenFile error %d on file %s' % (result, path), 'JET_OpenFile') 1108*f81fb7c4SAndroid Build Coastguard Worker 1109*f81fb7c4SAndroid Build Coastguard Worker def CloseFile (self): 1110*f81fb7c4SAndroid Build Coastguard Worker """Closes an open audio file.""" 1111*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1112*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_CloseFile') 1113*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_CloseFile(self.eas.handle) 1114*f81fb7c4SAndroid Build Coastguard Worker if result: 1115*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_CloseFile error %d' % result, 'JET_CloseFile') 1116*f81fb7c4SAndroid Build Coastguard Worker 1117*f81fb7c4SAndroid Build Coastguard Worker def QueueSegment (self, userID, seg_num, dls_num=-1, repeat=0, tranpose=0, mute_flags=0): 1118*f81fb7c4SAndroid Build Coastguard Worker """Queue a segment for playback. 1119*f81fb7c4SAndroid Build Coastguard Worker 1120*f81fb7c4SAndroid Build Coastguard Worker Arguments: 1121*f81fb7c4SAndroid Build Coastguard Worker seg_num - segment number to queue 1122*f81fb7c4SAndroid Build Coastguard Worker repeat - repeat count (-1=repeat forever, 0=no repeat, 1+ = play n+1 times) 1123*f81fb7c4SAndroid Build Coastguard Worker tranpose - transpose amount (+/-12) 1124*f81fb7c4SAndroid Build Coastguard Worker 1125*f81fb7c4SAndroid Build Coastguard Worker """ 1126*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1127*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_QueueSegment') 1128*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_QueueSegment(self.eas.handle, seg_num, dls_num, repeat, tranpose, mute_flags, userID) 1129*f81fb7c4SAndroid Build Coastguard Worker if result: 1130*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_QueueSegment error %d' % result, 'JET_QueueSegment') 1131*f81fb7c4SAndroid Build Coastguard Worker 1132*f81fb7c4SAndroid Build Coastguard Worker def Clear_Queue(self): 1133*f81fb7c4SAndroid Build Coastguard Worker """Kills the queue.""" 1134*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1135*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_Clear_Queue') 1136*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_Clear_Queue(self.eas.handle) 1137*f81fb7c4SAndroid Build Coastguard Worker if result: 1138*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_Clear_Queue error %d' % result, 'JET_Clear_Queue') 1139*f81fb7c4SAndroid Build Coastguard Worker 1140*f81fb7c4SAndroid Build Coastguard Worker def GetAppEvent(self): 1141*f81fb7c4SAndroid Build Coastguard Worker """Gets an App event.""" 1142*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1143*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_GetEvent') 1144*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_GetEvent(self.eas.handle, 0, 0) 1145*f81fb7c4SAndroid Build Coastguard Worker return result 1146*f81fb7c4SAndroid Build Coastguard Worker 1147*f81fb7c4SAndroid Build Coastguard Worker def Play(self): 1148*f81fb7c4SAndroid Build Coastguard Worker """Starts JET playback.""" 1149*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1150*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_Play') 1151*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_Play(self.eas.handle) 1152*f81fb7c4SAndroid Build Coastguard Worker if result: 1153*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_Play error %d' % result, 'JET_Play') 1154*f81fb7c4SAndroid Build Coastguard Worker 1155*f81fb7c4SAndroid Build Coastguard Worker def Pause(self): 1156*f81fb7c4SAndroid Build Coastguard Worker """Pauses JET playback.""" 1157*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1158*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_Pause') 1159*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_Pause(self.eas.handle) 1160*f81fb7c4SAndroid Build Coastguard Worker if result: 1161*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_Pause error %d' % result, 'JET_Pause') 1162*f81fb7c4SAndroid Build Coastguard Worker 1163*f81fb7c4SAndroid Build Coastguard Worker def Render (self, count=None, secs=None): 1164*f81fb7c4SAndroid Build Coastguard Worker """Calls EAS_Render to render audio. 1165*f81fb7c4SAndroid Build Coastguard Worker 1166*f81fb7c4SAndroid Build Coastguard Worker Arguments 1167*f81fb7c4SAndroid Build Coastguard Worker count - number of buffers to render 1168*f81fb7c4SAndroid Build Coastguard Worker secs - number of seconds to render 1169*f81fb7c4SAndroid Build Coastguard Worker 1170*f81fb7c4SAndroid Build Coastguard Worker If both count and secs are None, render a single buffer. 1171*f81fb7c4SAndroid Build Coastguard Worker 1172*f81fb7c4SAndroid Build Coastguard Worker """ 1173*f81fb7c4SAndroid Build Coastguard Worker # calls JET.Render 1174*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1175*f81fb7c4SAndroid Build Coastguard Worker self.eas.Render(count, secs) 1176*f81fb7c4SAndroid Build Coastguard Worker 1177*f81fb7c4SAndroid Build Coastguard Worker def Status (self): 1178*f81fb7c4SAndroid Build Coastguard Worker """Get JET status.""" 1179*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1180*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_Status') 1181*f81fb7c4SAndroid Build Coastguard Worker status = JET_Status() 1182*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_Status(self.eas.handle, byref(status)) 1183*f81fb7c4SAndroid Build Coastguard Worker if result: 1184*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_Status error %d' % result, 'JET_Status') 1185*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug("currentUserID=%d, repeatCount=%d, numQueuedSegments=%d, paused=%d" % 1186*f81fb7c4SAndroid Build Coastguard Worker (status.currentUserID, status.segmentRepeatCount, status.numQueuedSegments, status.paused)) 1187*f81fb7c4SAndroid Build Coastguard Worker return status 1188*f81fb7c4SAndroid Build Coastguard Worker 1189*f81fb7c4SAndroid Build Coastguard Worker def SetVolume (self, volume): 1190*f81fb7c4SAndroid Build Coastguard Worker """Set the JET volume""" 1191*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_SetVolume') 1192*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1193*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_SetVolume(self.eas.handle, volume) 1194*f81fb7c4SAndroid Build Coastguard Worker if result: 1195*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_SetVolume error %d' % result, 'JET_SetVolume') 1196*f81fb7c4SAndroid Build Coastguard Worker 1197*f81fb7c4SAndroid Build Coastguard Worker def SetTransposition (self, transposition): 1198*f81fb7c4SAndroid Build Coastguard Worker """Set the transposition of a stream.""" 1199*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_SetTransposition') 1200*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1201*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_SetTransposition(self.eas.handle, transposition) 1202*f81fb7c4SAndroid Build Coastguard Worker if result: 1203*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_SetTransposition error %d' % result, 'JET_SetTransposition') 1204*f81fb7c4SAndroid Build Coastguard Worker 1205*f81fb7c4SAndroid Build Coastguard Worker def TriggerClip (self, clipID): 1206*f81fb7c4SAndroid Build Coastguard Worker """Trigger a clip in the current segment.""" 1207*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_TriggerClip') 1208*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1209*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_TriggerClip(self.eas.handle, clipID) 1210*f81fb7c4SAndroid Build Coastguard Worker if result: 1211*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_SetTransposition error %d' % result, 'JET_TriggerClip') 1212*f81fb7c4SAndroid Build Coastguard Worker 1213*f81fb7c4SAndroid Build Coastguard Worker def SetMuteFlag (self, track_num, mute, sync=True): 1214*f81fb7c4SAndroid Build Coastguard Worker """Trigger a clip in the current segment.""" 1215*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_SetMuteFlag') 1216*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1217*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_SetMuteFlag(self.eas.handle, track_num, mute, sync) 1218*f81fb7c4SAndroid Build Coastguard Worker if result: 1219*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_SetMuteFlag error %d' % result, 'JET_SetMuteFlag') 1220*f81fb7c4SAndroid Build Coastguard Worker 1221*f81fb7c4SAndroid Build Coastguard Worker def SetMuteFlags (self, mute_flags, sync=True): 1222*f81fb7c4SAndroid Build Coastguard Worker """Trigger a clip in the current segment.""" 1223*f81fb7c4SAndroid Build Coastguard Worker eas_logger.debug('Call JET_SetMuteFlags') 1224*f81fb7c4SAndroid Build Coastguard Worker with self.eas.lock: 1225*f81fb7c4SAndroid Build Coastguard Worker result = eas_dll.JET_SetMuteFlags(self.eas.handle, mute_flags, sync) 1226*f81fb7c4SAndroid Build Coastguard Worker if result: 1227*f81fb7c4SAndroid Build Coastguard Worker raise EAS_Exception(result, 'JET_SetMuteFlag error %d' % result, 'JET_SetMuteFlags') 1228*f81fb7c4SAndroid Build Coastguard Worker 1229*f81fb7c4SAndroid Build Coastguard Worker 1230