summaryrefslogtreecommitdiffstats
path: root/pulseaudio
diff options
context:
space:
mode:
authorPaul W. Frields <stickster@gmail.com>2009-05-23 17:16:46 -0400
committerPaul W. Frields <stickster@gmail.com>2009-05-23 17:16:46 -0400
commit1846a632d0f450839af538c2105f1a30ec1c6398 (patch)
tree056d4f9610d4e2cb5973da009e77c607e774c7df /pulseaudio
parentccf4ecaaf1136cb01bc10bffb337acad88165d1d (diff)
downloadpulsecaster-1846a632d0f450839af538c2105f1a30ec1c6398.tar.gz
pulsecaster-1846a632d0f450839af538c2105f1a30ec1c6398.tar.xz
pulsecaster-1846a632d0f450839af538c2105f1a30ec1c6398.zip
Add simple PulseAudio bindings for Python
Thank you to Harry Karvonen <harry.karvonen@gmail.com> for providing this very helpful code!
Diffstat (limited to 'pulseaudio')
-rw-r--r--pulseaudio/PulseClient.py66
-rw-r--r--pulseaudio/PulseClient.pycbin0 -> 2021 bytes
-rw-r--r--pulseaudio/PulseObj.py589
-rw-r--r--pulseaudio/PulseObj.pycbin0 -> 9836 bytes
-rw-r--r--pulseaudio/PulseSink.py213
-rw-r--r--pulseaudio/PulseSink.pycbin0 -> 7116 bytes
-rw-r--r--pulseaudio/PulseSource.py187
-rw-r--r--pulseaudio/PulseSource.pycbin0 -> 5088 bytes
-rw-r--r--pulseaudio/PulseVolume.py114
-rw-r--r--pulseaudio/PulseVolume.pycbin0 -> 3553 bytes
-rw-r--r--pulseaudio/__init__.py29
-rw-r--r--pulseaudio/lib_pulseaudio.py513
-rw-r--r--pulseaudio/lib_pulseaudio.pycbin0 -> 7423 bytes
13 files changed, 1711 insertions, 0 deletions
diff --git a/pulseaudio/PulseClient.py b/pulseaudio/PulseClient.py
new file mode 100644
index 0000000..6705080
--- /dev/null
+++ b/pulseaudio/PulseClient.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+# vi: et sw=2
+#
+# PulseClient.py
+# Copyright (C) 2009 Harry Karvonen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Author: Harry Karvonen <harry.karvonen@gmail.com>
+#
+
+from lib_pulseaudio import *
+
+# This class contains all basic client features
+class PulseClient:
+ def __init__(self, name, index = 0):
+ self.index = index
+ self.name = name
+ return
+
+ ###
+
+ def printDebug(self):
+ print "self.index:", self.index
+ print "self.name:", self.name
+ return
+
+ ###
+
+ def __str__(self):
+ return "Client-ID: " + str(self.index) + ", Name: \"" + self.name + "\""
+
+################################################################################
+
+# This class is used with Ctypes
+class PulseClientCtypes(PulseClient):
+ def __init__(self, pa_client):
+ PulseClient.__init__(self, pa_client.name, pa_client.index)
+
+ self.owner_module = pa_client.owner_module
+ self.driver = pa_client.driver
+ #self.proplist = pa_sink_input_info.proplist
+ return
+
+ ###
+
+ def printDebug(self):
+ print "PulseClientCtypes"
+ PulseClient.printDebug(self)
+ print "self.owner_module:", self.owner_module
+ print "self.driver:", self.driver
+ #print "self.proplist:", self.proplist
+ return
+
diff --git a/pulseaudio/PulseClient.pyc b/pulseaudio/PulseClient.pyc
new file mode 100644
index 0000000..47b7e37
--- /dev/null
+++ b/pulseaudio/PulseClient.pyc
Binary files differ
diff --git a/pulseaudio/PulseObj.py b/pulseaudio/PulseObj.py
new file mode 100644
index 0000000..db6e866
--- /dev/null
+++ b/pulseaudio/PulseObj.py
@@ -0,0 +1,589 @@
+#!/usr/bin/python
+# vi: et sw=2
+#
+# PulseObj.py
+# Copyright (C) 2009 Harry Karvonen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Author: Harry Karvonen <harry.karvonen@gmail.com>
+#
+
+from lib_pulseaudio import *
+from PulseSink import PulseSinkInputInfo, PulseSinkInfo
+from PulseSource import PulseSourceOutputInfo, PulseSourceInfo
+from PulseClient import PulseClientCtypes
+
+################################################################################
+#
+# Classes
+#
+################################################################################
+
+class PulseObj:
+ "Basic PulseAudio object"
+
+ ##############################################################################
+ #
+ # Init
+ #
+ ##############################################################################
+
+ def __init__(self, server = None, retry = False):
+ "Initialise pulseaudio connection"
+
+ # Variables
+ self.server = server
+ self.mainloop = None
+ self.mainloop_api = None
+ self.context = None
+ self.ret = None
+ self.retry = retry
+ self.operation = None
+ self.connected = False
+ self.action_done = False
+ self.data = None
+
+ # Init
+
+ #
+ # Callbacks
+ #
+ self.PA_SIGNAL_CB = PA_SIGNAL_CB_T(self.py_signal_cb)
+
+ self.PA_STATE_CB = PA_STATE_CB_T(self.py_state_cb)
+ #
+ # Mainloop init
+ #
+ self.mainloop = pa_mainloop_new()
+
+ self.mainloop_api = pa_mainloop_get_api(self.mainloop)
+
+ #
+ # Signal binding
+ #
+ r = pa_signal_init(self.mainloop_api)
+
+ if r != 0:
+ # FIXME
+ print "FIXME Do something. Something is wrong"
+
+ # SIGINT
+ pa_signal_new(2, self.PA_SIGNAL_CB, None)
+
+ # SIGTERM
+ pa_signal_new(15, self.PA_SIGNAL_CB, None)
+
+ #
+ # Context creating
+ #
+ self.context = pa_context_new(self.mainloop_api, "PulseApplet")
+
+ pa_context_set_state_callback(self.context, self.PA_STATE_CB, None)
+
+ self.start_action()
+
+ #
+ # Connect
+ #
+ if 0 > pa_context_connect(self.context,
+ self.server,
+ 0,
+ None):
+ if self.retry:
+ pa_context_disconnect(self.context)
+ return
+ self.pulse_context_error()
+
+ self.pulse_iterate()
+
+ return
+
+ ##############################################################################
+ #
+ # Callback methods
+ #
+ # FIXME: rename methods better
+ #
+ ##############################################################################
+
+ def py_signal_cb(self, api, e, sig, userdata):
+ #print "py_signal_cb:", api, e, sig, userdata
+
+ if sig == 2:
+ self.pulse_disconnect()
+ elif sig == 15:
+ self.pulse_disconnect()
+
+ return 0
+
+ ###
+
+ def py_state_cb(self, c, b):
+ #print "py_state_cb:", c[0]._opaque_struct, b
+ state = pa_context_get_state(c);
+
+
+ if state == 0:
+ None
+ #print "py_state_cb: Unconnected"
+
+ elif state == 1:
+ None
+ #print "py_state_cb: Connecting"
+
+ elif state == 2:
+ None
+ #print "py_state_cb: Authorizing"
+
+ elif state == 3:
+ None
+ #print "py_state_cb: Setting name"
+
+ elif state == 4:
+ #print "py_state_cb: Ready"
+ self.complete_action()
+ self.connected = True
+
+ elif state == 5:
+ None
+ #print "py_state_cb: Failed"
+
+ elif state == 6:
+ None
+ #print "py_state_cb: Terminated"
+ if not self.retry:
+ import sys
+ sys.exit(pa_context_errno(c))
+
+ self.complete_action()
+
+ else:
+ None
+ #print "py_state_cb: Unknown state", state
+
+
+ #print "py_state_cb:", pa_strerror(pa_context_errno(c))
+ return 0
+
+ ###
+
+ def py_client_cb(self, c, client_info, endofdata, userdata):
+ "Sink callback"
+ #print "py_client_cb:", c, client_info, endofdata, userdata
+
+ if (endofdata):
+ self.complete_action()
+ return 0
+
+ if self.data == None:
+ self.data = [ PulseClientCtypes(client_info[0]) ]
+ else:
+ self.data.append(PulseClientCtypes(client_info[0]))
+
+ return 0
+
+ ###
+
+ def py_sink_input_cb(self, c, sink_input_info, endofdata, userdata):
+ "Sink input callback"
+ #print "py_sink_input_cb:", c, sink_input_info, endofdata, userdata
+
+ if (endofdata):
+ self.complete_action()
+ return 0
+
+ if self.data == None:
+ self.data = [ PulseSinkInputInfo(sink_input_info[0]) ]
+ else:
+ self.data.append(PulseSinkInputInfo(sink_input_info[0]))
+
+ return 0
+
+ ###
+
+ def py_sink_cb(self, c, sink_info, endofdata, userdata):
+ "Sink callback"
+ #print "py_sink_cb:", c, sink_info, endofdata, userdata
+
+ if (endofdata):
+ self.complete_action()
+ return 0
+
+ if self.data == None:
+ self.data = [ PulseSinkInfo(sink_info[0]) ]
+ else:
+ self.data.append(PulseSinkInfo(sink_info[0]))
+
+ return 0
+ ###
+
+ def py_source_output_cb(self, c, source_output_info, endofdata, userdata):
+ "Source output callback"
+ #print "py_source_output_cb:", c, source_output_info, endofdata, userdata
+
+ if (endofdata):
+ self.complete_action()
+ return 0
+
+ if self.data == None:
+ self.data = [ PulseSourceOutputInfo(source_output_info[0]) ]
+ else:
+ self.data.append(PulseSourceOutputInfo(source_output_info[0]))
+
+ return 0
+
+ ###
+
+ def py_source_cb(self, c, source_info, endofdata, userdata):
+ "Source callback"
+ #print "py_source_cb:", c, source_info, endofdata, userdata
+
+ if (endofdata):
+ self.complete_action()
+ return 0
+
+ if self.data == None:
+ self.data = [ PulseSourceInfo(source_info[0]) ]
+ else:
+ self.data.append(PulseSourceInfo(source_info[0]))
+
+ return 0
+ ###
+
+ def py_drain_cb(self, c, userdata):
+ #print "py_drain_cb: called"
+ return
+
+ ###
+
+ def py_context_success(self, c, success, userdata):
+ if success == 0:
+ None
+ #print "py_context_success: Failed"
+ else:
+ None
+ #print "py_context_success: Success"
+
+ self.complete_action()
+ return 0
+
+ ##############################################################################
+ #
+ ##############################################################################
+
+ def complete_action(self):
+ "Completed action"
+ #print "complete_action: Called"
+ self.action_done = True
+ return
+
+ ###
+
+ def start_action(self):
+ "Call every time when starting action"
+ #print "start_action: Called"
+ self.action_done = False
+ return
+
+ ###
+
+ def pulse_disconnect(self):
+ "Call when disconnect object"
+
+ #print "pulse_disconnect: Disconnecting"
+ pa_context_disconnect(self.context)
+ pa_mainloop_free(self.mainloop)
+ return
+
+ ###
+
+ def pulse_context_error(self):
+ "Print context error msg"
+
+ #print "pulse_context_error:", pa_strerror(pa_context_errno(self.context))
+ self.pulse_disconnect()
+ return
+
+ ###
+
+ def pulse_sink_input_list(self):
+ "List all sink input"
+ #print "pulse_sink_input_list: Called";
+
+ return_data = None
+
+ self.start_action()
+
+ # Callback function
+ SINK_INPUT_LIST_CB = PA_SINK_INPUT_INFO_CB_T(self.py_sink_input_cb)
+
+ self.operation = pa_context_get_sink_input_info_list(self.context,
+ SINK_INPUT_LIST_CB,
+ None)
+ self.pulse_iterate()
+
+ #print "pulse_sink_input_list:", self.data
+ return_data = self.data
+ self.data = None
+
+ return return_data
+
+ ###
+
+ def pulse_sink_list(self):
+ "List all sinks"
+ #print "pulse_sink_list: Called";
+
+ return_data = None
+
+ self.start_action()
+
+ # Callback function
+ SINK_LIST_CB = PA_SINK_INFO_CB_T(self.py_sink_cb)
+
+ self.operation = pa_context_get_sink_info_list(self.context,
+ SINK_LIST_CB,
+ None)
+ self.pulse_iterate()
+
+ #print "pulse_sink_list:", self.data
+ return_data = self.data
+ self.data = None
+
+ return return_data
+
+ ###
+
+ def pulse_source_output_list(self):
+ "List all source outputs"
+ #print "pulse_source_output_list: Called";
+
+ return_data = None
+
+ self.start_action()
+
+ # Callback function
+ SOURCE_OUTPUT_LIST_CB = PA_SOURCE_OUTPUT_INFO_CB_T(self.py_source_output_cb)
+
+ self.operation = pa_context_get_source_output_info_list(self.context,
+ SOURCE_OUTPUT_LIST_CB,
+ None)
+ self.pulse_iterate()
+
+ #print "pulse_source_output_list:", self.data
+ return_data = self.data
+ self.data = None
+
+ return return_data
+
+ ###
+
+ def pulse_source_list(self):
+ "List all sources"
+ #print "pulse_source_list: Called";
+
+ return_data = None
+
+ self.start_action()
+
+ # Callback function
+ SOURCE_LIST_CB = PA_SOURCE_INFO_CB_T(self.py_source_cb)
+
+ self.operation = pa_context_get_source_info_list(self.context,
+ SOURCE_LIST_CB,
+ None)
+ self.pulse_iterate()
+
+ #print "pulse_source_list:", self.data
+ return_data = self.data
+ self.data = None
+
+ return return_data
+
+ ###
+ def pulse_client_list(self):
+ "Fetch all clients"
+
+ self.start_action()
+
+ CLIENT_INFO_CB = PA_CLIENT_INFO_CB_T(self.py_client_cb)
+
+ self.operation = pa_context_get_client_info_list(self.context,
+ CLIENT_INFO_CB,
+ None)
+
+ self.pulse_iterate()
+
+ #print "pulse_client_list:", self.data
+ return_data = self.data
+ self.data = None
+
+ return return_data
+
+ ###
+
+ def pulse_sink_input_mute(self, index, mute):
+ "Mute one stream by index"
+
+ self.start_action()
+
+ CONTEXT_SUCCESS = PA_CONTEXT_SUCCESS_CB_T(self.py_context_success)
+
+ self.operation = pa_context_set_sink_input_mute(self.context,
+ index,
+ mute, # Mute = 1
+ CONTEXT_SUCCESS,
+ None)
+
+ self.pulse_iterate()
+
+ return
+
+ ###
+
+ def pulse_sink_mute(self, index, mute):
+ "Mute sink by index"
+
+ self.start_action()
+
+ CONTEXT_SUCCESS = PA_CONTEXT_SUCCESS_CB_T(self.py_context_success)
+
+ self.operation = pa_context_set_sink_mute_by_index(self.context,
+ index,
+ mute, # Mute = 1
+ CONTEXT_SUCCESS,
+ None)
+
+ self.pulse_iterate()
+
+ return
+
+ ###
+
+ def pulse_mute_stream(self, index):
+ self.pulse_sink_input_mute(index, 1)
+ return
+
+ ###
+
+ def pulse_unmute_stream(self, index):
+ self.pulse_sink_input_mute(index, 0)
+ return
+
+ ###
+
+ def pulse_mute_sink(self, index):
+ self.pulse_sink_mute(index, 1)
+ return
+
+ ###
+
+ def pulse_unmute_sink(self, index):
+ self.pulse_sink_mute(index, 0)
+ return
+
+ ###
+
+ def pulse_set_sink_input_volume(self, index, vol):
+ "Set volume by index"
+ self.start_action()
+
+ #print "pulse_set_sink_input_volume:", index, "Vol:", vol
+
+ #print vol.values
+ #for a in vol.toCtypes().values:
+ # print a
+ #return
+
+ PA_CONTEXT_SUCCESS_CB = PA_CONTEXT_SUCCESS_CB_T(self.py_context_success)
+
+ self.opertarion = pa_context_set_sink_input_volume(self.context,
+ index,
+ vol.toCtypes(),
+ PA_CONTEXT_SUCCESS_CB,
+ None)
+
+ self.pulse_iterate()
+
+ return
+
+ ###
+
+ def pulse_set_sink_volume(self, index, vol):
+ "Set volume by index"
+ self.start_action()
+
+ #print "pulse_set_sink_volume:", index, "Vol:", vol
+
+ PA_CONTEXT_SUCCESS_CB = PA_CONTEXT_SUCCESS_CB_T(self.py_context_success)
+
+ self.opertarion = pa_context_set_sink_volume_by_index(self.context,
+ index,
+ vol.toCtypes(),
+ PA_CONTEXT_SUCCESS_CB,
+ None)
+
+ self.pulse_iterate()
+
+ return
+
+ ###
+
+ def reconnect(self):
+ self.context = pa_context_new(self.mainloop_api, "PulseApplet")
+
+ pa_context_set_state_callback(self.context, self.PA_STATE_CB, None)
+
+ self.start_action()
+
+
+ if 0 > pa_context_connect(self.context,
+ self.server,
+ 0,
+ None):
+ if self.retry:
+ pa_context_disconnect(self.context)
+ #print "bar"
+ return
+ self.pulse_context_error()
+ #print "foo"
+
+ self.pulse_iterate()
+
+ return
+
+ ###
+
+ def pulse_iterate(self, times = 1):
+ "Runs queries"
+ #print "pulse_iterate: Called"
+ self.ret = pointer(c_int())
+
+ pa_mainloop_iterate(self.mainloop, times, self.ret)
+
+ while not self.action_done:
+ pa_mainloop_iterate(self.mainloop, times, self.ret)
+
+ return
+
+ ###
+
+ def pulse_run(self):
+ self.ret = pointer(c_int(0))
+
+ #pa_mainloop_iterate(self.mainloop, 11, self.ret)
+ pa_mainloop_run(self.mainloop, self.ret)
+ return
diff --git a/pulseaudio/PulseObj.pyc b/pulseaudio/PulseObj.pyc
new file mode 100644
index 0000000..22d7342
--- /dev/null
+++ b/pulseaudio/PulseObj.pyc
Binary files differ
diff --git a/pulseaudio/PulseSink.py b/pulseaudio/PulseSink.py
new file mode 100644
index 0000000..e76c386
--- /dev/null
+++ b/pulseaudio/PulseSink.py
@@ -0,0 +1,213 @@
+#!/usr/bin/python
+# vi: et sw=2
+#
+# PulseSink.py
+# Copyright (C) 2009 Harry Karvonen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Author: Harry Karvonen <harry.karvonen@gmail.com>
+#
+
+from lib_pulseaudio import *
+
+from PulseClient import PulseClient
+from PulseVolume import PulseVolumeCtypes
+
+# This class contains all commons features from PulseSinkInputInfo and
+# PulseSinkInfo
+class PulseSink:
+ def __init__(self, index, name, mute, volume, client):
+ self.index = index
+ self.name = name
+ self.mute = mute
+ self.volume = volume
+ self.client = client
+ return
+
+ # PROTOTYPE
+ def unmuteStream(self):
+ raise Exception("ABSTRACT METHOD CALLED")
+ return
+
+ # PROTOTYPE
+ def muteStream(self):
+ raise Exception("ABSTRACT METHOD CALLED")
+ return
+
+ # PROTOTYPE
+ def setVolume(self):
+ raise Exception("ABSTRACT METHOD CALLED")
+ return
+
+ def printDebug(self):
+ print "self.index:", self.index
+ print "self.name:", self.name
+ print "self.mute:", self.mute
+ print "self.volume:", self.volume
+ print "self.client:", self.client
+ return
+
+################################################################################
+
+class PulseSinkInfo(PulseSink):
+ def __init__(self, pa_sink_info):
+ PulseSink.__init__(self, pa_sink_info.index,
+ pa_sink_info.name,
+ pa_sink_info.mute,
+ PulseVolumeCtypes(pa_sink_info.volume),
+ PulseClient("Selected Sink"))
+
+ self.desctiption = pa_sink_info.description
+ self.sample_spec = pa_sink_info.sample_spec
+ self.channel_map = pa_sink_info.channel_map
+ self.owner_module = pa_sink_info.owner_module
+ self.monitor_source = pa_sink_info.monitor_source
+ self.monitor_source_name = pa_sink_info.monitor_source_name
+ self.latency = pa_sink_info.latency
+ self.driver = pa_sink_info.driver
+ self.flags = pa_sink_info.flags
+ self.proplist = pa_sink_info.proplist
+ self.configured_latency = pa_sink_info.configured_latency
+
+ return
+
+ ###
+ #
+ # Define PROTOTYPE functions
+
+ def unmuteStream(self, pulseInterface):
+ pulseInterface.pulse_unmute_sink(self.index)
+
+ self.mute = 0
+ return
+
+ ###
+
+ def muteStream(self, pulseInterface):
+ pulseInterface.pulse_mute_sink(self.index)
+
+ self.mute = 1
+ return
+
+ ###
+
+ def setVolume(self, pulseInterface, volume):
+ pulseInterface.pulse_set_sink_volume(self.index, volume)
+
+ self.volume = volume
+ return
+
+ ###
+
+ def printDebug(self):
+ print "PulseSinkInfo"
+ PulseSink.printDebug(self)
+ print "self.desctiption", self.desctiption
+ print "self.sample_spec", self.sample_spec
+ print "self.channel_map", self.channel_map
+ print "self.owner_module", self.owner_module
+ print "self.monitor_source", self.monitor_source
+ print "self.monitor_source_name", self.monitor_source_name
+ print "self.latency", self.latency
+ print "self.driver", self.driver
+ print "self.flags", self.flags
+ print "self.proplist", self.proplist
+ print "self.configured_latency", self.configured_latency
+ return
+
+ ###
+
+ def __str__(self):
+ return "ID: " + str(self.index) + ", Name: \"" + \
+ self.name + "\""
+
+################################################################################
+
+class PulseSinkInputInfo(PulseSink):
+ def __init__(self, pa_sink_input_info):
+ PulseSink.__init__(self, pa_sink_input_info.index,
+ pa_sink_input_info.name,
+ pa_sink_input_info.mute,
+ PulseVolumeCtypes(pa_sink_input_info.volume),
+ PulseClient("Unknown client"))
+ self.owner_module = pa_sink_input_info.owner_module
+ self.client_id = pa_sink_input_info.client
+ self.sink = pa_sink_input_info.sink
+ self.sample_spec = pa_sink_input_info.sample_spec
+ self.channel_map = pa_sink_input_info.channel_map
+ self.buffer_usec = pa_sink_input_info.buffer_usec
+ self.sink_usec = pa_sink_input_info.sink_usec
+ self.resample_method = pa_sink_input_info.resample_method
+ self.driver = pa_sink_input_info.driver
+ #self.proplist = pa_sink_input_info.proplist
+
+ return
+
+ ###
+
+ def setClient(self, c):
+ self.client = c
+
+ ###
+ #
+ # Define PROTOTYPE functions
+
+ def unmuteStream(self, pulseInterface):
+ pulseInterface.pulse_unmute_stream(self.index)
+
+ self.mute = 0
+ return
+
+ ###
+
+ def muteStream(self, pulseInterface):
+ pulseInterface.pulse_mute_stream(self.index)
+
+ self.mute = 1
+ return
+
+ ###
+
+ def setVolume(self, pulseInterface, volume):
+ pulseInterface.pulse_set_sink_input_volume(self.index, volume)
+
+ self.volume = volume
+ return
+
+ ###
+
+ def printDebug(self):
+ print "PulseSinkInputInfo"
+ PulseSink.printDebug(self)
+
+ print "self.owner_module:", self.owner_module
+ print "self.client_id:", self.client_id
+ print "self.sink:", self.sink
+ print "self.sample_spec:", self.sample_spec
+ print "self.channel_map:", self.channel_map
+ print "self.buffer_usec:", self.buffer_usec
+ print "self.sink_usec:", self.sink_usec
+ print "self.resample_method:", self.resample_method
+ print "self.driver:", self.driver
+
+ ###
+
+ def __str__(self):
+ if self.client:
+ return "ID: " + str(self.index) + ", Name: \"" + \
+ self.name + "\", mute: " + str(self.mute) + ", " + str(self.client)
+ return "ID: " + str(self.index) + ", Name: \"" + \
+ self.name + "\", mute: " + str(self.mute)
diff --git a/pulseaudio/PulseSink.pyc b/pulseaudio/PulseSink.pyc
new file mode 100644
index 0000000..6b63538
--- /dev/null
+++ b/pulseaudio/PulseSink.pyc
Binary files differ
diff --git a/pulseaudio/PulseSource.py b/pulseaudio/PulseSource.py
new file mode 100644
index 0000000..4856477
--- /dev/null
+++ b/pulseaudio/PulseSource.py
@@ -0,0 +1,187 @@
+#!/usr/bin/python
+# vi: et sw=2
+#
+# PulseSource.py
+# Copyright (C) 2009 Harry Karvonen, Paul W. Frields
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Author: Harry Karvonen <harry.karvonen@gmail.com>
+# Paul W. Frields <stickster@gmail.com>
+#
+
+from lib_pulseaudio import *
+
+from PulseClient import PulseClient
+from PulseVolume import PulseVolumeCtypes
+
+# This class contains all commons features from PulseSourceInputInfo and
+# PulseSourceInfo
+class PulseSource:
+ def __init__(self, index, name, mute, volume, client):
+ self.index = index
+ self.name = name
+ self.mute = mute
+ self.volume = volume
+ self.client = client
+ return
+
+ # PROTOTYPE
+ def unmuteStream(self):
+ raise Exception("ABSTRACT METHOD CALLED")
+ return
+
+ # PROTOTYPE
+ def muteStream(self):
+ raise Exception("ABSTRACT METHOD CALLED")
+ return
+
+ # PROTOTYPE
+ def setVolume(self):
+ raise Exception("ABSTRACT METHOD CALLED")
+ return
+
+ def printDebug(self):
+ print "self.index:", self.index
+ print "self.name:", self.name
+ print "self.mute:", self.mute
+ print "self.volume:", self.volume
+ print "self.client:", self.client
+ return
+
+################################################################################
+
+class PulseSourceInfo(PulseSource):
+ def __init__(self, pa_source_info):
+ PulseSource.__init__(self, pa_source_info.index,
+ pa_source_info.name,
+ pa_source_info.mute,
+ PulseVolumeCtypes(pa_source_info.volume),
+ PulseClient("Selected Source"))
+
+ self.description = pa_source_info.description
+ self.sample_spec = pa_source_info.sample_spec
+ self.channel_map = pa_source_info.channel_map
+ self.owner_module = pa_source_info.owner_module
+ self.latency = pa_source_info.latency
+ self.driver = pa_source_info.driver
+ self.flags = pa_source_info.flags
+ self.proplist = pa_source_info.proplist
+ self.configured_latency = pa_source_info.configured_latency
+
+ return
+
+ ###
+ #
+ # Define PROTOTYPE functions
+
+ def unmuteStream(self, pulseInterface):
+ pulseInterface.pulse_unmute_source(self.index)
+
+ self.mute = 0
+ return
+
+ ###
+
+ def muteStream(self, pulseInterface):
+ pulseInterface.pulse_mute_source(self.index)
+
+ self.mute = 1
+ return
+
+ ###
+
+ def setVolume(self, pulseInterface, volume):
+ pulseInterface.pulse_set_source_volume(self.index, volume)
+
+ self.volume = volume
+ return
+
+ ###
+
+ def printDebug(self):
+ print "PulseSourceInfo"
+ PulseSource.printDebug(self)
+ print "self.description", self.description
+ print "self.sample_spec", self.sample_spec
+ print "self.channel_map", self.channel_map
+ print "self.owner_module", self.owner_module
+ print "self.monitor_of_sink", self.monitor_of_sink
+ print "self.monitor_of_sink_name", self.monitor_of_sink_name
+ print "self.latency", self.latency
+ print "self.driver", self.driver
+ print "self.flags", self.flags
+ print "self.proplist", self.proplist
+ print "self.configured_latency", self.configured_latency
+ return
+
+ ###
+
+ def __str__(self):
+ return "ID: " + str(self.index) + ", Name: \"" + \
+ self.name + "\""
+
+################################################################################
+
+class PulseSourceOutputInfo(PulseSource):
+ def __init__(self, pa_source_output_info):
+ PulseSource.__init__(self, pa_source_output_info.index,
+ pa_source_output_info.name,
+ pa_source_output_info.mute,
+ PulseVolumeCtypes(pa_source_output_info.volume),
+ PulseClient("Unknown client"))
+ self.owner_module = pa_source_output_info.owner_module
+ self.client_id = pa_source_output_info.client
+ self.source = pa_source_output_info.source
+ self.sample_spec = pa_source_output_info.sample_spec
+ self.channel_map = pa_source_output_info.channel_map
+ self.buffer_usec = pa_source_output_info.buffer_usec
+ self.source_usec = pa_source_output_info.source_usec
+ self.resample_method = pa_source_output_info.resample_method
+ self.driver = pa_source_output_info.driver
+ #self.proplist = pa_source_output_info.proplist
+
+ return
+
+ ###
+
+ def setClient(self, c):
+ self.client = c
+
+ ###
+
+ def printDebug(self):
+ print "PulseSourceInputInfo"
+ PulseSource.printDebug(self)
+
+ print "self.owner_module:", self.owner_module
+ print "self.client_id:", self.client_id
+ print "self.source:", self.source
+ print "self.sample_spec:", self.sample_spec
+ print "self.channel_map:", self.channel_map
+ print "self.buffer_usec:", self.buffer_usec
+ print "self.source_usec:", self.source_usec
+ print "self.resample_method:", self.resample_method
+ print "self.driver:", self.driver
+
+ ###
+
+ def __str__(self):
+ if self.client:
+ return "ID: " + str(self.index) + ", Name: \"" + \
+ self.name + "\", mute: " + str(self.mute) + ", " + str(self.client)
+ return "ID: " + str(self.index) + ", Name: \"" + \
+ self.name + "\", mute: " + str(self.mute)
+
diff --git a/pulseaudio/PulseSource.pyc b/pulseaudio/PulseSource.pyc
new file mode 100644
index 0000000..98fb391
--- /dev/null
+++ b/pulseaudio/PulseSource.pyc
Binary files differ
diff --git a/pulseaudio/PulseVolume.py b/pulseaudio/PulseVolume.py
new file mode 100644
index 0000000..1ff6b7a
--- /dev/null
+++ b/pulseaudio/PulseVolume.py
@@ -0,0 +1,114 @@
+#!/usr/bin/python
+# vi: et sw=2
+#
+# PulseVolume.py
+# Copyright (C) 2009 Harry Karvonen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Author: Harry Karvonen <harry.karvonen@gmail.com>
+#
+
+from lib_pulseaudio import *
+import math
+
+# This contains all basic volume features
+class PulseVolume:
+ def __init__(self, vol = 0, channels = 2):
+ self.channels = channels
+
+ if vol > 100 or vol < 0:
+ print "WARNING: Volume is invalid!"
+ vol = 0
+
+ self.values = [vol] * self.channels
+
+ return
+
+ ##############################
+ #
+ # Type conversions
+ #
+ #def fromCtypes(self, pa_cvolume):
+ # self.channels = pa_cvolume.channels
+ # self.values = map(lambda x: (math.ceil(float(x) * 100 / PA_VOLUME_NORM)),
+ # pa_cvolume.values[0:self.channels])
+ # return self
+
+ def toCtypes(self):
+ ct = PA_CVOLUME()
+ ct.channels = self.channels
+
+ for x in range(0, self.channels):
+ ct.values[x] = (self.values[x] * PA_VOLUME_NORM) / 100
+
+ return ct
+
+ ###
+
+ def printDebug(self):
+ print "PulseVolume"
+ print "self.channels:", self.channels
+ print "self.values:", self.values
+ #print "self.proplist:", self.proplist
+
+ ###
+
+ def incVolume(self, vol):
+ "Increment volume level (mono only)"
+ vol += sum(self.values) / len(self.values)
+
+ vol = int(vol)
+
+ if vol > 100:
+ vol = 100
+ elif vol < 0:
+ vol = 0
+
+ self.setVolume(vol)
+
+ return
+
+ ###
+
+ def setVolume(self, vol, balance = None):
+ if not balance:
+ self.values = [vol] * self.channels
+ else:
+ self.values[balance] = vol
+
+ return
+
+ ###
+
+ def getVolume(self):
+ "Return mono volume"
+ return int(sum(self.values) / len(self.values))
+
+ ###
+
+ def __str__(self):
+ return "Channels: " + str(self.channels) + \
+ ", values: \"" + str(map(lambda x: str(x) + "%", self.values)) + "\""
+
+################################################################################
+
+class PulseVolumeCtypes(PulseVolume):
+ def __init__(self, pa_cvolume):
+ self.channels = pa_cvolume.channels
+ self.values = map(lambda x: (math.ceil(float(x) * 100 / PA_VOLUME_NORM)),
+ pa_cvolume.values[0:self.channels])
+ return
+
diff --git a/pulseaudio/PulseVolume.pyc b/pulseaudio/PulseVolume.pyc
new file mode 100644
index 0000000..f900dc7
--- /dev/null
+++ b/pulseaudio/PulseVolume.pyc
Binary files differ
diff --git a/pulseaudio/__init__.py b/pulseaudio/__init__.py
new file mode 100644
index 0000000..8fa7217
--- /dev/null
+++ b/pulseaudio/__init__.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# vi: et sw=2
+#
+# __init__.py
+# Copyright (C) 2009 Harry Karvonen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Author: Harry Karvonen <harry.karvonen@gmail.com>
+#
+
+
+
+from PulseObj import *
+from PulseVolume import *
+from PulseClient import *
+from PulseSink import *
diff --git a/pulseaudio/lib_pulseaudio.py b/pulseaudio/lib_pulseaudio.py
new file mode 100644
index 0000000..9892374
--- /dev/null
+++ b/pulseaudio/lib_pulseaudio.py
@@ -0,0 +1,513 @@
+#!/usr/bin/python
+# vi: et sw=2
+#
+# lib_pulseaudio.py
+# Copyright (C) 2009 Harry Karvonen
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Provides pulseaudio interface for python
+#
+# Author: Harry Karvonen <harry.karvonen@gmail.com>
+#
+
+from ctypes import *
+
+pulse = CDLL("libpulse.so.0");
+
+################################################################################
+#
+# Constrants
+#
+################################################################################
+
+PA_CHANNELS_MAX = 32
+PA_VOLUME_NORM = 0x10000
+
+################################################################################
+#
+# Structs
+#
+################################################################################
+
+class PA_IO_EVENT(Structure):
+ _fields_ = [("_opaque_struct", c_int)]
+
+class PA_MAINLOOP(Structure):
+ _fields_ = [("_opaque_struct", c_int)]
+
+class PA_MAINLOOP_API(Structure):
+ _fields_ = [("_opaque_struct", c_int)]
+
+class PA_CONTEXT(Structure):
+ _fields_ = [("_opaque_struct", c_int)]
+
+class PA_OPERATION(Structure):
+ _fields_ = [("_opaque_struct", c_int)]
+
+class PA_SAMPLE_SPEC(Structure):
+ _fields_ = [
+ ("format", c_int), # FIXME check this
+ ("rate", c_uint32),
+ ("channels", c_uint32)
+ ]
+
+class PA_CHANNEL_MAP(Structure):
+ _fields_ = [
+ ("channels", c_uint8),
+ ("map", c_int * PA_CHANNELS_MAX)
+ ]
+
+class PA_CVOLUME(Structure):
+ _fields_ = [
+ ("channels", c_uint8),
+ ("values", c_uint32 * PA_CHANNELS_MAX)
+ ]
+
+PA_USEC_T = c_uint64
+
+class PA_SINK_INPUT_INFO(Structure):
+ __slots__ = [
+ 'index',
+ 'name',
+ 'owner_module',
+ 'client',
+ 'sink',
+ 'sample_spec',
+ 'channel_map',
+ 'volume',
+ 'buffer_usec',
+ 'sink_usec',
+ 'resample_method',
+ 'driver',
+ 'mute',
+ ]
+ _fields_ = [
+ ("index", c_uint32),
+ ("name", c_char_p),
+ ("owner_module", c_uint32),
+ ("client", c_uint32),
+ ("sink", c_uint32),
+ ("sample_spec", PA_SAMPLE_SPEC),
+ ("channel_map", PA_CHANNEL_MAP),
+ ("volume", PA_CVOLUME),
+ ("buffer_usec", PA_USEC_T),
+ ("sink_usec", PA_USEC_T),
+ ("resample_method", c_char_p),
+ ("driver", c_char_p),
+ ("mute", c_int)
+ #("proplist", POINTER(c_int))
+ ]
+
+class PA_SINK_INFO(Structure):
+ _fields_ = [
+ ("name", c_char_p),
+ ("index", c_uint32),
+ ("description", c_char_p),
+ ("sample_spec", PA_SAMPLE_SPEC),
+ ("channel_map", PA_CHANNEL_MAP),
+ ("owner_module", c_uint32),
+ ("volume", PA_CVOLUME),
+ ("mute", c_int),
+ ("monitor_source", c_uint32),
+ ("monitor_source_name", c_char_p),
+ ("latency", PA_USEC_T),
+ ("driver", c_char_p),
+ ("flags", c_int),
+ ("proplist", POINTER(c_int)),
+ ("configured_latency", PA_USEC_T)
+ ]
+
+class PA_SOURCE_OUTPUT_INFO(Structure):
+ __slots__ = [
+ 'index',
+ 'name',
+ 'owner_module',
+ 'client',
+ 'source',
+ 'sample_spec',
+ 'channel_map',
+ 'volume',
+ 'buffer_usec',
+ 'sink_usec',
+ 'resample_method',
+ 'driver',
+ 'mute',
+ ]
+ _fields_ = [
+ ("index", c_uint32),
+ ("name", c_char_p),
+ ("owner_module", c_uint32),
+ ("client", c_uint32),
+ ("source", c_uint32),
+ ("sample_spec", PA_SAMPLE_SPEC),
+ ("channel_map", PA_CHANNEL_MAP),
+ ("volume", PA_CVOLUME),
+ ("buffer_usec", PA_USEC_T),
+ ("sink_usec", PA_USEC_T),
+ ("resample_method", c_char_p),
+ ("driver", c_char_p),
+ ("mute", c_int)
+ #("proplist", POINTER(c_int))
+ ]
+
+class PA_SOURCE_INFO(Structure):
+ _fields_ = [
+ ("name", c_char_p),
+ ("index", c_uint32),
+ ("description", c_char_p),
+ ("sample_spec", PA_SAMPLE_SPEC),
+ ("channel_map", PA_CHANNEL_MAP),
+ ("owner_module", c_uint32),
+ ("volume", PA_CVOLUME),
+ ("mute", c_int),
+ ("monitor_of_sink", c_uint32),
+ ("monitor_of_sink_name", c_char_p),
+ ("latency", PA_USEC_T),
+ ("driver", c_char_p),
+ ("flags", c_int),
+ ("proplist", POINTER(c_int)),
+ ("configured_latency", PA_USEC_T)
+ ]
+
+class PA_CLIENT_INFO(Structure):
+ _fields_ = [
+ ("index", c_uint32),
+ ("name", c_char_p),
+ ("owner_module", c_uint32),
+ ("driver", c_char_p)
+ #("proplist", POINTER(c_int))
+ ]
+
+################################################################################
+#
+# Callback types
+#
+################################################################################
+
+#PA_IO_EVENT_CB_T = CFUNCTYPE(c_void_p,
+# POINTER(PA_MAINLOOP_API),
+# POINTER(PA_IO_EVENT),
+# c_int,
+# c_int,
+# c_void_p)
+
+# SIGNAL
+PA_SIGNAL_CB_T = CFUNCTYPE(c_void_p,
+ POINTER(PA_MAINLOOP_API),
+ POINTER(c_int), # FIXME wrong type
+ c_int,
+ c_void_p)
+
+# STATE
+PA_STATE_CB_T = CFUNCTYPE(c_int,
+ POINTER(PA_CONTEXT),
+ c_void_p)
+
+# CLIENT
+PA_CLIENT_INFO_CB_T = CFUNCTYPE(c_void_p,
+ POINTER(PA_CONTEXT),
+ POINTER(PA_CLIENT_INFO),
+ c_int,
+ c_void_p)
+# SINK INPUT
+PA_SINK_INPUT_INFO_CB_T = CFUNCTYPE(c_int, #FIXME wrong type
+ POINTER(PA_CONTEXT),
+ POINTER(PA_SINK_INPUT_INFO),
+ c_int,
+ c_void_p)
+
+# SINK
+PA_SINK_INFO_CB_T = CFUNCTYPE(c_int, #FIXME wrong type
+ POINTER(PA_CONTEXT),
+ POINTER(PA_SINK_INFO),
+ c_int,
+ c_void_p)
+# SOURCE OUTPUT
+PA_SOURCE_OUTPUT_INFO_CB_T = CFUNCTYPE(c_int, #FIXME wrong type
+ POINTER(PA_CONTEXT),
+ POINTER(PA_SOURCE_OUTPUT_INFO),
+ c_int,
+ c_void_p)
+
+# SOURCE
+PA_SOURCE_INFO_CB_T = CFUNCTYPE(c_int, #FIXME wrong type
+ POINTER(PA_CONTEXT),
+ POINTER(PA_SOURCE_INFO),
+ c_int,
+ c_void_p)
+# CONTEXT
+PA_CONTEXT_DRAIN_CB_T = CFUNCTYPE(c_void_p,
+ POINTER(PA_CONTEXT),
+ c_void_p)
+
+PA_CONTEXT_SUCCESS_CB_T = CFUNCTYPE(c_void_p,
+ POINTER(PA_CONTEXT),
+ c_int,
+ c_void_p)
+
+################################################################################
+#
+# Functions
+#
+################################################################################
+
+#
+# pa_strerror
+pa_strerror = pulse.pa_strerror
+pa_strerror.restype = c_char_p
+pa_strerror.argtypes = [
+ c_int
+]
+
+#
+# pa_mainloop_*
+pa_mainloop_new = pulse.pa_mainloop_new
+pa_mainloop_new.restype = POINTER(PA_MAINLOOP)
+pa_mainloop_new.argtypes = [
+]
+
+pa_mainloop_get_api = pulse.pa_mainloop_get_api
+pa_mainloop_get_api.restype = POINTER(PA_MAINLOOP_API)
+pa_mainloop_get_api.argtypes = [
+ POINTER(PA_MAINLOOP)
+]
+
+pa_mainloop_run = pulse.pa_mainloop_run
+pa_mainloop_run.restype = c_int
+pa_mainloop_run.argtypes = [
+ POINTER(PA_MAINLOOP),
+ POINTER(c_int)
+]
+
+pa_mainloop_iterate = pulse.pa_mainloop_iterate
+pa_mainloop_iterate.restype = c_int
+pa_mainloop_iterate.argtypes = [
+ POINTER(PA_MAINLOOP),
+ c_int,
+ POINTER(c_int)
+]
+
+pa_mainloop_quit = pulse.pa_mainloop_quit
+pa_mainloop_quit.restype = c_int
+pa_mainloop_quit.argtypes = [
+ POINTER(PA_MAINLOOP),
+ c_int
+]
+
+pa_mainloop_dispatch = pulse.pa_mainloop_dispatch
+pa_mainloop_dispatch.restype = c_int
+pa_mainloop_dispatch.argtypes = [
+ POINTER(PA_MAINLOOP)
+]
+
+pa_mainloop_free = pulse.pa_mainloop_run
+pa_mainloop_free.restype = c_int
+pa_mainloop_free.argtypes = [
+ POINTER(PA_MAINLOOP)
+]
+
+#
+# pa_signal_*
+pa_signal_init = pulse.pa_signal_init
+pa_signal_init.restype = c_int
+pa_signal_init.argtypes = [
+ POINTER(PA_MAINLOOP_API)
+]
+
+pa_signal_new = pulse.pa_signal_new
+pa_signal_new.restype = None #POINTER(c_int) #FIXME PA_SIGNAL_EVENT)
+pa_signal_new.argtypes = [
+ c_int,
+ PA_SIGNAL_CB_T,
+ POINTER(c_int)
+]
+
+#
+# pa_context_*
+pa_context_errno = pulse.pa_context_errno
+pa_context_errno.restype = c_int
+pa_context_errno.argtypes = [
+ POINTER(PA_CONTEXT)
+]
+
+pa_context_new = pulse.pa_context_new
+pa_context_new.restype = POINTER(PA_CONTEXT)
+pa_context_new.argtypes = [
+ POINTER(PA_MAINLOOP_API),
+ c_char_p
+]
+
+
+pa_context_set_state_callback = pulse.pa_context_set_state_callback
+pa_context_set_state_callback.restype = None
+pa_context_set_state_callback.argtypes = [
+ POINTER(PA_CONTEXT),
+ PA_STATE_CB_T,
+ c_void_p
+]
+
+pa_context_connect = pulse.pa_context_connect
+pa_context_connect.restype = c_int
+pa_context_connect.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_char_p,
+ c_int, #FIXME | isn't correct
+ POINTER(c_int)
+]
+
+pa_context_get_state = pulse.pa_context_get_state
+pa_context_get_state.restype = c_int;
+pa_context_get_state.argtypes = [
+ POINTER(PA_CONTEXT)
+]
+
+pa_context_drain = pulse.pa_context_drain
+pa_context_drain.restype = POINTER(PA_OPERATION)
+pa_context_drain.argtypes = [
+ POINTER(PA_CONTEXT),
+ PA_CONTEXT_DRAIN_CB_T,
+ c_void_p
+]
+
+pa_context_disconnect = pulse.pa_context_disconnect
+pa_context_disconnect.restype = c_int;
+pa_context_disconnect.argtypes = [
+ POINTER(PA_CONTEXT)
+]
+
+#
+# pa_context_*_sink_*
+pa_context_get_sink_input_info_list = pulse.pa_context_get_sink_input_info_list
+pa_context_get_sink_input_info_list.restype = POINTER(c_int)
+pa_context_get_sink_input_info_list.argtypes = [
+ POINTER(PA_CONTEXT),
+ PA_SINK_INPUT_INFO_CB_T,
+ c_void_p
+]
+
+pa_context_get_sink_info_list = pulse.pa_context_get_sink_info_list
+pa_context_get_sink_info_list.restype = POINTER(c_int)
+pa_context_get_sink_info_list.argtypes = [
+ POINTER(PA_CONTEXT),
+ PA_SINK_INFO_CB_T,
+ c_void_p
+]
+
+pa_context_set_sink_mute_by_index = pulse.pa_context_set_sink_mute_by_index
+pa_context_set_sink_mute_by_index.restype = POINTER(c_int)
+pa_context_set_sink_mute_by_index.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_uint32,
+ c_int,
+ PA_CONTEXT_SUCCESS_CB_T,
+ c_void_p
+]
+
+pa_context_set_sink_input_mute = pulse.pa_context_set_sink_input_mute
+pa_context_set_sink_input_mute.restype = POINTER(c_int)
+pa_context_set_sink_input_mute.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_uint32,
+ c_int,
+ PA_CONTEXT_SUCCESS_CB_T,
+ c_void_p
+]
+
+pa_context_set_sink_volume_by_index = pulse.pa_context_set_sink_volume_by_index
+pa_context_set_sink_volume_by_index.restype = POINTER(c_int)
+pa_context_set_sink_volume_by_index.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_uint32,
+ POINTER(PA_CVOLUME),
+ PA_CONTEXT_SUCCESS_CB_T,
+ c_void_p
+]
+
+pa_context_set_sink_input_volume = pulse.pa_context_set_sink_input_volume
+pa_context_set_sink_input_volume.restype = POINTER(c_int)
+pa_context_set_sink_input_volume.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_uint32,
+ POINTER(PA_CVOLUME),
+ PA_CONTEXT_SUCCESS_CB_T,
+ c_void_p
+]
+
+#
+# pa_context_*_source_*
+pa_context_get_source_output_info_list = pulse.pa_context_get_source_output_info_list
+pa_context_get_source_output_info_list.restype = POINTER(c_int)
+pa_context_get_source_output_info_list.argtypes = [
+ POINTER(PA_CONTEXT),
+ PA_SOURCE_OUTPUT_INFO_CB_T,
+ c_void_p
+]
+
+pa_context_get_source_info_list = pulse.pa_context_get_source_info_list
+pa_context_get_source_info_list.restype = POINTER(c_int)
+pa_context_get_source_info_list.argtypes = [
+ POINTER(PA_CONTEXT),
+ PA_SOURCE_INFO_CB_T,
+ c_void_p
+]
+
+pa_context_set_source_mute_by_index = pulse.pa_context_set_source_mute_by_index
+pa_context_set_source_mute_by_index.restype = POINTER(c_int)
+pa_context_set_source_mute_by_index.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_uint32,
+ c_int,
+ PA_CONTEXT_SUCCESS_CB_T,
+ c_void_p
+]
+
+pa_context_set_source_volume_by_index = pulse.pa_context_set_source_volume_by_index
+pa_context_set_source_volume_by_index.restype = POINTER(c_int)
+pa_context_set_source_volume_by_index.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_uint32,
+ POINTER(PA_CVOLUME),
+ PA_CONTEXT_SUCCESS_CB_T,
+ c_void_p
+]
+
+#
+# pa_context_*_client_*
+
+pa_context_get_client_info_list = pulse.pa_context_get_client_info_list
+pa_context_get_client_info_list.restype = POINTER(c_int)
+pa_context_get_client_info_list.argtypes = [
+ POINTER(PA_CONTEXT),
+ PA_CLIENT_INFO_CB_T,
+ c_void_p
+]
+pa_context_get_client_info = pulse.pa_context_get_client_info
+pa_context_get_client_info.restype = POINTER(c_int)
+pa_context_get_client_info.argtypes = [
+ POINTER(PA_CONTEXT),
+ c_uint32,
+ PA_CLIENT_INFO_CB_T,
+ c_void_p
+]
+
+#
+# pa_operation_*
+pa_operation_unref = pulse.pa_operation_unref
+pa_operation_unref.restype = c_int
+pa_operation_unref.argtypes = [
+ POINTER(PA_OPERATION)
+]
+
diff --git a/pulseaudio/lib_pulseaudio.pyc b/pulseaudio/lib_pulseaudio.pyc
new file mode 100644
index 0000000..88b2c10
--- /dev/null
+++ b/pulseaudio/lib_pulseaudio.pyc
Binary files differ