16b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
26b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivifrom __future__ import with_statement
36b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
46b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviimport threading
56b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviimport logging
66b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviimport time
76b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivifrom ctypes import *
86b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivifrom JetUtils import OsWindows
96b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# stream state
126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_READY = 0
136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_PLAY = 1
146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_STOPPING = 2
156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_PAUSING = 3
166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_STOPPED = 4
176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_PAUSED = 5
186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_OPEN = 6
196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_ERROR = 7
206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STATE_EMPTY = 8
216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EAS error codes
236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_SUCCESS	= 0
246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_FAILURE = -1
256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_INVALID_MODULE = -2
266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_MALLOC_FAILED = -3
276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_POS = -4
286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_INVALID_FILE_MODE = -5
296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_SEEK = -6
306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_LENGTH = -7
316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_NOT_IMPLEMENTED = -8
326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_CLOSE_FAILED = -9
336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_OPEN_FAILED = -10
346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_INVALID_HANDLE = -11
356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_NO_MIX_BUFFER = -12
366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_PARAMETER_RANGE = -13
376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_MAX_FILES_OPEN = -14
386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_UNRECOGNIZED_FORMAT = -15
396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_BUFFER_SIZE_MISMATCH = -16
406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_FORMAT = -17
416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_SMF_NOT_INITIALIZED = -18
426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_LOCATE_BEYOND_END = -19
436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_INVALID_PCM_TYPE = -20
446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_MAX_PCM_STREAMS = -21
456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_NO_VOICE_ALLOCATED = -22
466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_INVALID_CHANNEL = -23
476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_ALREADY_STOPPED = -24
486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_READ_FAILED = -25
496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_HANDLE_INTEGRITY = -26
506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_MAX_STREAMS_OPEN = -27
516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_INVALID_PARAMETER = -28
526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FEATURE_NOT_AVAILABLE = -29
536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_SOUND_LIBRARY = -30
546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_NOT_VALID_IN_THIS_STATE = -31
556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_NO_VIRTUAL_SYNTHESIZER = -32
566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_ALREADY_OPEN = -33
576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FILE_ALREADY_CLOSED = -34
586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_INCOMPATIBLE_VERSION = -35
596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_QUEUE_IS_FULL = -36
606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_QUEUE_IS_EMPTY = -37
616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_ERROR_FEATURE_ALREADY_ACTIVE = -38
626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# special result codes
646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_EOF = 3
656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_STREAM_BUFFERING = 4
666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# buffer full error returned from Render
686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_BUFFER_FULL = 5
696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# file types
716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivifile_types = (
726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Unknown',
736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'SMF Type 0 (.mid)',
746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'SMF Type 1 (.mid)',
756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'SMAF - Unknown type (.mmf)',
766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'SMAF MA-2 (.mmf)',
776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'SMAF MA-3 (.mmf)',
786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'SMAF MA-5 (.mmf)',
796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'CMX/QualComm  (.pmd)',
806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'MFi (NTT/DoCoMo i-mode)',
816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'OTA/Nokia (.ott)',
826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'iMelody (.imy)',
836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'RTX/RTTTL (.rtx)',
846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'XMF Type 0 (.xmf)',
856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'XMF Type 1 (.xmf)',
866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'WAVE/PCM (.wav)',
876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'WAVE/IMA-ADPCM (.wav)',
886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'MMAPI Tone Control (.js)'
896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi)
906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivistream_states = (
926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Ready',
936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Play',
946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Stopping',
956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Stopped',
966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Pausing',
976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Paused',
986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Open',
996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Error',
1006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	'Empty'
1016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi)
1026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# iMode play modes
1046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviIMODE_PLAY_ALL = 0
1056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviIMODE_PLAY_PARTIAL = 1
1066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# callback type for metadata
1086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_METADATA_CBFUNC = CFUNCTYPE(c_int, c_int, c_char_p, c_ulong)
1096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# callbacks for external audio
1116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_EXT_PRG_CHG_FUNC = CFUNCTYPE(c_int, c_void_p, c_void_p)
1126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_EXT_EVENT_FUNC = CFUNCTYPE(c_int, c_void_p, c_void_p)
1136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# callback for aux mixer decoder
1156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_DECODER_FUNC = CFUNCTYPE(c_void_p, c_void_p, c_int, c_int)
1166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# DLL path
1186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviif OsWindows():
1196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	EAS_DLL_PATH = "EASDLL.dll"
1206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivielse:
1216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	EAS_DLL_PATH = "libEASLIb.dylib"
1226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivieas_dll = None
1246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# logger
1266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivieas_logger = None
1276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# InitEASModule
1306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trividef InitEASModule (dll_path=None):
1326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	global eas_dll
1336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	global eas_logger
1346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	# initialize logger
1376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	if eas_logger is None:
1386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger = logging.getLogger('EAS')
1396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	# initialize path to DLL
1416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	if dll_path is None:
1426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		dll_path=EAS_DLL_PATH
1436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	# intialize DLL
1456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	if eas_dll is None:
1466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_dll = cdll.LoadLibrary(dll_path)
1476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# S_JET_CONFIG
1506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass S_JET_CONFIG (Structure):
1526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	_fields_ = [('appLowNote', c_ubyte)]
1536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# S_EXT_AUDIO_PRG_CHG
1566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass S_EXT_AUDIO_PRG_CHG (Structure):
1586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	_fields_ = [('bank', c_ushort),
1596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('program', c_ubyte),
1606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('channel', c_ubyte)]
1616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# S_EXT_AUDIO_EVENT
1646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass S_EXT_AUDIO_EVENT (Structure):
1666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	_fields_ = [('channel', c_ubyte),
1676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('note', c_ubyte),
1686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('velocity', c_ubyte),
1696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('noteOn', c_ubyte)]
1706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# S_MIDI_CONTROLLERS
1736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass S_MIDI_CONTROLLERS (Structure):
1756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	_fields_ = [('modWheel', c_ubyte),
1766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('volume', c_ubyte),
1776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('pan', c_ubyte),
1786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('expression', c_ubyte),
1796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('channelPressure', c_ubyte)]
1806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# WAVEFORMAT
1836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass WAVEFORMAT (Structure):
1856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	_fields_ = [('wFormatTag', c_ushort),
1866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('nChannels', c_ushort),
1876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('nSamplesPerSec', c_ulong),
1886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('nAvgBytesPerSec', c_ulong),
1896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('nBlockAlign', c_ushort),
1906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('wBitsPerSample', c_ushort)]
1916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EAS_Exception
1946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
1956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass EAS_Exception (Exception):
1966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __init__ (self, result_code, msg, function=None):
1976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.msg = msg
1986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.result_code = result_code
1996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.function = function
2006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __str__ (self):
2016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return self.msg
2026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
2046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# Log callback function
2056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
2066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# map EAS severity levels to the Python logging module
2076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviseverity_mapping = (logging.CRITICAL, logging.CRITICAL, logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG)
2086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviLOG_FUNC_TYPE = CFUNCTYPE(c_int, c_int, c_char_p)
2096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trividef Log (level, msg):
2106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	eas_logger.log(severity_mapping[level], msg)
2116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	return level
2126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviLogCallback = LOG_FUNC_TYPE(Log)
2136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
2156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EAS_Stream
2166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
2176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass EAS_Stream (object):
2186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __init__ (self, handle, eas):
2196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_Stream.__init__')
2206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.handle = handle
2216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.eas = eas
2226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetVolume (self, volume):
2246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the stream volume"""
2256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetVolume: volume=%d' % volume)
2266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetVolume(self.eas.handle, self.handle, volume)
2286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetVolume error %d on file %s' % (result, self.path), 'EAS_SetVolume')
2306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetVolume (self):
2326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the stream volume."""
2336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetVolume')
2346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			volume = eas_dll.EAS_GetVolume(self.eas.handle, self.handle)
2366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if volume < 0:
2376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(volume, 'EAS_GetVolume error %d on file %s' % (volume, self.path), 'EAS_GetVolume')
2386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_GetVolume: volume=%d' % volume)
2396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return volume
2406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetPriority (self, priority):
2426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the stream priority"""
2436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetPriority: priority=%d' % priority)
2446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetPriority(self.eas.handle, self.handle, priority)
2466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetPriority error %d on file %s' % (result, self.path), 'EAS_SetPriority')
2486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetPriority (self):
2506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the stream priority."""
2516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetPriority')
2526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		priority = c_int(0)
2536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetPriority(self.eas.handle, self.handle, byref(priority))
2556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetPriority error %d on file %s' % (result, self.path), 'EAS_GetPriority')
2576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_GetPriority: priority=%d' % priority.value)
2586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return priority.value
2596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetTransposition (self, transposition):
2616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the transposition of a stream."""
2626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetTransposition: transposition=%d' % transposition)
2636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetTransposition(self.eas.handle, self.handle, transposition)
2656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetTransposition error %d on file %s' % (result, self.path), 'EAS_SetTransposition')
2676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetPolyphony (self, polyphony):
2696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the polyphony of a stream."""
2706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetPolyphony: polyphony=%d' % polyphony)
2716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetPolyphony(self.eas.handle, self.handle, polyphony)
2736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetPolyphony error %d on file %s' % (result, self.path), 'EAS_SetPolyphony')
2756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetPolyphony (self):
2776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the polyphony of a stream."""
2786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetPolyphony')
2796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		polyphony = c_int(0)
2806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetPolyphony(self.eas.handle, self.handle, byref(polyphony))
2826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetPolyphony error %d on file %s' % (result, self.path), 'EAS_GetPolyphony')
2846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_SetPolyphony: polyphony=%d' % polyphony.value)
2856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return polyphony.value
2866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SelectLib (self, test_lib=False):
2886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SelectLib: test_lib=%s' % test_lib)
2896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SelectLib(self.eas.handle, self.handle, test_lib)
2916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SelectLib error %d on file %s' % (result, self.path), 'EAS_SelectLib')
2936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
2946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def LoadDLSCollection (self, path):
2956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_LoadDLSCollection: lib_path=%d' % path)
2966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
2976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_LoadDLSCollection(self.eas.handle, self.handle, path)
2986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
2996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_LoadDLSCollection error %d on file %s lib %s' % (result, self.path, path), 'EAS_LoadDLSCollection')
3006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def RegExtAudioCallback (self, user_data, prog_chg_func, event_func):
3026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Register an external audio callback."""
3036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_RegExtAudioCallback')
3046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if prog_chg_func is not None:
3056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			prog_chg_func = EAS_EXT_PRG_CHG_FUNC(prog_chg_func)
3066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
3076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			prog_chg_func = 0
3086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if event_func is not None:
3096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			event_func = EAS_EXT_EVENT_FUNC(event_func)
3106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
3116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			event_func = 0
3126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
3136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_RegExtAudioCallback(self.eas.handle, self.handle, user_data, prog_chg_func, event_func)
3146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
3156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_RegExtAudioCallback error %d on file %s' % (result, self.path), 'EAS_RegExtAudioCallback')
3166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetPlayMode (self, play_mode):
3186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set play mode on a stream."""
3196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetPlayMode: play_mode=%d' % play_mode)
3206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
3216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetPlayMode(self.eas.handle, self.handle, play_mode)
3226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
3236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetPlayMode error %d on file %s' % (result, self.path), 'EAS_SetPlayMode')
3246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi"""
3266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel TriviEAS_PUBLIC EAS_RESULT EAS_GetMIDIControllers (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_U8 channel, S_MIDI_CONTROLLERS *pControl);
3276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi"""
3286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
3306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EAS_File
3316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
3326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass EAS_File (EAS_Stream):
3336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __init__ (self, path, handle, eas):
3346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		EAS_Stream.__init__(self, handle, eas)
3356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_File.__init__')
3366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.path = path
3376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.prepared = False
3386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Prepare (self):
3406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Prepare an audio file for playback"""
3416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if self.prepared:
3426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.warning('Prepare already called on file %s' % self.path)
3436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
3446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			with self.eas.lock:
3456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				eas_logger.debug('Call EAS_Prepare for file: %s' % self.path)
3466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				result = eas_dll.EAS_Prepare(self.eas.handle, self.handle)
3476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				if result:
3486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					raise EAS_Exception(result, 'EAS_Prepare error %d on file %s' % (result, self.path), 'EAS_Prepare')
3496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.prepared = True
3506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def State (self):
3526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get stream state."""
3536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
3546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_State for file: %s' % self.path)
3556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			state = c_long(-1)
3566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_State(self.eas.handle, self.handle, byref(state))
3576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
3586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_State error %d on file %s' % (result, self.path), 'EAS_State')
3596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('EAS_State: file=%s, state=%s' % (self.path, stream_states[state.value]))
3606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return state.value
3616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Close (self):
3636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Close audio file."""
3646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if hasattr(self, 'handle'):
3656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			with self.eas.lock:
3666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				eas_logger.debug('Call EAS_CloseFile for file: %s' % self.path)
3676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				result = eas_dll.EAS_CloseFile(self.eas.handle, self.handle)
3686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				if result:
3696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					raise EAS_Exception(result, 'EAS_CloseFile error %d on file %s' % (result, self.path), 'EAS_CloseFile')
3706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				# remove file from the EAS object
3726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.eas.audio_streams.remove(self)
3736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# clean up references
3756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			del self.handle
3766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			del self.eas
3776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			del self.path
3786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Pause (self):
3806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Pause a stream."""
3816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_Pause')
3826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
3836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_Pause(self.eas.handle, self.handle)
3846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
3856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_Pause error %d on file %s' % (result, self.path), 'EAS_Pause')
3866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Resume (self):
3886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Resume a stream."""
3896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_Resume')
3906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
3916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_Resume(self.eas.handle, self.handle)
3926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
3936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_Resume error %d on file %s' % (result, self.path), 'EAS_Resume')
3946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
3956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Locate (self, secs, offset=False):
3966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the playback position of a stream in seconds."""
3976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_Locate: location=%.3f, relative=%s' % (secs, offset))
3986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
3996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_Locate(self.eas.handle, self.handle, int(secs * 1000 + 0.5), offset)
4006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_Locate error %d on file %s' % (result, self.path), 'EAS_Locate')
4026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetLocation (self):
4046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the stream location in seconds."""
4056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetLocation')
4066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		msecs = c_int(0)
4076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetLocation(self.eas.handle, self.handle, byref(msecs))
4096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetLocation error %d on file %s' % (result, self.path), 'EAS_GetLocation')
4116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		msecs = float(msecs.value) / 1000
4126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_GetLocation: location=%.3f' % msecs)
4136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return msecs
4146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetFileType (self):
4166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the file type."""
4176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetFileType')
4186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		file_type = c_int(0)
4196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetFileType(self.eas.handle, self.handle, byref(file_type))
4216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetFileType error %d on file %s' % (result, self.path), 'EAS_GetFileType')
4236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		file_type = file_type.value
4246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if file_type < len(file_types):
4256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			file_desc = file_types[file_type]
4266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
4276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			file_desc = 'Unrecognized type %d' % file_type
4286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_GetFileType: type=%d, desc=%s' % (file_type, file_desc))
4296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return (file_type, file_desc)
4306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetRepeat (self, count):
4326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the repeat count of a stream."""
4336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetRepeat: count=%d' % count)
4346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetRepeat(self.eas.handle, self.handle, count)
4366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetRepeat error %d on file %s' % (result, self.path), 'EAS_SetRepeat')
4386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetRepeat (self):
4406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the repeat count of a stream."""
4416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetRepeat')
4426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		count = c_int(0)
4436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetRepeat(self.eas.handle, self.handle, byref(count))
4456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetRepeat error %d on file %s' % (result, self.path), 'EAS_GetRepeat')
4476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_GetRepeat: count=%d' % count.value)
4486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return count.value
4496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetPlaybackRate (self, rate):
4516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the playback rate of a stream."""
4526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetPlaybackRate')
4536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetPlaybackRate(self.eas.handle, self.handle, rate)
4556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetPlaybackRate error %d on file %s' % (result, self.path), 'EAS_SetPlaybackRate')
4576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def ParseMetaData (self):
4596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Parse the metadata in a file."""
4606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_ParseMetaData')
4616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		length = c_int(0)
4626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_ParseMetaData(self.eas.handle, self.handle, byref(length))
4646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_ParseMetaData error %d on file %s' % (result, self.path), 'EAS_ParseMetaData')
4666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return float(length.value) / 1000.0
4676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def RegisterMetaDataCallback (self, func, buf, buf_size, user_data):
4696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Register a metadata callback."""
4706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_RegisterMetaDataCallback')
4716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if func is not None:
4736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				callback = EAS_METADATA_CBFUNC(func)
4746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			else:
4756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				callback = 0
4766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_RegisterMetaDataCallback(self.eas.handle, self.handle, callback, buf, buf_size, user_data)
4776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_RegisterMetaDataCallback error %d on file %s' % (result, self.path), 'EAS_RegisterMetaDataCallback')
4796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetWaveFmtChunk (self):
4816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the file type."""
4826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetWaveFmtChunk')
4836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		wave_fmt_chunk = c_void_p(0)
4846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
4856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetWaveFmtChunk(self.eas.handle, self.handle, byref(wave_fmt_chunk))
4866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
4876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetWaveFmtChunk error %d on file %s' % (result, self.path), 'EAS_GetWaveFmtChunk')
4886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return cast(wave_fmt_chunk, POINTER(WAVEFORMAT)).contents
4896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
4906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Play (self, max_time=None):
4916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Plays the file to the end or max_time."""
4926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_File.Play')
4936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if not self.prepared:
4946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.Prepare()
4956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if max_time is not None:
4966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			max_time += self.eas.GetRenderTime()
4976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		while self.State() not in (EAS_STATE_STOPPED, EAS_STATE_ERROR, EAS_STATE_EMPTY):
4986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.eas.Render()
4996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if max_time is not None:
5006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				if self.eas.GetRenderTime() >= max_time:
5016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					eas_logger.info('Max render time exceeded - stopping playback')
5026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					self.Pause()
5036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					self.eas.Render()
5046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					break
5056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
5076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EAS_MIDIStream
5086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
5096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass EAS_MIDIStream (EAS_Stream):
5106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Write(self, data):
5116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Write data to MIDI stream."""
5126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
5136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_WriteMIDIStream(self.eas.handle, self.handle, data, len(data))
5146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
5156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_WriteMIDIStream error %d' % result, 'EAS_WriteMIDIStream')
5166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Close (self):
5186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Close MIDI stream."""
5196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if hasattr(self, 'handle'):
5206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			with self.eas.lock:
5216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				eas_logger.debug('Call EAS_CloseMIDIStream')
5226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				result = eas_dll.EAS_CloseMIDIStream(self.eas.handle, self.handle)
5236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				if result:
5246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					raise EAS_Exception(result, 'EAS_CloseFile error %d' % result, 'EAS_CloseMIDIStream')
5256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				# remove file from the EAS object
5276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.eas.audio_streams.remove(self)
5286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# clean up references
5306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			del self.handle
5316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			del self.eas
5326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
5346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EAS_Config
5356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
5366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass EAS_Config (Structure):
5376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	_fields_ = [('libVersion', c_ulong),
5386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('checkedVersion', c_int),
5396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('maxVoices', c_long),
5406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('numChannels', c_long),
5416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('sampleRate', c_long),
5426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('mixBufferSize', c_long),
5436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('filterEnabled', c_int),
5446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('buildTimeStamp', c_ulong),
5456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('buildGUID', c_char_p)]
5466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
5486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EAS
5496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
5506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass EAS (object):
5516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __init__ (self, handle=None, dll_path=None, log_file=None):
5526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if eas_dll is None:
5536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			InitEASModule(dll_path)
5546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if log_file is not None:
5556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.addHandler(log_file)
5566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS.__init__')
5576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.Init(handle)
5586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __del__ (self):
5606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS.__del__')
5616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.Shutdown()
5626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Init (self, handle=None):
5646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Initializes the EAS Library."""
5656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS.Init')
5666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# if we are already initialized, shutdown first
5686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if hasattr(self, 'handle'):
5696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('EAS.Init called with library already initalized')
5706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.ShutDown()
5716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# setup the logging function
5736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_dll.SetLogCallback(LogCallback)
5746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# create some members
5766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.handle = c_void_p(0)
5776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.audio_streams = []
5786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.output_streams = []
5796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.aux_mixer = None
5806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# create a sync lock
5826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.lock = threading.RLock()
5836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
5846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# set log callback
5856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# get library configuration
5876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.Config()
5886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
5896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# initialize library
5906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if handle is None:
5916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.do_shutdown = True
5926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				eas_logger.debug('Call EAS_Init')
5936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				result = eas_dll.EAS_Init(byref(self.handle))
5946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				if result:
5956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					raise EAS_Exception(result, 'EAS_Init error %d' % result, 'EAS_Init')
5966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			else:
5976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.do_shutdown = False
5986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.handle = handle
5996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# allocate audio buffer for rendering
6016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			AudioBufferType = c_ubyte * (2 * self.config.mixBufferSize * self.config.numChannels)
6026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.audio_buffer = AudioBufferType()
6036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.buf_size = self.config.mixBufferSize
6046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Config (self):
6066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Retrieves the EAS library configuration"""
6076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if not hasattr(self, 'config'):
6086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_Config')
6096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_dll.EAS_Config.restype = POINTER(EAS_Config)
6106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.config = eas_dll.EAS_Config()[0]
6116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug("libVersion=%08x, maxVoices=%d, numChannels=%d, sampleRate = %d, mixBufferSize=%d" %
6126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			(self.config.libVersion, self.config.maxVoices, self.config.numChannels, self.config.sampleRate, self.config.mixBufferSize))
6136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Shutdown (self):
6156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Shuts down the EAS library"""
6166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS.Shutdown')
6176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if hasattr(self, 'handle'):
6186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			with self.lock:
6196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				# close audio streams
6206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				audio_streams = self.audio_streams
6216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				for f in audio_streams:
6226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					eas_logger.warning('Stream was not closed before EAS_Shutdown')
6236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					f.Close()
6246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				# close output streams
6266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				output_streams = self.output_streams
6276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				for s in output_streams:
6286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					s.close()
6296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				# shutdown library
6316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				if self.do_shutdown:
6326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					eas_logger.debug('Call EAS_Shutdown')
6336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					result = eas_dll.EAS_Shutdown(self.handle)
6346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					if result:
6356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi						raise EAS_Exception(result, 'EAS_Shutdown error %d' % result, 'EAS_Shutdown')
6366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				del self.handle
6376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def OpenFile (self, path):
6396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Opens an audio file to be played by the EAS library and
6406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		returns an EAS_File object
6416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
6436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			path - path to audio file
6446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Returns:
6466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			EAS_File
6476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
6496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
6506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_OpenFile for file: %s' % path)
6516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream_handle = c_void_p(0)
6526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_OpenFile(self.handle, path, byref(stream_handle))
6536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
6546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_OpenFile error %d on file %s' % (result, path), 'EAS_OpenFile')
6556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# create file object and save in list
6576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream = EAS_File(path, stream_handle, self)
6586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.audio_streams.append(stream)
6596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return stream
6606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def OpenMIDIStream (self, stream=None):
6626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Opens a MIDI stream.
6636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
6656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream - open stream object. If None, a new synth
6666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			is created.
6676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Returns:
6696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			EAS_MIDIStream
6706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
6726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
6736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_OpenMIDIStream')
6746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream_handle = c_void_p(0)
6756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if stream.handle is not None:
6766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				result = eas_dll.EAS_OpenMIDIStream(self.handle, byref(stream_handle), stream.handle)
6776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			else:
6786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				result = eas_dll.EAS_OpenMIDIStream(self.handle, byref(stream_handle), 0)
6796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
6806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_OpenMIDIStream error %d' % result, 'EAS_OpenMIDIStream')
6816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# create stream object and save in list
6836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream = EAS_MIDIStream(stream_handle, self)
6846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.audio_streams.append(stream)
6856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return stream
6866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def OpenToneControlStream (self, path):
6886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Opens an MMAPI tone control file to be played by the EAS
6896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		library and returns an EAS_File object
6906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
6926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			path - path to audio file
6936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Returns:
6956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			EAS_File
6966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
6976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
6986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
6996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_MMAPIToneControl for file: %s' % path)
7006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream_handle = c_void_p(0)
7016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_MMAPIToneControl(self.handle, path, byref(stream_handle))
7026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
7036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_MMAPIToneControl error %d on file %s' % (result, path), 'EAS_OpenToneControlStream')
7046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# create file object and save in list
7066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream = EAS_File(path, stream_handle, self)
7076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.audio_streams.append(stream)
7086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return stream
7096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Attach (self, stream):
7116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Attach a file or output device to the EAS output.
7126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		The stream object must support the following methods as
7146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		defined in the Python wave module:
7156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			close()
7166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			setparams()
7176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			writeframesraw()
7186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
7206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream - open wave object
7216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
7236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.output_streams.append(stream)
7246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		stream.setparams((self.config.numChannels, 2, self.config.sampleRate, 0, 'NONE', None))
7256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Detach (self, stream):
7276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Detach a file or output device from the EAS output. See
7286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		EAS.Attach for more details. It is the responsibility of
7296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		the caller to close the wave file or stream.
7306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
7326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream - open and attached wave object
7336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
7346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.output_streams.remove(stream)
7356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def StartWave (self, dev_num=0, sampleRate=None, maxBufSize=None):
7376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Route the audio output to the indicated wave device. Note
7386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		that this can cause EASDLL.EAS_RenderWaveOut to return an
7396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		error code if all the output buffers are full. In this case,
7406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		the render thread should sleep a bit and try again.
7416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Unfortunately, due to the nature of the MMSYSTEM interface,
7426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		there is no simple way to suspend the render thread.
7436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
7456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if sampleRate == None:
7466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			sampleRate = self.config.sampleRate
7476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if maxBufSize == None:
7486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			maxBufSize = self.config.mixBufferSize
7496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
7506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.OpenWaveOutDevice(dev_num, sampleRate, maxBufSize)
7516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
7526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'OpenWaveOutDevice error %d' % result, 'OpenWaveOutDevice')
7536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def StopWave (self):
7556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Stop routing audio output to the audio device."""
7566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
7576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.CloseWaveOutDevice()
7586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
7596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'CloseWaveOutDevice error %d' % result, 'CloseWaveOutDevice')
7606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Render (self, count=None, secs=None):
7626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Calls EAS_Render to render audio.
7636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments
7656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			count - number of buffers to render
7666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			secs - number of seconds to render
7676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		If both count and secs are None, render a single buffer.
7696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
7716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# determine number of buffers to render
7736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if count is None:
7746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if secs is not None:
7756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				count = int(secs * float(self.config.sampleRate) / float(self.buf_size) + 0.5)
7766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			else:
7776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				count = 1
7786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# render buffers
7806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('rendering %d buffers' % count)
7816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		samplesRendered = c_long(0)
7826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
7836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			for c in range(count):
7846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				# render a buffer of audio
7856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				eas_logger.debug('rendering buffer')
7866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				while 1:
7876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					if self.aux_mixer is None:
7886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi						result = eas_dll.EAS_RenderWaveOut(self.handle, byref(self.audio_buffer), self.buf_size, byref(samplesRendered))
7896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					else:
7906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi						result = eas_dll.EAS_RenderAuxMixer(self.handle, byref(self.audio_buffer), byref(samplesRendered))
7916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					if result == 0:
7936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi						break;
7946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					if result == EAS_BUFFER_FULL:
7956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi						time.sleep(0.01)
7966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					else:
7976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi						raise EAS_Exception(result, 'EAS_Render error %d' % result, 'EAS_Render')
7986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
7996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				# output to attached streams
8006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				for s in self.output_streams:
8016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					s.writeframesraw(self.audio_buffer)
8026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetRenderTime (self):
8046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the render time in seconds."""
8056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetRenderTime')
8066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		msecs = c_int(0)
8076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetRenderTime(self.handle, byref(msecs))
8096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetRenderTime error %d' % result, 'EAS_GetRenderTime')
8116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		msecs = float(msecs.value) / 1000
8126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_GetRenderTime: time=%.3f' % msecs)
8136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return msecs
8146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetVolume (self, volume):
8166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the master volume"""
8176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetVolume: volume=%d' % volume)
8186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetVolume(self.handle, 0, volume)
8206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					raise EAS_Exception(result, 'EAS_SetVolume error %d' % result, 'EAS_SetVolume')
8226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetVolume (self):
8246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the stream volume."""
8256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetVolume')
8266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		volume = c_int(0)
8276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetVolume(self.handle, 0, byref(volume))
8296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetVolume error %d' % result, 'EAS_GetVolume')
8316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EAS_GetVolume: volume=%d' % volume.value)
8326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return volume.value
8336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetPolyphony (self, polyphony, synth_num=0):
8356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the polyphony of a synth."""
8366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetSynthPolyphony: synth_num=%d, polyphony=%d' % (synth_num, polyphony))
8376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetSynthPolyphony(self.handle, synth_num, polyphony)
8396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetSynthPolyphony error %d on synth %d' % (result, synth_num), 'EAS_SetPolyphony')
8416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetPolyphony (self, synth_num=0):
8436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the polyphony of a synth."""
8446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetSynthPolyphony: synth_num=%d' % synth_num)
8456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		polyphony = c_int(0)
8466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetSynthPolyphony(self.handle, synth_num, byref(polyphony))
8486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_GetSynthPolyphony error %d on synth %d' % (result, synth_num), 'EAS_GetPolyphony')
8506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetSynthPolyphony: synth_num=%d, polyphony=%d' % (synth_num, polyphony.value))
8516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return polyphony.value
8526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetMaxLoad (self, max_load):
8546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the maximum parser load."""
8556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetMaxLoad: max_load=%d' % max_load)
8566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetMaxLoad(self.handle, max_load)
8586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetMaxLoad error %d' % result, 'EAS_SetMaxLoad')
8606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetParameter (self, module, param, value):
8626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set a module parameter."""
8636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetParameter: module=%d, param=%d, value=%d' % (module, param, value))
8646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SetParameter(self.handle, module, param, value)
8666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetParameter error %d (param=%d, value=%d)' % (result, param, value), 'EAS_SetParameter')
8686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetParameter (self, module, param):
8706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get the polyphony of a synth."""
8716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_GetParameter: module=%d, param=%d' % (module, param))
8726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		value = c_int(0)
8736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_GetParameter(self.handle, module, param, byref(value))
8756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SetParameter error %d (param=%d)' % (result, param), 'EAS_GetParameter')
8776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SetParameter: module=%d, param=%d, value=%d' % (module, param, value.value))
8786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		return value.value
8796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SelectLib (self, test_lib=False):
8816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_SelectLib: test_lib=%s' % test_lib)
8826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		easdll = cdll.LoadLibrary('EASDLL')
8836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_SelectLib(self.handle, 0, test_lib)
8856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_SelectLib error %d' % result, 'EAS_SelectLib')
8876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def LoadDLSCollection (self, path):
8896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_LoadDLSCollection: lib_path=%s' % path)
8906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
8916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_LoadDLSCollection(self.handle, 0, path)
8926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
8936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_LoadDLSCollection error %d lib %s' % (result, path), 'EAS_LoadDLSCollection')
8946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetAuxMixerHook (self, aux_mixer):
8966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
8976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# if aux mixer has bigger buffer, re-allocate buffer
8986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if (aux_mixer is not None) and (aux_mixer.buf_size > self.config.mixBufferSize):
8996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			buf_size = aux_mixer.buf_size
9006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
9016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			buf_size = self.config.mixBufferSize
9026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# allocate audio buffer for rendering
9046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		AudioBufferType = c_ubyte * (2 * buf_size * self.config.numChannels)
9056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.audio_buffer = AudioBufferType()
9066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.buf_size = buf_size
9076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.aux_mixer = aux_mixer
9086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetDebugLevel (self, level=3):
9106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Sets the EAS debug level."""
9116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.lock:
9126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_SetDebugLevel')
9136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_dll.EAS_DLLSetDebugLevel(self.handle, level)
9146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
9166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# EASAuxMixer
9176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
9186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass EASAuxMixer (object):
9196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __init__ (self, eas=None, num_streams=3, sample_rate=44100, max_sample_rate=44100):
9206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EASAuxMixer.__init__')
9216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.Init(eas, num_streams, sample_rate, max_sample_rate)
9226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __del__ (self):
9246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EASAuxMixer.__del__')
9256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.Shutdown()
9266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Init (self, eas=None, num_streams=3, sample_rate=44100, max_sample_rate=44100):
9286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Initializes the EAS Auxilliary Mixer."""
9296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EASAuxMixer.Init')
9306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if hasattr(self, 'eas'):
9326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			raise EAS_Exception(-1, 'EASAuxMixer already initialized', 'EASAuxMixer.Init')
9336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# initialize EAS, if necessary
9356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if eas is None:
9366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('No EAS handle --- initializing EAS')
9376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas = EAS()
9386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.alloc_eas = True
9396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
9406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.alloc_eas = False
9416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.eas = eas
9426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# initialize library
9446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call EAS_InitAuxMixer')
9456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		buf_size = c_int(0)
9466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		result = eas_dll.EAS_InitAuxMixer(eas.handle, num_streams, sample_rate, max_sample_rate, byref(buf_size))
9476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if result:
9486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			raise EAS_Exception(result, 'EAS_InitAuxMixer error %d' % result, 'EAS_InitAuxMixer')
9496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.buf_size = buf_size.value
9506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.streams = []
9516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas.SetAuxMixerHook(self)
9526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Shutdown (self):
9546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Shuts down the EAS Auxilliary Mixer"""
9556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('EASAuxMixer.Shutdown')
9566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if not hasattr(self, 'eas'):
9576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return
9586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
9606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if len(self.streams):
9616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				eas_logger.warning('Stream was not closed before EAS_ShutdownAuxMixer')
9626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				for stream in self.streams:
9636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					self.CloseStream(stream)
9646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.eas.SetAuxMixerHook(None)
9666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# shutdown library
9686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_ShutdownAuxMixer')
9696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_ShutdownAuxMixer(self.eas.handle)
9706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
9716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_ShutdownAuxMixer error %d' % result, 'EAS_ShutdownAuxMixer')
9726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# if we created the EAS reference here, shut it down
9746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if self.alloc_eas:
9756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.eas.Shutdown()
9766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.alloc_eas = False
9776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			del self.eas
9786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def OpenStream (self, decoder_func, inst_data, sample_rate, num_channels):
9806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Opens an audio file to be played by the JET library and
9816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		returns a JET_File object
9826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
9846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			callback - callback function to decode more audio
9856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
9876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
9886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_OpenAudioStream')
9896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			decoder_func = EAS_DECODER_FUNC(decoder_func)
9906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			stream_handle = c_void_p(0)
9916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.EAS_OpenAudioStream(self.eas.handle, decoder_func, inst_data, sample_rate, num_channels, stream_handle)
9926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
9936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_OpenAudioStream error %d on file %s' % (result, path), 'EAS_OpenAudioStream')
9946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.streams.add(stream_handle)
9956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return stream_handle
9966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
9976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def CloseStream (self, stream_handle):
9986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Closes an open audio stream."""
9996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
10006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call EAS_CloseAudioStream')
10016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_CloseFile(self.eas.handle, stream_handle)
10026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
10036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'EAS_CloseAudioStream error %d' % result, 'EAS_CloseAudioStream')
10046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
10066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# JET_Status
10076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
10086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass JET_Status (Structure):
10096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	_fields_ = [('currentUserID', c_int),
10106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('segmentRepeatCount', c_int),
10116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('numQueuedSegments', c_int),
10126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('paused', c_int),
10136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('location', c_long),
10146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('currentPlayingSegment', c_int),
10156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				('currentQueuedSegment', c_int),
10166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				]
10176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
10196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# JET_File
10206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
10216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass JET_File (object):
10226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __init__ (self, handle, jet):
10236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('JET_File.__init__')
10246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.handle = handle
10256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.jet = jet
10266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
10286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi# JET
10296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi#---------------------------------------------------------------
10306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Triviclass JET (object):
10316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __init__ (self, eas=None):
10326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# eas_logger.debug('JET.__init__')
10336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.Init(eas)
10346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def __del__ (self):
10366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('JET.__del__')
10376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.Shutdown()
10386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Init (self, eas=None, config=None):
10406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Initializes the JET Library."""
10416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# eas_logger.debug('JET.Init')
10426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if hasattr(self, 'eas'):
10446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			raise EAS_Exception(-1, 'JET library already initialized', 'Jet.Init')
10456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# create some members
10476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if eas is None:
10486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# eas_logger.debug('No EAS handle --- initializing EAS')
10496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas = EAS()
10506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.alloc_eas = True
10516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
10526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.alloc_eas = False
10536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.eas = eas
10546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		self.fileOpen = False
10556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# handle configuration
10576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if config is None:
10586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			config_handle = c_void_p(0)
10596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			config_size = 0
10606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		else:
10616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			jet_config = S_JET_CONFIG()
10626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			jet_config.appLowNote = config.appLowNote
10636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			config_handle = c_void_p(jet_config)
10646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			config_size = jet_config.sizeof()
10656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# initialize library
10676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# eas_logger.debug('Call JET_Init')
10686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		result = eas_dll.JET_Init(eas.handle, config_handle, config_size)
10696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if result:
10706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			raise EAS_Exception(result, 'JET_Init error %d' % result, 'JET_Init')
10716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Shutdown (self):
10736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Shuts down the JET library"""
10746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('JET.Shutdown')
10756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		if not hasattr(self, 'eas'):
10766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return
10776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
10796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if self.fileOpen:
10806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				eas_logger.warning('Stream was not closed before JET_Shutdown')
10816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.CloseFile()
10826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# shutdown library
10846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_Shutdown')
10856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_Shutdown(self.eas.handle)
10866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
10876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_Shutdown error %d' % result, 'JET_Shutdown')
10886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			# if we created the EAS reference here, shut it down
10906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if self.alloc_eas:
10916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.eas.Shutdown()
10926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				self.alloc_eas = False
10936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			del self.eas
10946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def OpenFile (self, path):
10966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Opens an audio file to be played by the JET library and
10976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		returns a JET_File object
10986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
10996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
11006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			path - path to audio file
11016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
11036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_OpenFile for file: %s' % path)
11056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_OpenFile(self.eas.handle, path)
11066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_OpenFile error %d on file %s' % (result, path), 'JET_OpenFile')
11086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def CloseFile (self):
11106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Closes an open audio file."""
11116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_CloseFile')
11136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_CloseFile(self.eas.handle)
11146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_CloseFile error %d' % result, 'JET_CloseFile')
11166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def QueueSegment (self, userID, seg_num, dls_num=-1, repeat=0, tranpose=0, mute_flags=0):
11186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Queue a segment for playback.
11196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments:
11216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			seg_num - segment number to queue
11226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			repeat - repeat count (-1=repeat forever, 0=no repeat, 1+ = play n+1 times)
11236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			tranpose - transpose amount (+/-12)
11246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			"""
11266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_QueueSegment')
11286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_QueueSegment(self.eas.handle, seg_num, dls_num, repeat, tranpose, mute_flags, userID)
11296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11306b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_QueueSegment error %d' % result, 'JET_QueueSegment')
11316b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11326b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Clear_Queue(self):
11336b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Kills the queue."""
11346b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11356b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_Clear_Queue')
11366b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_Clear_Queue(self.eas.handle)
11376b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11386b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_Clear_Queue error %d' % result, 'JET_Clear_Queue')
11396b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11406b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def GetAppEvent(self):
11416b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Gets an App event."""
11426b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11436b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_GetEvent')
11446b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_GetEvent(self.eas.handle, 0, 0)
11456b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return result
11466b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11476b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Play(self):
11486b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Starts JET playback."""
11496b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11506b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_Play')
11516b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_Play(self.eas.handle)
11526b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11536b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_Play error %d' % result, 'JET_Play')
11546b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11556b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Pause(self):
11566b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Pauses JET playback."""
11576b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11586b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_Pause')
11596b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_Pause(self.eas.handle)
11606b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11616b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_Pause error %d' % result, 'JET_Pause')
11626b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11636b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Render (self, count=None, secs=None):
11646b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Calls EAS_Render to render audio.
11656b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11666b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		Arguments
11676b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			count - number of buffers to render
11686b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			secs - number of seconds to render
11696b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11706b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		If both count and secs are None, render a single buffer.
11716b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11726b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""
11736b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		# calls JET.Render
11746b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11756b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			self.eas.Render(count, secs)
11766b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11776b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def Status (self):
11786b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Get JET status."""
11796b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11806b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug('Call JET_Status')
11816b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			status = JET_Status()
11826b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_Status(self.eas.handle, byref(status))
11836b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11846b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_Status error %d' % result, 'JET_Status')
11856b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			eas_logger.debug("currentUserID=%d, repeatCount=%d, numQueuedSegments=%d, paused=%d" %
11866b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				(status.currentUserID, status.segmentRepeatCount, status.numQueuedSegments, status.paused))
11876b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			return status
11886b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11896b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetVolume (self, volume):
11906b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the JET volume"""
11916b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call JET_SetVolume')
11926b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
11936b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_SetVolume(self.eas.handle, volume)
11946b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
11956b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi					raise EAS_Exception(result, 'JET_SetVolume error %d' % result, 'JET_SetVolume')
11966b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
11976b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetTransposition (self, transposition):
11986b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Set the transposition of a stream."""
11996b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call JET_SetTransposition')
12006b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
12016b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_SetTransposition(self.eas.handle, transposition)
12026b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
12036b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_SetTransposition error %d' % result, 'JET_SetTransposition')
12046b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
12056b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def TriggerClip (self, clipID):
12066b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Trigger a clip in the current segment."""
12076b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call JET_TriggerClip')
12086b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
12096b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_TriggerClip(self.eas.handle, clipID)
12106b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
12116b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_SetTransposition error %d' % result, 'JET_TriggerClip')
12126b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
12136b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetMuteFlag (self, track_num, mute, sync=True):
12146b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Trigger a clip in the current segment."""
12156b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call JET_SetMuteFlag')
12166b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
12176b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_SetMuteFlag(self.eas.handle, track_num, mute, sync)
12186b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
12196b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_SetMuteFlag error %d' % result, 'JET_SetMuteFlag')
12206b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
12216b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi	def SetMuteFlags (self, mute_flags, sync=True):
12226b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		"""Trigger a clip in the current segment."""
12236b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		eas_logger.debug('Call JET_SetMuteFlags')
12246b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi		with self.eas.lock:
12256b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			result = eas_dll.JET_SetMuteFlags(self.eas.handle, mute_flags, sync)
12266b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi			if result:
12276b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi				raise EAS_Exception(result, 'JET_SetMuteFlag error %d' % result, 'JET_SetMuteFlags')
12286b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
12296b065d0f7161fe54e6f58fd2b8ad6c650b2d3657Jean-Michel Trivi
1230